diff options
author | Werner Koch <[email protected]> | 2016-07-13 13:11:46 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2016-07-13 13:11:46 +0000 |
commit | 4ef62278e3c9406360dc50288f422291497e218f (patch) | |
tree | fff3a49be5c2659ab87195e5b0a4f88e51a49205 /common/name-value.c | |
parent | Merge branch 'master' into STABLE-BRANCH-2-2 (diff) | |
parent | gpg: New option --mimemode. (diff) | |
download | gnupg-4ef62278e3c9406360dc50288f422291497e218f.tar.gz gnupg-4ef62278e3c9406360dc50288f422291497e218f.zip |
Merge branch 'master' into STABLE-BRANCH-2-2
--
Diffstat (limited to '')
-rw-r--r-- | common/name-value.c (renamed from common/private-keys.c) | 183 |
1 files changed, 117 insertions, 66 deletions
diff --git a/common/private-keys.c b/common/name-value.c index 4cf7d227c..0b32a4442 100644 --- a/common/private-keys.c +++ b/common/name-value.c @@ -1,4 +1,4 @@ -/* private-keys.c - Parser and writer for the extended private key format. +/* name-value.c - Parser and writer for a name-value format. * Copyright (C) 2016 g10 Code GmbH * * This file is part of GnuPG. @@ -27,28 +27,34 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +/* + * This module aso provides features for the extended private key + * format of gpg-agent. + */ + #include <config.h> #include <assert.h> #include <gcrypt.h> #include <gpg-error.h> #include <string.h> -#include "private-keys.h" #include "mischelp.h" #include "strlist.h" #include "util.h" +#include "name-value.h" -struct private_key_container +struct name_value_container { - struct private_key_entry *first; - struct private_key_entry *last; + struct name_value_entry *first; + struct name_value_entry *last; + unsigned int private_key_mode:1; }; -struct private_key_entry +struct name_value_entry { - struct private_key_entry *prev; - struct private_key_entry *next; + struct name_value_entry *prev; + struct name_value_entry *next; /* The name. Comments and blank lines have NAME set to NULL. */ char *name; @@ -70,38 +76,59 @@ 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. */ /* Allocate a private key container structure. */ -pkc_t -pkc_new (void) +nvc_t +nvc_new (void) +{ + return xtrycalloc (1, sizeof (struct name_value_container)); +} + + +/* Allocate a private key container structure for use with private keys. */ +nvc_t +nvc_new_private_key (void) { - return xtrycalloc (1, sizeof (struct private_key_container)); + nvc_t nvc = nvc_new (); + if (nvc) + nvc->private_key_mode = 1; + return nvc; } static void -pke_release (pke_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); } /* Release a private key container structure. */ void -pkc_release (pkc_t pk) +nvc_release (nvc_t pk) { - pke_t e, next; + nve_t e, next; if (pk == NULL) return; @@ -109,7 +136,7 @@ pkc_release (pkc_t pk) for (e = pk->first; e; e = next) { next = e->next; - pke_release (e); + nve_release (e, pk->private_key_mode); } xfree (pk); @@ -140,7 +167,7 @@ valid_name (const char *name) /* Makes sure that ENTRY has a RAW_VALUE. */ static gpg_error_t -assert_raw_value (pke_t entry) +assert_raw_value (nve_t entry) { gpg_error_t err = 0; size_t len, offset; @@ -256,7 +283,7 @@ continuation_length (const char *s, int *swallow_ws, const char **start) /* Makes sure that ENTRY has a VALUE. */ static gpg_error_t -assert_value (pke_t entry) +assert_value (nve_t entry) { size_t len; int swallow_ws; @@ -297,7 +324,7 @@ assert_value (pke_t entry) /* Get the name. */ char * -pke_name (pke_t pke) +nve_name (nve_t pke) { return pke->name; } @@ -305,7 +332,7 @@ pke_name (pke_t pke) /* Get the value. */ char * -pke_value (pke_t pke) +nve_value (nve_t pke) { if (assert_value (pke)) return NULL; @@ -321,23 +348,26 @@ pke_value (pke_t pke) given. If PRESERVE_ORDER is not given, entries with the same name are grouped. NAME, VALUE and RAW_VALUE is consumed. */ static gpg_error_t -_pkc_add (pkc_t pk, char *name, char *value, strlist_t raw_value, +_nvc_add (nvc_t pk, char *name, char *value, strlist_t raw_value, int preserve_order) { gpg_error_t err = 0; - pke_t e; + nve_t e; assert (value || 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 && pkc_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; } @@ -354,21 +384,21 @@ _pkc_add (pkc_t pk, char *name, char *value, strlist_t raw_value, if (pk->first) { - pke_t last; + nve_t last; if (preserve_order || name == NULL) last = pk->last; else { /* See if there is already an entry with NAME. */ - last = pkc_lookup (pk, name); + last = nvc_lookup (pk, name); /* If so, find the last in that block. */ if (last) { while (last->next) { - pke_t next = last->next; + nve_t next = last->next; if (next->name && ascii_strcasecmp (next->name, name) == 0) last = next; @@ -414,7 +444,7 @@ _pkc_add (pkc_t pk, char *name, char *value, strlist_t raw_value, /* Add (NAME, VALUE) to PK. If an entry with NAME already exists, it is not updated but the new entry is appended. */ gpg_error_t -pkc_add (pkc_t pk, const char *name, const char *value) +nvc_add (nvc_t pk, const char *name, const char *value) { char *k, *v; @@ -429,7 +459,7 @@ pkc_add (pkc_t pk, const char *name, const char *value) return my_error_from_syserror (); } - return _pkc_add (pk, k, v, NULL, 0); + return _nvc_add (pk, k, v, NULL, 0); } @@ -437,14 +467,14 @@ pkc_add (pkc_t pk, const char *name, const char *value) is updated with VALUE. If multiple entries with NAME exist, the first entry is updated. */ gpg_error_t -pkc_set (pkc_t pk, const char *name, const char *value) +nvc_set (nvc_t pk, const char *name, const char *value) { - pke_t e; + nve_t e; if (! valid_name (name)) return GPG_ERR_INV_NAME; - e = pkc_lookup (pk, name); + e = nvc_lookup (pk, name); if (e) { char *v; @@ -463,13 +493,13 @@ pkc_set (pkc_t pk, const char *name, const char *value) return 0; } else - return pkc_add (pk, name, value); + return nvc_add (pk, name, value); } /* Delete the given entry from PK. */ void -pkc_delete (pkc_t pk, pke_t entry) +nvc_delete (nvc_t pk, nve_t entry) { if (entry->prev) entry->prev->next = entry->next; @@ -481,7 +511,7 @@ pkc_delete (pkc_t pk, pke_t entry) else pk->last = entry->prev; - pke_release (entry); + nve_release (entry, pk->private_key_mode); } @@ -489,10 +519,10 @@ pkc_delete (pkc_t pk, pke_t entry) /* Lookup and iteration. */ /* Get the first non-comment entry. */ -pke_t -pkc_first (pkc_t pk) +nve_t +nvc_first (nvc_t pk) { - pke_t entry; + nve_t entry; for (entry = pk->first; entry; entry = entry->next) if (entry->name) return entry; @@ -501,10 +531,10 @@ pkc_first (pkc_t pk) /* Get the first entry with the given name. */ -pke_t -pkc_lookup (pkc_t pk, const char *name) +nve_t +nvc_lookup (nvc_t pk, const char *name) { - pke_t entry; + nve_t entry; for (entry = pk->first; entry; entry = entry->next) if (entry->name && ascii_strcasecmp (entry->name, name) == 0) return entry; @@ -513,8 +543,8 @@ pkc_lookup (pkc_t pk, const char *name) /* Get the next non-comment entry. */ -pke_t -pke_next (pke_t entry) +nve_t +nve_next (nve_t entry) { for (entry = entry->next; entry; entry = entry->next) if (entry->name) @@ -524,8 +554,8 @@ pke_next (pke_t entry) /* Get the next entry with the given name. */ -pke_t -pke_next_value (pke_t entry, const char *name) +nve_t +nve_next_value (nve_t entry, const char *name) { for (entry = entry->next; entry; entry = entry->next) if (entry->name && ascii_strcasecmp (entry->name, name) == 0) @@ -539,14 +569,14 @@ pke_next_value (pke_t entry, const char *name) /* Get the private key. */ gpg_error_t -pkc_get_private_key (pkc_t pk, gcry_sexp_t *retsexp) +nvc_get_private_key (nvc_t pk, gcry_sexp_t *retsexp) { gpg_error_t err; - pke_t e; + nve_t e; - e = pkc_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) @@ -558,12 +588,15 @@ pkc_get_private_key (pkc_t pk, gcry_sexp_t *retsexp) /* Set the private key. */ gpg_error_t -pkc_set_private_key (pkc_t pk, gcry_sexp_t sexp) +nvc_set_private_key (nvc_t pk, gcry_sexp_t sexp) { gpg_error_t err; 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); @@ -605,7 +638,7 @@ pkc_set_private_key (pkc_t pk, gcry_sexp_t sexp) } *p = 0; - err = pkc_set (pk, "Key:", clean); + err = nvc_set (pk, "Key:", clean); xfree (raw); xfree (clean); return err; @@ -615,11 +648,9 @@ pkc_set_private_key (pkc_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 -pkc_parse (pkc_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; @@ -628,8 +659,7 @@ pkc_parse (pkc_t *result, int *errlinep, estream_t stream) char *name = NULL; strlist_t raw_value = NULL; - - *result = pkc_new (); + *result = for_private_key? nvc_new_private_key () : nvc_new (); if (*result == NULL) return my_error_from_syserror (); @@ -659,7 +689,7 @@ pkc_parse (pkc_t *result, int *errlinep, estream_t stream) /* No continuation. Add the current entry if any. */ if (raw_value) { - err = _pkc_add (*result, name, NULL, raw_value, 1); + err = _nvc_add (*result, name, NULL, raw_value, 1); if (err) goto leave; } @@ -675,7 +705,7 @@ pkc_parse (pkc_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; } @@ -708,13 +738,13 @@ pkc_parse (pkc_t *result, int *errlinep, estream_t stream) /* Add the final entry. */ if (raw_value) - err = _pkc_add (*result, name, NULL, raw_value, 1); + err = _nvc_add (*result, name, NULL, raw_value, 1); leave: gpgrt_free (buf); if (err) { - pkc_release (*result); + nvc_release (*result); *result = NULL; } @@ -722,12 +752,33 @@ pkc_parse (pkc_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 -pkc_write (pkc_t pk, estream_t stream) +nvc_write (nvc_t pk, estream_t stream) { gpg_error_t err; - pke_t entry; + nve_t entry; strlist_t s; for (entry = pk->first; entry; entry = entry->next) |