diff --git a/doc/gpg.texi b/doc/gpg.texi index 0c53bc1d4..7842e6200 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1669,12 +1669,13 @@ claim" signatures are always accepted. @item --trusted-key @var{long key ID or fingerprint} @opindex trusted-key -Assume that the specified key (which must be given -as a full 8 byte key ID or 20 byte fingerprint) is as trustworthy as one of -your own secret keys. This option is useful if you -don't want to keep your secret keys (or one of them) +Assume that the specified key (which should be given as fingerprint) +is as trustworthy as one of your own secret keys. This option is +useful if you don't want to keep your secret keys (or one of them) online but still want to be able to check the validity of a given -recipient's or signator's key. +recipient's or signator's key. If the given key is not locally +available but an LDAP keyserver is configured the missing key is +imported from that server. @item --trust-model @{pgp|classic|tofu|tofu+pgp|direct|always|auto@} @opindex trust-model diff --git a/g10/getkey.c b/g10/getkey.c index 8dd585ea9..1e6d7fb9f 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -558,6 +558,42 @@ leave: } +/* Same as get_pubkey but if the key was not found the function tries + * to import it from LDAP. FIXME: We should not need this but swicth + * to a fingerprint lookup. */ +gpg_error_t +get_pubkey_with_ldap_fallback (ctrl_t ctrl, PKT_public_key *pk, u32 *keyid) +{ + gpg_error_t err; + + err = get_pubkey (ctrl, pk, keyid); + if (!err) + return 0; + + if (gpg_err_code (err) != GPG_ERR_NO_PUBKEY) + return err; + + /* Note that this code does not handle the case for two readers + * having both openpgp encryption keys. Only one will be tried. */ + if (opt.debug) + log_debug ("using LDAP to find a public key\n"); + err = keyserver_import_keyid (ctrl, keyid, + opt.keyserver, KEYSERVER_IMPORT_FLAG_LDAP); + if (gpg_err_code (err) == GPG_ERR_NO_DATA + || gpg_err_code (err) == GPG_ERR_NO_KEYSERVER) + { + /* Dirmngr returns NO DATA is the selected keyserver + * does not have the requested key. It returns NO + * KEYSERVER if no LDAP keyservers are configured. */ + err = gpg_error (GPG_ERR_NO_PUBKEY); + } + if (err) + return err; + + return get_pubkey (ctrl, pk, keyid); +} + + /* Similar to get_pubkey, but it does not take PK->REQ_USAGE into * account nor does it merge in the self-signed data. This function * also only considers primary keys. It is intended to be used as a diff --git a/g10/keydb.h b/g10/keydb.h index e1a316cca..3ffd7691a 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -322,6 +322,10 @@ gpg_error_t get_pubkey_for_sig (ctrl_t ctrl, /* Return the public key with the key id KEYID and store it at PK. */ int get_pubkey (ctrl_t ctrl, PKT_public_key *pk, u32 *keyid); +/* Same as get_pubkey but with auto LDAP fetch. */ +gpg_error_t get_pubkey_with_ldap_fallback (ctrl_t ctrl, + PKT_public_key *pk, u32 * keyid); + /* Similar to get_pubkey, but it does not take PK->REQ_USAGE into account nor does it merge in the self-signed data. This function also only considers primary keys. */ diff --git a/g10/trustdb.c b/g10/trustdb.c index 98e9e35a1..116cbe604 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -300,7 +300,7 @@ verify_own_keys (ctrl_t ctrl) PKT_public_key pk; memset (&pk, 0, sizeof pk); - rc = get_pubkey (ctrl, &pk, k->kid); + rc = get_pubkey_with_ldap_fallback (ctrl, &pk, k->kid); if (rc) log_info(_("key %s: no public key for trusted key - skipped\n"), keystr(k->kid));