1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-09-20 14:51:42 +02:00

gpg: Improve decryption diagnostic for an ADSK key.

* g10/keydb.h (GET_PUBKEYBLOCK_FLAG_ADSK): New constant.
* g10/packet.h (PUBKEY_USAGE_XENC_MASK): New constant.
* g10/pubkey-enc.c (get_session_key): Consider an ADSK also as "marked
for encryption use".
(get_it): Print a note if an ADSK key was used.  Use the new
get_pubkeyblock flag.
* g10/getkey.c (struct getkey_ctx_s): Add field allow_adsk.
(get_pubkeyblock): Factor all code out to ...
(get_pubkeyblock_ext): new.
(finish_lookup): Add new arg allow_adsk and make use of it.
--

This patch solves two purposes:
- We write a note that the ADSK key was used for decryption
- We avoid running into a
  "oops: public key not found for preference check\n"
  due to ADSK keys.  The error is mostly harmless but lets gpg return
  with an exit code of 2.
This commit is contained in:
Werner Koch 2024-08-12 14:50:08 +02:00
parent 1d18c143f4
commit 882ab7fef9
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
5 changed files with 42 additions and 13 deletions

View File

@ -4076,7 +4076,7 @@ current home directory (@pxref{option --homedir}).
startup. It may contain options pertaining to all components of
GnuPG. Its current main use is for the "use-keyboxd" option. If
the default home directory @file{~/.gnupg} does not exist, GnuPG creates
this directory and a @file{common.conf} file with "use_keyboxd".
this directory and a @file{common.conf} file with "use-keyboxd".
@end table

View File

@ -68,6 +68,9 @@ struct getkey_ctx_s
details. */
int exact;
/* Allow returning an ADSK key. */
int allow_adsk;
/* Part of the search criteria: Whether the caller only wants keys
with an available secret key. This is used by getkey_next to get
the next result with the same initial criteria. */
@ -141,7 +144,8 @@ static int lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret,
kbnode_t *ret_keyblock, kbnode_t *ret_found_key);
static kbnode_t finish_lookup (kbnode_t keyblock,
unsigned int req_usage, int want_exact,
int want_secret, unsigned int *r_flags);
int want_secret, int allow_adsk,
unsigned int *r_flags);
static void print_status_key_considered (kbnode_t keyblock, unsigned int flags);
@ -586,7 +590,7 @@ get_pubkeyblock_for_sig (ctrl_t ctrl, PKT_signature *sig)
* The self-signed data has already been merged into the public key
* using merge_selfsigs. */
kbnode_t
get_pubkeyblock (ctrl_t ctrl, u32 * keyid)
get_pubkeyblock_ext (ctrl_t ctrl, u32 * keyid, unsigned int flags)
{
struct getkey_ctx_s ctx;
int rc = 0;
@ -602,6 +606,7 @@ get_pubkeyblock (ctrl_t ctrl, u32 * keyid)
ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
ctx.items[0].u.kid[0] = keyid[0];
ctx.items[0].u.kid[1] = keyid[1];
ctx.allow_adsk = !!(flags & GET_PUBKEYBLOCK_FLAG_ADSK);
rc = lookup (ctrl, &ctx, 0, &keyblock, NULL);
getkey_end (ctrl, &ctx);
@ -609,6 +614,12 @@ get_pubkeyblock (ctrl_t ctrl, u32 * keyid)
}
kbnode_t
get_pubkeyblock (ctrl_t ctrl, u32 * keyid)
{
return get_pubkeyblock_ext (ctrl, keyid, 0);
}
/* Return the public key with the key id KEYID iff the secret key is
* available and store it at PK. The resources should be released
* using release_public_key_parts().
@ -1770,7 +1781,7 @@ get_pubkey_fromfile (ctrl_t ctrl, PKT_public_key *pk, const char *fname,
/* Warning: node flag bits 0 and 1 should be preserved by
* merge_selfsigs. FIXME: Check whether this still holds. */
merge_selfsigs (ctrl, keyblock);
found_key = finish_lookup (keyblock, pk->req_usage, 0, 0, &infoflags);
found_key = finish_lookup (keyblock, pk->req_usage, 0, 0, 0, &infoflags);
print_status_key_considered (keyblock, infoflags);
if (found_key)
pk_from_block (pk, keyblock, found_key);
@ -3652,7 +3663,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
*/
static kbnode_t
finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
int want_secret, unsigned int *r_flags)
int want_secret, int allow_adsk, unsigned int *r_flags)
{
kbnode_t k;
@ -3673,6 +3684,9 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
#define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC|PUBKEY_USAGE_CERT)
req_usage &= USAGE_MASK;
/* In allow ADSK mode make sure both encryption bis are set. */
if (allow_adsk && (req_usage & PUBKEY_USAGE_XENC_MASK))
req_usage |= PUBKEY_USAGE_XENC_MASK;
/* Request the primary if we're certifying another key, and also if
* signing data while --pgp7 is on since pgp 7 do
@ -3700,7 +3714,8 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
pk->flags.exact = 1;
break;
}
else if ((k->pkt->pkt.public_key->pubkey_usage == PUBKEY_USAGE_RENC))
else if (!allow_adsk && (k->pkt->pkt.public_key->pubkey_usage
== PUBKEY_USAGE_RENC))
{
if (DBG_LOOKUP)
log_debug ("finish_lookup: found via ADSK - not selected\n");
@ -3806,7 +3821,7 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
}
if (opt.flags.require_pqc_encryption
&& (req_usage & PUBKEY_USAGE_ENC)
&& (req_usage & PUBKEY_USAGE_XENC_MASK)
&& pk->pubkey_algo != PUBKEY_ALGO_KYBER)
{
if (DBG_LOOKUP)
@ -3894,7 +3909,7 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
log_debug ("\tprimary key has expired\n");
}
else if (opt.flags.require_pqc_encryption
&& (req_usage & PUBKEY_USAGE_ENC)
&& (req_usage & PUBKEY_USAGE_XENC_MASK)
&& pk->pubkey_algo != PUBKEY_ALGO_KYBER)
{
if (DBG_LOOKUP)
@ -4037,7 +4052,8 @@ lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret,
* merge_selfsigs. */
merge_selfsigs (ctrl, keyblock);
found_key = finish_lookup (keyblock, ctx->req_usage, ctx->exact,
want_secret, &infoflags);
want_secret, ctx->allow_adsk,
&infoflags);
print_status_key_considered (keyblock, infoflags);
if (found_key)
{

View File

@ -351,6 +351,8 @@ int get_pubkey_fast (ctrl_t ctrl, PKT_public_key *pk, u32 *keyid);
kbnode_t get_pubkeyblock_for_sig (ctrl_t ctrl, PKT_signature *sig);
/* Return the key block for the key with KEYID. */
#define GET_PUBKEYBLOCK_FLAG_ADSK 1 /* Allow returning ADSK key. */
kbnode_t get_pubkeyblock_ext (ctrl_t ctrl, u32 *keyid, unsigned int flags);
kbnode_t get_pubkeyblock (ctrl_t ctrl, u32 *keyid);
/* A list used by get_pubkeys to gather all of the matches. */

View File

@ -60,10 +60,14 @@
#define PUBKEY_USAGE_RENC 1024 /* Restricted encryption. */
#define PUBKEY_USAGE_TIME 2048 /* Timestamp use. */
/* The usage bits which can be derived from the algo. */
#define PUBKEY_USAGE_BASIC_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC\
|PUBKEY_USAGE_CERT|PUBKEY_USAGE_AUTH)
/* The usage bits which define encryption. */
#define PUBKEY_USAGE_XENC_MASK (PUBKEY_USAGE_ENC | PUBKEY_USAGE_RENC)
/* Bitflags to convey hints on what kind of signature is created. */
#define SIGNHINT_KEYSIG 1
#define SIGNHINT_SELFSIG 2

