mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
gpg: With --auto-key-retrieve prefer WKD over keyservers.
* g10/mainproc.c (check_sig_and_print): Print a hint on how to make use of the preferred keyserver. Remove keyserver lookup just by the keyid. Try a WKD lookup before a keyserver lookup. -- The use of the the keyid for lookups does not make much sense anymore since for quite some time we do have the fingerprint as part of the signature. GnuPG-bug-id: 4595 Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
b0e8724b10
commit
96bf8f4778
24
doc/gpg.texi
24
doc/gpg.texi
@ -1814,10 +1814,26 @@ These options enable or disable the automatic retrieving of keys from
|
|||||||
a keyserver when verifying signatures made by keys that are not on the
|
a keyserver when verifying signatures made by keys that are not on the
|
||||||
local keyring. The default is @option{--no-auto-key-retrieve}.
|
local keyring. The default is @option{--no-auto-key-retrieve}.
|
||||||
|
|
||||||
If the method "wkd" is included in the list of methods given to
|
The order of methods tried to lookup the key is:
|
||||||
@option{auto-key-locate}, the signer's user ID is part of the
|
|
||||||
signature, and the option @option{--disable-signer-uid} is not used,
|
1. If a preferred keyserver is specified in the signature and the
|
||||||
the "wkd" method may also be used to retrieve a key.
|
option @option{honor-keyserver-url} is active (which is not the
|
||||||
|
default), that keyserver is tried. Note that the creator of the
|
||||||
|
signature uses the option @option{--sig-keyserver-url} to specify the
|
||||||
|
preferred keyserver for data signatures.
|
||||||
|
|
||||||
|
2. If the signature has the Signer's UID set (e.g. using
|
||||||
|
@option{--sender} while creating the signature) a Web Key Directory
|
||||||
|
(WKD) lookup is done. This is the default configuration but can be
|
||||||
|
disabled by removing WKD from the auto-key-locate list or by using the
|
||||||
|
option @option{--disable-signer-uid}.
|
||||||
|
|
||||||
|
3. If the option @option{honor-pka-record} is active, the legacy PKA
|
||||||
|
method is used.
|
||||||
|
|
||||||
|
4. If any keyserver is configured and the Issuer Fingerprint is part
|
||||||
|
of the signature (since GnuPG 2.1.16), the configured keyservers are
|
||||||
|
tried.
|
||||||
|
|
||||||
Note that this option makes a "web bug" like behavior possible.
|
Note that this option makes a "web bug" like behavior possible.
|
||||||
Keyserver or Web Key Directory operators can see which keys you
|
Keyserver or Web Key Directory operators can see which keys you
|
||||||
|
@ -333,7 +333,7 @@ parse_keyserver_uri (const char *string,int require_scheme)
|
|||||||
{
|
{
|
||||||
/* Three slashes means network path with a default host name.
|
/* Three slashes means network path with a default host name.
|
||||||
This is a hack because it does not crok all possible
|
This is a hack because it does not crok all possible
|
||||||
combiantions. We should better repalce all code bythe parser
|
combinations. We should better replace all code by the parser
|
||||||
from http.c. */
|
from http.c. */
|
||||||
keyserver->path = xstrdup (uri+2);
|
keyserver->path = xstrdup (uri+2);
|
||||||
}
|
}
|
||||||
|
116
g10/mainproc.c
116
g10/mainproc.c
@ -1843,7 +1843,6 @@ check_sig_and_print (CTX c, kbnode_t node)
|
|||||||
int is_revkey = 0;
|
int is_revkey = 0;
|
||||||
char *issuer_fpr = NULL;
|
char *issuer_fpr = NULL;
|
||||||
PKT_public_key *pk = NULL; /* The public key for the signature or NULL. */
|
PKT_public_key *pk = NULL; /* The public key for the signature or NULL. */
|
||||||
int tried_ks_by_fpr;
|
|
||||||
const void *extrahash = NULL;
|
const void *extrahash = NULL;
|
||||||
size_t extrahashlen = 0;
|
size_t extrahashlen = 0;
|
||||||
|
|
||||||
@ -2002,12 +2001,17 @@ check_sig_and_print (CTX c, kbnode_t node)
|
|||||||
rc = do_check_sig (c, node, extrahash, extrahashlen,
|
rc = do_check_sig (c, node, extrahash, extrahashlen,
|
||||||
NULL, &is_expkey, &is_revkey, &pk);
|
NULL, &is_expkey, &is_revkey, &pk);
|
||||||
|
|
||||||
/* If the key isn't found, check for a preferred keyserver. */
|
/* If the key isn't found, check for a preferred keyserver. Note
|
||||||
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY && sig->flags.pref_ks)
|
* that this is only done if honor-keyserver-url has been set. We
|
||||||
|
* test for this in the loop so that we can show info about the
|
||||||
|
* preferred keyservers. */
|
||||||
|
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
|
||||||
|
&& sig->flags.pref_ks)
|
||||||
{
|
{
|
||||||
const byte *p;
|
const byte *p;
|
||||||
int seq = 0;
|
int seq = 0;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
int any_pref_ks = 0;
|
||||||
|
|
||||||
while ((p=enum_sig_subpkt (sig->hashed,SIGSUBPKT_PREF_KS,&n,&seq,NULL)))
|
while ((p=enum_sig_subpkt (sig->hashed,SIGSUBPKT_PREF_KS,&n,&seq,NULL)))
|
||||||
{
|
{
|
||||||
@ -2018,9 +2022,10 @@ check_sig_and_print (CTX c, kbnode_t node)
|
|||||||
log_info(_("Key available at: ") );
|
log_info(_("Key available at: ") );
|
||||||
print_utf8_buffer (log_get_stream(), p, n);
|
print_utf8_buffer (log_get_stream(), p, n);
|
||||||
log_printf ("\n");
|
log_printf ("\n");
|
||||||
|
any_pref_ks = 1;
|
||||||
|
|
||||||
if (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE
|
if ((opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)
|
||||||
&& opt.keyserver_options.options&KEYSERVER_HONOR_KEYSERVER_URL)
|
&& (opt.keyserver_options.options&KEYSERVER_HONOR_KEYSERVER_URL))
|
||||||
{
|
{
|
||||||
struct keyserver_spec *spec;
|
struct keyserver_spec *spec;
|
||||||
|
|
||||||
@ -2029,6 +2034,10 @@ check_sig_and_print (CTX c, kbnode_t node)
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
if (DBG_LOOKUP)
|
||||||
|
log_debug ("trying auto-key-retrieve method %s\n",
|
||||||
|
"Pref-KS");
|
||||||
|
|
||||||
free_public_key (pk);
|
free_public_key (pk);
|
||||||
pk = NULL;
|
pk = NULL;
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
glo_ctrl.in_auto_key_retrieve++;
|
||||||
@ -2037,6 +2046,9 @@ check_sig_and_print (CTX c, kbnode_t node)
|
|||||||
if (!res)
|
if (!res)
|
||||||
rc = do_check_sig (c, node, extrahash, extrahashlen,
|
rc = do_check_sig (c, node, extrahash, extrahashlen,
|
||||||
NULL, &is_expkey, &is_revkey, &pk);
|
NULL, &is_expkey, &is_revkey, &pk);
|
||||||
|
else if (DBG_LOOKUP)
|
||||||
|
log_debug ("lookup via %s failed: %s\n", "Pref-KS",
|
||||||
|
gpg_strerror (res));
|
||||||
free_keyserver_spec (spec);
|
free_keyserver_spec (spec);
|
||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
@ -2044,10 +2056,44 @@ check_sig_and_print (CTX c, kbnode_t node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (any_pref_ks
|
||||||
|
&& (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)
|
||||||
|
&& !(opt.keyserver_options.options&KEYSERVER_HONOR_KEYSERVER_URL))
|
||||||
|
log_info (_("Note: Use '%s' to make use of this info\n"),
|
||||||
|
"--keyserver-option honor-keyserver-url");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the above methods didn't work, our next try is to retrieve the
|
||||||
|
* key from the WKD. This requires that WKD is in the AKL and the
|
||||||
|
* Signer's UID is in the signature. */
|
||||||
|
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
|
||||||
|
&& (opt.keyserver_options.options & KEYSERVER_AUTO_KEY_RETRIEVE)
|
||||||
|
&& !opt.flags.disable_signer_uid
|
||||||
|
&& akl_has_wkd_method ()
|
||||||
|
&& sig->signers_uid)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (DBG_LOOKUP)
|
||||||
|
log_debug ("trying auto-key-retrieve method %s\n", "WKD");
|
||||||
|
free_public_key (pk);
|
||||||
|
pk = NULL;
|
||||||
|
glo_ctrl.in_auto_key_retrieve++;
|
||||||
|
res = keyserver_import_wkd (c->ctrl, sig->signers_uid, 1, 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, extrahash, extrahashlen,
|
||||||
|
NULL, &is_expkey, &is_revkey, &pk);
|
||||||
|
else if (DBG_LOOKUP)
|
||||||
|
log_debug ("lookup via %s failed: %s\n", "WKD", gpg_strerror (res));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the avove methods didn't work, our next try is to use the URI
|
/* If the avove methods didn't work, our next try is to use the URI
|
||||||
* from a DNS PKA record. */
|
* from a DNS PKA record. This is a legacy method which will
|
||||||
|
* eventually be removed. */
|
||||||
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
|
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
|
||||||
&& (opt.keyserver_options.options & KEYSERVER_AUTO_KEY_RETRIEVE)
|
&& (opt.keyserver_options.options & KEYSERVER_AUTO_KEY_RETRIEVE)
|
||||||
&& (opt.keyserver_options.options & KEYSERVER_HONOR_PKA_RECORD))
|
&& (opt.keyserver_options.options & KEYSERVER_HONOR_PKA_RECORD))
|
||||||
@ -2064,6 +2110,9 @@ check_sig_and_print (CTX c, kbnode_t node)
|
|||||||
spec = parse_keyserver_uri (uri, 1);
|
spec = parse_keyserver_uri (uri, 1);
|
||||||
if (spec)
|
if (spec)
|
||||||
{
|
{
|
||||||
|
if (DBG_LOOKUP)
|
||||||
|
log_debug ("trying auto-key-retrieve method %s\n", "PKA");
|
||||||
|
|
||||||
free_public_key (pk);
|
free_public_key (pk);
|
||||||
pk = NULL;
|
pk = NULL;
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
glo_ctrl.in_auto_key_retrieve++;
|
||||||
@ -2073,16 +2122,16 @@ check_sig_and_print (CTX c, kbnode_t node)
|
|||||||
if (!res)
|
if (!res)
|
||||||
rc = do_check_sig (c, node, extrahash, extrahashlen,
|
rc = do_check_sig (c, node, extrahash, extrahashlen,
|
||||||
NULL, &is_expkey, &is_revkey, &pk);
|
NULL, &is_expkey, &is_revkey, &pk);
|
||||||
|
else if (DBG_LOOKUP)
|
||||||
|
log_debug ("lookup via %s failed: %s\n", "PKA",
|
||||||
|
gpg_strerror (res));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the above methods didn't work, our next try is to locate
|
/* If the above methods didn't work, our next try is to locate
|
||||||
* the key via its fingerprint from a keyserver. This requires
|
* the key via its fingerprint from a keyserver. This requires
|
||||||
* that the signers fingerprint is encoded in the signature. We
|
* that the signers fingerprint is encoded in the signature. */
|
||||||
* favor this over the WKD method (to be tried next), because an
|
|
||||||
* arbitrary keyserver is less subject to web bug like monitoring. */
|
|
||||||
tried_ks_by_fpr = 0;
|
|
||||||
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
|
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
|
||||||
&& (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)
|
&& (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)
|
||||||
&& keyserver_any_configured (c->ctrl))
|
&& keyserver_any_configured (c->ctrl))
|
||||||
@ -2094,60 +2143,23 @@ check_sig_and_print (CTX c, kbnode_t node)
|
|||||||
p = issuer_fpr_raw (sig, &n);
|
p = issuer_fpr_raw (sig, &n);
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
|
if (DBG_LOOKUP)
|
||||||
|
log_debug ("trying auto-key-retrieve method %s\n", "KS");
|
||||||
|
|
||||||
/* v4 or v5 packet with a SHA-1/256 fingerprint. */
|
/* v4 or v5 packet with a SHA-1/256 fingerprint. */
|
||||||
free_public_key (pk);
|
free_public_key (pk);
|
||||||
pk = NULL;
|
pk = NULL;
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
glo_ctrl.in_auto_key_retrieve++;
|
||||||
res = keyserver_import_fprint (c->ctrl, p, n, opt.keyserver, 1);
|
res = keyserver_import_fprint (c->ctrl, p, n, opt.keyserver, 1);
|
||||||
tried_ks_by_fpr = 1;
|
|
||||||
glo_ctrl.in_auto_key_retrieve--;
|
glo_ctrl.in_auto_key_retrieve--;
|
||||||
if (!res)
|
if (!res)
|
||||||
rc = do_check_sig (c, node, extrahash, extrahashlen,
|
rc = do_check_sig (c, node, extrahash, extrahashlen,
|
||||||
NULL, &is_expkey, &is_revkey, &pk);
|
NULL, &is_expkey, &is_revkey, &pk);
|
||||||
|
else if (DBG_LOOKUP)
|
||||||
|
log_debug ("lookup via %s failed: %s\n", "KS", gpg_strerror (res));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
|
||||||
&& !opt.flags.disable_signer_uid
|
|
||||||
&& akl_has_wkd_method ()
|
|
||||||
&& sig->signers_uid)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
|
|
||||||
free_public_key (pk);
|
|
||||||
pk = NULL;
|
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
|
||||||
res = keyserver_import_wkd (c->ctrl, sig->signers_uid, 1, 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, extrahash, extrahashlen,
|
|
||||||
NULL, &is_expkey, &is_revkey, &pk);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
&& !tried_ks_by_fpr
|
|
||||||
&& keyserver_any_configured (c->ctrl))
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
|
|
||||||
free_public_key (pk);
|
|
||||||
pk = NULL;
|
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
|
||||||
res = keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver, 1);
|
|
||||||
glo_ctrl.in_auto_key_retrieve--;
|
|
||||||
if (!res)
|
|
||||||
rc = do_check_sig (c, node, extrahash, extrahashlen,
|
|
||||||
NULL, &is_expkey, &is_revkey, &pk);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rc || gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE)
|
if (!rc || gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE)
|
||||||
{
|
{
|
||||||
kbnode_t un, keyblock;
|
kbnode_t un, keyblock;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user