summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2016-06-23 13:17:25 +0200
committerWerner Koch <wk@gnupg.org>2016-06-23 13:17:25 +0200
commit3ead21da80da4570e77036cc05303914c9b1f364 (patch)
tree097664acffb2bf71683c2c51278527a60c9018f8
parentcommon: Rename external symbols in name-value.c. (diff)
downloadgnupg2-3ead21da80da4570e77036cc05303914c9b1f364.tar.xz
gnupg2-3ead21da80da4570e77036cc05303914c9b1f364.zip
common: Add dedicated private key functions to name-value.c.
* common/name-value.c (struct name_value_container): Add field 'private_key_mode'. (my_error): New. Use instead of gpg_error. (nvc_new_private_key): New. (nve_release): Add arg 'private_key_mode'. (nvc_release): Call nve_release with private_key_mode flag. (nvc_delete): Ditto. (_nvc_add): Do no special case "Key:" in non-private_key_mode. (nvc_get_private_key): Return error in non-private_key_mode. (nvc_set_private_key): Ditto. (nvc_parse): Factor all code out to ... (do_nvc_parse): new. Add arg 'for_private_key'. (nvc_parse_private_key): New. * agent/findkey.c (write_extended_private_key): Replace nvc_parse by nvc_parse_private_key. (read_key_file): Ditto. * common/t-name-value.c (private_key_mode): New variable. (my_nvc_new): New. Replace all callers. (test_key_extraction): Take mode in account. (run_tests): Ditto. (run_modification_tests): Ditto. (parse): Ditto. (main): Add option --parse and rename --parse to --parse-key. -- Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r--agent/findkey.c4
-rw-r--r--common/name-value.c82
-rw-r--r--common/name-value.h15
-rw-r--r--common/t-name-value.c96
4 files changed, 153 insertions, 44 deletions
diff --git a/agent/findkey.c b/agent/findkey.c
index dc7099c76..c5ab0e905 100644
--- a/agent/findkey.c
+++ b/agent/findkey.c
@@ -62,7 +62,7 @@ write_extended_private_key (char *fname, estream_t fp,
int remove = 0;
int line;
- err = nvc_parse (&pk, &line, fp);
+ err = nvc_parse_private_key (&pk, &line, fp);
if (err)
{
log_error ("error parsing '%s' line %d: %s\n",
@@ -690,7 +690,7 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
nvc_t pk;
int line;
- rc = nvc_parse (&pk, &line, fp);
+ rc = nvc_parse_private_key (&pk, &line, fp);
es_fclose (fp);
if (rc)
diff --git a/common/name-value.c b/common/name-value.c
index e297f1a54..0b32a4442 100644
--- a/common/name-value.c
+++ b/common/name-value.c
@@ -47,6 +47,7 @@ struct name_value_container
{
struct name_value_entry *first;
struct name_value_entry *last;
+ unsigned int private_key_mode:1;
};
@@ -75,6 +76,13 @@ my_error_from_syserror (void)
}
+static inline gpg_error_t
+my_error (gpg_err_code_t ec)
+{
+ return gpg_err_make (default_errsource, ec);
+}
+
+
/* Allocation and deallocation. */
@@ -87,17 +95,31 @@ nvc_new (void)
}
+/* Allocate a private key container structure for use with private keys. */
+nvc_t
+nvc_new_private_key (void)
+{
+ nvc_t nvc = nvc_new ();
+ if (nvc)
+ nvc->private_key_mode = 1;
+ return nvc;
+}
+
+
static void
-nve_release (nve_t entry)
+nve_release (nve_t entry, int private_key_mode)
{
if (entry == NULL)
return;
xfree (entry->name);
- if (entry->value)
+ if (entry->value && private_key_mode)
wipememory (entry->value, strlen (entry->value));
xfree (entry->value);
- free_strlist_wipe (entry->raw_value);
+ if (private_key_mode)
+ free_strlist_wipe (entry->raw_value);
+ else
+ free_strlist (entry->raw_value);
xfree (entry);
}
@@ -114,7 +136,7 @@ nvc_release (nvc_t pk)
for (e = pk->first; e; e = next)
{
next = e->next;
- nve_release (e);
+ nve_release (e, pk->private_key_mode);
}
xfree (pk);
@@ -336,13 +358,16 @@ _nvc_add (nvc_t pk, char *name, char *value, strlist_t raw_value,
if (name && ! valid_name (name))
{
- err = gpg_error (GPG_ERR_INV_NAME);
+ err = my_error (GPG_ERR_INV_NAME);
goto leave;
}
- if (name && ascii_strcasecmp (name, "Key:") == 0 && nvc_lookup (pk, "Key:"))
+ if (name
+ && pk->private_key_mode
+ && !ascii_strcasecmp (name, "Key:")
+ && nvc_lookup (pk, "Key:"))
{
- err = gpg_error (GPG_ERR_INV_NAME);
+ err = my_error (GPG_ERR_INV_NAME);
goto leave;
}
@@ -486,7 +511,7 @@ nvc_delete (nvc_t pk, nve_t entry)
else
pk->last = entry->prev;
- nve_release (entry);
+ nve_release (entry, pk->private_key_mode);
}
@@ -549,9 +574,9 @@ nvc_get_private_key (nvc_t pk, gcry_sexp_t *retsexp)
gpg_error_t err;
nve_t e;
- e = nvc_lookup (pk, "Key:");
+ e = pk->private_key_mode? nvc_lookup (pk, "Key:") : NULL;
if (e == NULL)
- return gpg_error (GPG_ERR_MISSING_KEY);
+ return my_error (GPG_ERR_MISSING_KEY);
err = assert_value (e);
if (err)
@@ -569,6 +594,9 @@ nvc_set_private_key (nvc_t pk, gcry_sexp_t sexp)
char *raw, *clean, *p;
size_t len, i;
+ if (!pk->private_key_mode)
+ return my_error (GPG_ERR_MISSING_KEY);
+
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
raw = xtrymalloc (len);
@@ -620,11 +648,9 @@ nvc_set_private_key (nvc_t pk, gcry_sexp_t sexp)
/* Parsing and serialization. */
-/* Parse STREAM and return a newly allocated private key container
- structure in RESULT. If ERRLINEP is given, the line number the
- parser was last considering is stored there. */
-gpg_error_t
-nvc_parse (nvc_t *result, int *errlinep, estream_t stream)
+static gpg_error_t
+do_nvc_parse (nvc_t *result, int *errlinep, estream_t stream,
+ int for_private_key)
{
gpg_error_t err = 0;
gpgrt_ssize_t len;
@@ -633,8 +659,7 @@ nvc_parse (nvc_t *result, int *errlinep, estream_t stream)
char *name = NULL;
strlist_t raw_value = NULL;
-
- *result = nvc_new ();
+ *result = for_private_key? nvc_new_private_key () : nvc_new ();
if (*result == NULL)
return my_error_from_syserror ();
@@ -680,7 +705,7 @@ nvc_parse (nvc_t *result, int *errlinep, estream_t stream)
colon = strchr (buf, ':');
if (colon == NULL)
{
- err = gpg_error (GPG_ERR_INV_VALUE);
+ err = my_error (GPG_ERR_INV_VALUE);
goto leave;
}
@@ -727,6 +752,27 @@ nvc_parse (nvc_t *result, int *errlinep, estream_t stream)
}
+/* Parse STREAM and return a newly allocated name value container
+ structure in RESULT. If ERRLINEP is given, the line number the
+ parser was last considering is stored there. */
+gpg_error_t
+nvc_parse (nvc_t *result, int *errlinep, estream_t stream)
+{
+ return do_nvc_parse (result, errlinep, stream, 0);
+}
+
+
+/* Parse STREAM and return a newly allocated name value container
+ structure in RESULT - assuming the extended private key format. If
+ ERRLINEP is given, the line number the parser was last considering
+ is stored there. */
+gpg_error_t
+nvc_parse_private_key (nvc_t *result, int *errlinep, estream_t stream)
+{
+ return do_nvc_parse (result, errlinep, stream, 1);
+}
+
+
/* Write a representation of PK to STREAM. */
gpg_error_t
nvc_write (nvc_t pk, estream_t stream)
diff --git a/common/name-value.h b/common/name-value.h
index 21a5293e0..f5f17e6de 100644
--- a/common/name-value.h
+++ b/common/name-value.h
@@ -40,10 +40,14 @@ typedef struct name_value_entry *nve_t;
/* Memory management, and dealing with entries. */
-/* Allocate a private key container structure. */
+/* Allocate a name value container structure. */
nvc_t nvc_new (void);
-/* Release a private key container structure. */
+/* Allocate a name value container structure for use with the extended
+ * private key format. */
+nvc_t nvc_new_private_key (void);
+
+/* Release a name value container structure. */
void nvc_release (nvc_t pk);
/* Get the name. */
@@ -103,6 +107,13 @@ gpg_error_t nvc_set_private_key (nvc_t pk, gcry_sexp_t sexp);
parser was last considering is stored there. */
gpg_error_t nvc_parse (nvc_t *result, int *errlinep, estream_t stream);
+/* Parse STREAM and return a newly allocated name value container
+ structure in RESULT - assuming the extended private key format. If
+ ERRLINEP is given, the line number the parser was last considering
+ is stored there. */
+gpg_error_t nvc_parse_private_key (nvc_t *result, int *errlinep,
+ estream_t stream);
+
/* Write a representation of PK to STREAM. */
gpg_error_t nvc_write (nvc_t pk, estream_t stream);
diff --git a/common/t-name-value.c b/common/t-name-value.c
index 810c85c38..fc9303bb8 100644
--- a/common/t-name-value.c
+++ b/common/t-name-value.c
@@ -29,6 +29,18 @@
#include "name-value.h"
static int verbose;
+static int private_key_mode;
+
+
+static nvc_t
+my_nvc_new (void)
+{
+ if (private_key_mode)
+ return nvc_new_private_key ();
+ else
+ return nvc_new ();
+}
+
void
test_getting_values (nvc_t pk)
@@ -55,14 +67,22 @@ test_key_extraction (nvc_t pk)
gpg_error_t err;
gcry_sexp_t key;
- err = nvc_get_private_key (pk, &key);
- assert (err == 0);
- assert (key);
+ if (private_key_mode)
+ {
+ err = nvc_get_private_key (pk, &key);
+ assert (err == 0);
+ assert (key);
- if (verbose)
- gcry_sexp_dump (key);
+ if (verbose)
+ gcry_sexp_dump (key);
- gcry_sexp_release (key);
+ gcry_sexp_release (key);
+ }
+ else
+ {
+ err = nvc_get_private_key (pk, &key);
+ assert (gpg_err_code (err) == GPG_ERR_MISSING_KEY);
+ }
}
@@ -240,7 +260,10 @@ run_tests (void)
0, dummy_realloc, dummy_free, "r");
assert (source);
- err = nvc_parse (&pk, NULL, source);
+ if (private_key_mode)
+ err = nvc_parse_private_key (&pk, NULL, source);
+ else
+ err = nvc_parse (&pk, NULL, source);
assert (err == 0);
assert (pk);
@@ -272,7 +295,7 @@ run_modification_tests (void)
gcry_sexp_t key;
char *buf;
- pk = nvc_new ();
+ pk = my_nvc_new ();
assert (pk);
nvc_set (pk, "Foo:", "Bar");
@@ -354,20 +377,29 @@ run_modification_tests (void)
xfree (buf);
nvc_release (pk);
- pk = nvc_new ();
+ pk = my_nvc_new ();
assert (pk);
err = gcry_sexp_build (&key, NULL, "(hello world)");
assert (err == 0);
assert (key);
- err = nvc_set_private_key (pk, key);
- gcry_sexp_release (key);
- assert (err == 0);
- buf = nvc_to_string (pk);
- assert (strcmp (buf, "Key: (hello world)\n") == 0);
- xfree (buf);
- nvc_release (pk);
+ if (private_key_mode)
+ {
+ err = nvc_set_private_key (pk, key);
+ gcry_sexp_release (key);
+ assert (err == 0);
+
+ buf = nvc_to_string (pk);
+ assert (strcmp (buf, "Key: (hello world)\n") == 0);
+ xfree (buf);
+ nvc_release (pk);
+ }
+ else
+ {
+ err = nvc_set_private_key (pk, key);
+ assert (gpg_err_code (err) == GPG_ERR_MISSING_KEY);
+ }
}
@@ -403,7 +435,7 @@ convert (const char *fname)
exit (1);
}
- pk = nvc_new ();
+ pk = my_nvc_new ();
assert (pk);
err = nvc_set_private_key (pk, key);
@@ -437,7 +469,10 @@ parse (const char *fname)
exit (1);
}
- err = nvc_parse (&pk_a, &line, source);
+ if (private_key_mode)
+ err = nvc_parse_private_key (&pk_a, &line, source);
+ else
+ err = nvc_parse (&pk_a, &line, source);
if (err)
{
fprintf (stderr, "failed to parse %s line %d: %s\n",
@@ -448,14 +483,14 @@ parse (const char *fname)
buf = nvc_to_string (pk_a);
xfree (buf);
- pk_b = nvc_new ();
+ pk_b = my_nvc_new ();
assert (pk_b);
for (e = nvc_first (pk_a); e; e = nve_next (e))
{
gcry_sexp_t key = NULL;
- if (strcasecmp (nve_name (e), "Key:") == 0)
+ if (private_key_mode && !strcasecmp (nve_name (e), "Key:"))
{
err = nvc_get_private_key (pk_a, &key);
if (err)
@@ -487,7 +522,8 @@ print_usage (void)
fprintf (stderr,
"usage: t-private-keys [--verbose]"
" [--convert <private-key-file>"
- " || --parse <extended-private-key-file>]\n");
+ " || --parse-key <extended-private-key-file>"
+ " || --parse <file> ]\n");
exit (2);
}
@@ -495,7 +531,7 @@ print_usage (void)
int
main (int argc, char **argv)
{
- enum { TEST, CONVERT, PARSE } command = TEST;
+ enum { TEST, CONVERT, PARSE, PARSEKEY } command = TEST;
if (argc)
{ argc--; argv++; }
@@ -513,6 +549,14 @@ main (int argc, char **argv)
print_usage ();
}
+ if (argc && !strcmp (argv[0], "--parse-key"))
+ {
+ command = PARSEKEY;
+ argc--; argv++;
+ if (argc != 1)
+ print_usage ();
+ }
+
if (argc && !strcmp (argv[0], "--parse"))
{
command = PARSE;
@@ -526,12 +570,20 @@ main (int argc, char **argv)
case TEST:
run_tests ();
run_modification_tests ();
+ private_key_mode = 1;
+ run_tests ();
+ run_modification_tests ();
break;
case CONVERT:
convert (*argv);
break;
+ case PARSEKEY:
+ private_key_mode = 1;
+ parse (*argv);
+ break;
+
case PARSE:
parse (*argv);
break;