View File

@ -143,7 +143,7 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek)
else if (opt.try_all_secrets
|| (k->keyid[0] == keyid[0] && k->keyid[1] == keyid[1]))
{
if (!opt.quiet && !(sk->pubkey_usage & PUBKEY_USAGE_ENC))
if (!opt.quiet && !(sk->pubkey_usage & PUBKEY_USAGE_XENC_MASK))
log_info (_("used key is not marked for encryption use.\n"));
}
else
@ -156,7 +156,7 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek)
if (!opt.quiet && !k->keyid[0] && !k->keyid[1])
{
log_info (_("okay, we are the anonymous recipient.\n"));
if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC))
if (!(sk->pubkey_usage & PUBKEY_USAGE_XENC_MASK))
log_info (_("used key is not marked for encryption use.\n")
);
}
@ -443,7 +443,7 @@ get_it (ctrl_t ctrl,
{
PKT_public_key *pk = NULL;
PKT_public_key *mainpk = NULL;
KBNODE pkb = get_pubkeyblock (ctrl, keyid);
KBNODE pkb = get_pubkeyblock_ext (ctrl, keyid, GET_PUBKEYBLOCK_FLAG_ADSK);
if (!pkb)
{
@ -495,6 +495,13 @@ get_it (ctrl_t ctrl,
}
}
if (pk && !(pk->pubkey_usage & PUBKEY_USAGE_ENC)
&& (pk->pubkey_usage & PUBKEY_USAGE_RENC))
{
log_info (_("Note: ADSK key has been used for decryption"));
log_printf ("\n");
}
if (pk && pk->flags.revoked)
{
log_info (_("Note: key has been revoked"));
@ -512,7 +519,7 @@ get_it (ctrl_t ctrl,
/* Note that we do not want to create a trustdb just for
* getting the ownertrust: If there is no trustdb there can't
* be ulitmately trusted key anyway and thus the ownertrust
* be an ultimately trusted key anyway and thus the ownertrust
* value is irrelevant. */
write_status_printf (STATUS_DECRYPTION_KEY, "%s %s %c",
pkhex, mainpkhex,