diff --git a/doc/DETAILS b/doc/DETAILS index d2df9ace4..2fcdb2830 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -341,10 +341,12 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: arguments in future versions. ** General status codes -*** NEWSIG +*** NEWSIG [] Is issued right before a signature verification starts. This is - useful to define a context for parsing ERROR status messages. No - arguments are currently defined. + useful to define a context for parsing ERROR status messages. + arguments are currently defined. If SIGNERS_UID is given and is + not "-" this is the percent escape value of the OpenPGP Signer's + User ID signature sub-packet. *** GOODSIG The signature with the keyid is good. For each signature only one diff --git a/g10/free-packet.c b/g10/free-packet.c index 8176e368b..3883f877a 100644 --- a/g10/free-packet.c +++ b/g10/free-packet.c @@ -82,6 +82,7 @@ free_seckey_enc( PKT_signature *sig ) xfree (sig->pka_info->uri); xfree (sig->pka_info); } + xfree (sig->signers_uid); xfree(sig); } @@ -258,6 +259,8 @@ copy_signature( PKT_signature *d, PKT_signature *s ) d->pka_info = s->pka_info? cp_pka_info (s->pka_info) : NULL; d->hashed = cp_subpktarea (s->hashed); d->unhashed = cp_subpktarea (s->unhashed); + if (s->signers_uid) + d->signers_uid = xstrdup (s->signers_uid); if(s->numrevkeys) { d->revkey=NULL; diff --git a/g10/mainproc.c b/g10/mainproc.c index 15dc4b9c0..7033de7dd 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -1541,6 +1541,19 @@ pka_uri_from_sig (CTX c, PKT_signature *sig) } +/* Return true if the AKL has the WKD method specified. */ +static int +akl_has_wkd_method (void) +{ + struct akl *akl; + + for (akl = opt.auto_key_locate; akl; akl = akl->next) + if (akl->type == AKL_WKD) + return 1; + return 0; +} + + static void print_good_bad_signature (int statno, const char *keyid_str, kbnode_t un, PKT_signature *sig, int rc) @@ -1697,7 +1710,11 @@ check_sig_and_print (CTX c, kbnode_t node) } } - write_status_text (STATUS_NEWSIG, NULL); + if (sig->signers_uid) + write_status_buffer (STATUS_NEWSIG, + sig->signers_uid, strlen (sig->signers_uid), 0); + else + write_status_text (STATUS_NEWSIG, NULL); astr = openpgp_pk_algo_name ( sig->pubkey_algo ); if (keystrlen () > 8) @@ -1713,8 +1730,7 @@ check_sig_and_print (CTX c, kbnode_t node) rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); - /* If the key isn't found, check for a preferred keyserver */ - + /* If the key isn't found, check for a preferred keyserver. */ if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY && sig->flags.pref_ks) { const byte *p; @@ -1755,8 +1771,8 @@ check_sig_and_print (CTX c, kbnode_t node) } } - /* If the preferred keyserver thing above didn't work, our second - try is to use the URI from a DNS PKA record. */ + /* If the avove methods didn't work, our next try is to use the URI + * from a DNS PKA record. */ if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY && (opt.keyserver_options.options & KEYSERVER_AUTO_KEY_RETRIEVE) && (opt.keyserver_options.options & KEYSERVER_HONOR_PKA_RECORD)) @@ -1775,17 +1791,54 @@ check_sig_and_print (CTX c, kbnode_t node) { glo_ctrl.in_auto_key_retrieve++; res = keyserver_import_keyid (c->ctrl, sig->keyid, spec); - glo_ctrl.in_auto_key_retrieve--; - free_keyserver_spec (spec); - if (!res) - rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); + glo_ctrl.in_auto_key_retrieve--; + free_keyserver_spec (spec); + if (!res) + rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); } } } - /* If the preferred keyserver thing above didn't work and we got - no information from the DNS PKA, this is a third try. */ + /* If the above methods didn't work, our next try is to use locate + * the key via its fingerprint from a keyserver. This requires + * that the signers fingerprint is encoded in the signature. We + * favor this over the WKD method (to be tried next), because an + * arbitrary keyserver is less subject to web bug like + * monitoring. */ + /* if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY */ + /* && signature_hash_full_fingerprint (sig) */ + /* && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE) */ + /* && keyserver_any_configured (c->ctrl)) */ + /* { */ + /* int res; */ + /* glo_ctrl.in_auto_key_retrieve++; */ + /* res = keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver ); */ + /* glo_ctrl.in_auto_key_retrieve--; */ + /* if (!res) */ + /* rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); */ + /* } */ + + /* If the above methods didn't work, our next try is to retrieve the + * key from the WKD. */ + if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY + && (opt.keyserver_options.options & KEYSERVER_AUTO_KEY_RETRIEVE) + && akl_has_wkd_method () + && sig->signers_uid) + { + int res; + + glo_ctrl.in_auto_key_retrieve++; + res = keyserver_import_wkd (c->ctrl, sig->signers_uid, NULL, NULL); + glo_ctrl.in_auto_key_retrieve--; + /* Fixme: If the fingerprint is embedded in the signature, + * compare it to the fingerprint of the returned key. */ + if (!res) + rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); + } + + /* If the above methods did't work, our next try is to use a + * keyserver. */ if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE) && keyserver_any_configured (c->ctrl)) @@ -1793,7 +1846,7 @@ check_sig_and_print (CTX c, kbnode_t node) int res; glo_ctrl.in_auto_key_retrieve++; - res=keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver ); + res = keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver ); glo_ctrl.in_auto_key_retrieve--; if (!res) rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); diff --git a/g10/packet.h b/g10/packet.h index 6ea2f8314..8fb6fc48f 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -230,6 +230,8 @@ typedef struct int numrevkeys; pka_info_t *pka_info; /* Malloced PKA data or NULL if not available. See also flags.pka_tried. */ + char *signers_uid; /* Malloced value of the SIGNERS_UID + * subpacket. */ subpktarea_t *hashed; /* All subpackets with hashed data (v4 only). */ subpktarea_t *unhashed; /* Ditto for unhashed data. */ /* First 2 bytes of the digest. (Serialized. Note: this is not diff --git a/g10/parse-packet.c b/g10/parse-packet.c index c77e409e5..c30abcbe3 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1915,6 +1915,20 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, if (p) sig->flags.pref_ks = 1; + p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIGNERS_UID, &len); + if (p && len) + { + sig->signers_uid = xtrymalloc (len+1); + if (!sig->signers_uid) + { + rc = gpg_error_from_syserror (); + goto leave; + } + /* Note that we don't care about binary zeroes in the value. */ + memcpy (sig->signers_uid, p, len); + sig->signers_uid[len] = 0; + } + p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_NOTATION, NULL); if (p) sig->flags.notation = 1;