mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: Try Signer's User ID sub-packet with --auto-key-retrieve.
* g10/packet.h (PKT_signature): Add field 'signers_uid'. * g10/parse-packet.c (parse_signature): Set this field. * g10/free-packet.c (free_seckey_enc): Free field. (copy_signature): Copy field. * g10/mainproc.c (akl_has_wkd_method): New. (check_sig_and_print): Extend NEWSIG status. If WKD is enabled try to locate a missing key via the signature's Signer's User ID sub-packet. Do this right before trying a keyserver lookup. -- Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
18b03e756b
commit
08c82b1b55
@ -341,10 +341,12 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
|
||||
arguments in future versions.
|
||||
|
||||
** General status codes
|
||||
*** NEWSIG
|
||||
*** NEWSIG [<signers_uid>]
|
||||
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 <long_keyid_or_fpr> <username>
|
||||
The signature with the keyid is good. For each signature only one
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user