diff options
author | Werner Koch <[email protected]> | 2016-08-23 13:22:28 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2016-08-23 13:24:10 +0000 |
commit | be4ff75d7d5ac6ed15feb245ef3cec59b4bad561 (patch) | |
tree | 67dffdf32235e3e459aa52cd1b248420a6dc480f /src/verify.c | |
parent | core: Extend gpgme_user_id_t with 'address'. (diff) | |
download | gpgme-be4ff75d7d5ac6ed15feb245ef3cec59b4bad561.tar.gz gpgme-be4ff75d7d5ac6ed15feb245ef3cec59b4bad561.zip |
core: Change the way TOFU information are represented.
* src/gpgme.h.in (struct _gpgme_signature): Remove field 'tofu'. Add
field 'key'.
(struct _gpgme_key): Add field 'fpr'.
(struct _gpgme_user_id): Add field 'tofu'.
(struct _gpgme_tofu_info): Remove fields 'address' and 'fpr'.
* src/key.c (gpgme_key_unref): Release TOFU and FPR.
* src/keylist.c (keylist_colon_handler): Store the fingerprint of the
first subkey also in KEY.
* src/verify.c (release_tofu_info): Remove.
(release_op_data): Release KEY.
(parse_tofu_user): Rewrite for new data structure.
(parse_tofu_stats): Ditto.
(parse_tofu_stats_long): Ditto.
* tests/run-verify.c (print_result): Ditto.
* tests/run-keylist.c (main): Print more fields.
--
TOFU information are now associated with the user ID and not with a
separate object.
Note that this breaks code relying on the former non-released TOFU
feature. The C++ bindings won't work right now.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'src/verify.c')
-rw-r--r-- | src/verify.c | 106 |
1 files changed, 59 insertions, 47 deletions
diff --git a/src/verify.c b/src/verify.c index 1ec09fe8..173d1cb7 100644 --- a/src/verify.c +++ b/src/verify.c @@ -50,22 +50,6 @@ typedef struct static void -release_tofu_info (gpgme_tofu_info_t t) -{ - while (t) - { - gpgme_tofu_info_t t2 = t->next; - - free (t->address); - free (t->fpr); - free (t->description); - free (t); - t = t2; - } -} - - -static void release_op_data (void *hook) { op_data_t opd = (op_data_t) hook; @@ -88,7 +72,8 @@ release_op_data (void *hook) free (sig->fpr); if (sig->pka_address) free (sig->pka_address); - release_tofu_info (sig->tofu); + if (sig->key) + gpgme_key_unref (sig->key); free (sig); sig = next; } @@ -690,49 +675,80 @@ parse_tofu_user (gpgme_signature_t sig, char *args) { gpg_error_t err; char *tail; - gpgme_tofu_info_t ti, ti2; + gpgme_user_id_t uid; + gpgme_tofu_info_t ti; + char *fpr = NULL; + char *address = NULL; tail = strchr (args, ' '); if (!tail || tail == args) - return trace_gpg_error (GPG_ERR_INV_ENGINE); /* No fingerprint. */ + { + err = trace_gpg_error (GPG_ERR_INV_ENGINE); /* No fingerprint. */ + goto leave; + } *tail++ = 0; - ti = calloc (1, sizeof *ti); - if (!ti) - return gpg_error_from_syserror (); - - ti->fpr = strdup (args); - if (!ti->fpr) + fpr = strdup (args); + if (!fpr) { - free (ti); - return gpg_error_from_syserror (); + err = gpg_error_from_syserror (); + goto leave; } args = tail; tail = strchr (args, ' '); if (tail == args) - return trace_gpg_error (GPG_ERR_INV_ENGINE); /* No addr-spec. */ + { + err = trace_gpg_error (GPG_ERR_INV_ENGINE); /* No addr-spec. */ + goto leave; + } if (tail) *tail = 0; - err = _gpgme_decode_percent_string (args, &ti->address, 0, 0); + err = _gpgme_decode_percent_string (args, &address, 0, 0); if (err) + goto leave; + + if (!sig->key) { - free (ti); - return err; + err = _gpgme_key_new (&sig->key); + if (err) + goto leave; + sig->key->fpr = fpr; + fpr = NULL; + } + else if (!sig->key->fpr) + { + err = trace_gpg_error (GPG_ERR_INTERNAL); + goto leave; + } + else if (strcmp (sig->key->fpr, fpr)) + { + /* The engine did not emit NEWSIG before a new key. */ + err = trace_gpg_error (GPG_ERR_INV_ENGINE); + goto leave; } - /* Append to the tofu info list. */ - if (!sig->tofu) - sig->tofu = ti; - else + err = _gpgme_key_append_name (sig->key, address, 0); + if (err) + goto leave; + + uid = sig->key->_last_uid; + assert (uid); + + ti = calloc (1, sizeof *ti); + if (!ti) { - for (ti2 = sig->tofu; ti2->next; ti2 = ti2->next) - ; - ti2->next = ti; + err = gpg_error_from_syserror (); + goto leave; } + uid->tofu = ti; - return 0; + + leave: + free (fpr); + free (address); + return err; } @@ -749,12 +765,10 @@ parse_tofu_stats (gpgme_signature_t sig, char *args) int nfields; unsigned long uval; - if (!sig->tofu) + if (!sig->key || !sig->key->_last_uid || !(ti = sig->key->_last_uid->tofu)) return trace_gpg_error (GPG_ERR_INV_ENGINE); /* No TOFU_USER seen. */ - for (ti = sig->tofu; ti->next; ti = ti->next) - ; if (ti->firstseen || ti->signcount || ti->validity || ti->policy) - return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Already seen. */ + return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Already set. */ nfields = _gpgme_split_fields (args, field, DIM (field)); if (nfields < 3) @@ -825,12 +839,10 @@ parse_tofu_stats_long (gpgme_signature_t sig, char *args, int raw) gpgme_tofu_info_t ti; char *p; - if (!sig->tofu) + if (!sig->key || !sig->key->_last_uid || !(ti = sig->key->_last_uid->tofu)) return trace_gpg_error (GPG_ERR_INV_ENGINE); /* No TOFU_USER seen. */ - for (ti = sig->tofu; ti->next; ti = ti->next) - ; if (ti->description) - return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Already seen. */ + return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Already set. */ err = _gpgme_decode_percent_string (args, &ti->description, 0, 0); if (err) |