mirror of
git://git.gnupg.org/gnupg.git
synced 2024-11-10 21:38:50 +01: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:
parent
1d18c143f4
commit
882ab7fef9
@ -4076,7 +4076,7 @@ current home directory (@pxref{option --homedir}).
|
|||||||
startup. It may contain options pertaining to all components of
|
startup. It may contain options pertaining to all components of
|
||||||
GnuPG. Its current main use is for the "use-keyboxd" option. If
|
GnuPG. Its current main use is for the "use-keyboxd" option. If
|
||||||
the default home directory @file{~/.gnupg} does not exist, GnuPG creates
|
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
|
@end table
|
||||||
|
|
||||||
|
32
g10/getkey.c
32
g10/getkey.c
@ -68,6 +68,9 @@ struct getkey_ctx_s
|
|||||||
details. */
|
details. */
|
||||||
int exact;
|
int exact;
|
||||||
|
|
||||||
|
/* Allow returning an ADSK key. */
|
||||||
|
int allow_adsk;
|
||||||
|
|
||||||
/* Part of the search criteria: Whether the caller only wants keys
|
/* Part of the search criteria: Whether the caller only wants keys
|
||||||
with an available secret key. This is used by getkey_next to get
|
with an available secret key. This is used by getkey_next to get
|
||||||
the next result with the same initial criteria. */
|
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);
|
kbnode_t *ret_keyblock, kbnode_t *ret_found_key);
|
||||||
static kbnode_t finish_lookup (kbnode_t keyblock,
|
static kbnode_t finish_lookup (kbnode_t keyblock,
|
||||||
unsigned int req_usage, int want_exact,
|
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);
|
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
|
* The self-signed data has already been merged into the public key
|
||||||
* using merge_selfsigs. */
|
* using merge_selfsigs. */
|
||||||
kbnode_t
|
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;
|
struct getkey_ctx_s ctx;
|
||||||
int rc = 0;
|
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].mode = KEYDB_SEARCH_MODE_LONG_KID;
|
||||||
ctx.items[0].u.kid[0] = keyid[0];
|
ctx.items[0].u.kid[0] = keyid[0];
|
||||||
ctx.items[0].u.kid[1] = keyid[1];
|
ctx.items[0].u.kid[1] = keyid[1];
|
||||||
|
ctx.allow_adsk = !!(flags & GET_PUBKEYBLOCK_FLAG_ADSK);
|
||||||
rc = lookup (ctrl, &ctx, 0, &keyblock, NULL);
|
rc = lookup (ctrl, &ctx, 0, &keyblock, NULL);
|
||||||
getkey_end (ctrl, &ctx);
|
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
|
/* 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
|
* available and store it at PK. The resources should be released
|
||||||
* using release_public_key_parts().
|
* 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
|
/* Warning: node flag bits 0 and 1 should be preserved by
|
||||||
* merge_selfsigs. FIXME: Check whether this still holds. */
|
* merge_selfsigs. FIXME: Check whether this still holds. */
|
||||||
merge_selfsigs (ctrl, keyblock);
|
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);
|
print_status_key_considered (keyblock, infoflags);
|
||||||
if (found_key)
|
if (found_key)
|
||||||
pk_from_block (pk, keyblock, found_key);
|
pk_from_block (pk, keyblock, found_key);
|
||||||
@ -3652,7 +3663,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
|
|||||||
*/
|
*/
|
||||||
static kbnode_t
|
static kbnode_t
|
||||||
finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
|
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;
|
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)
|
#define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC|PUBKEY_USAGE_CERT)
|
||||||
req_usage &= USAGE_MASK;
|
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
|
/* Request the primary if we're certifying another key, and also if
|
||||||
* signing data while --pgp7 is on since pgp 7 do
|
* 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;
|
pk->flags.exact = 1;
|
||||||
break;
|
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)
|
if (DBG_LOOKUP)
|
||||||
log_debug ("finish_lookup: found via ADSK - not selected\n");
|
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
|
if (opt.flags.require_pqc_encryption
|
||||||
&& (req_usage & PUBKEY_USAGE_ENC)
|
&& (req_usage & PUBKEY_USAGE_XENC_MASK)
|
||||||
&& pk->pubkey_algo != PUBKEY_ALGO_KYBER)
|
&& pk->pubkey_algo != PUBKEY_ALGO_KYBER)
|
||||||
{
|
{
|
||||||
if (DBG_LOOKUP)
|
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");
|
log_debug ("\tprimary key has expired\n");
|
||||||
}
|
}
|
||||||
else if (opt.flags.require_pqc_encryption
|
else if (opt.flags.require_pqc_encryption
|
||||||
&& (req_usage & PUBKEY_USAGE_ENC)
|
&& (req_usage & PUBKEY_USAGE_XENC_MASK)
|
||||||
&& pk->pubkey_algo != PUBKEY_ALGO_KYBER)
|
&& pk->pubkey_algo != PUBKEY_ALGO_KYBER)
|
||||||
{
|
{
|
||||||
if (DBG_LOOKUP)
|
if (DBG_LOOKUP)
|
||||||
@ -4037,7 +4052,8 @@ lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret,
|
|||||||
* merge_selfsigs. */
|
* merge_selfsigs. */
|
||||||
merge_selfsigs (ctrl, keyblock);
|
merge_selfsigs (ctrl, keyblock);
|
||||||
found_key = finish_lookup (keyblock, ctx->req_usage, ctx->exact,
|
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);
|
print_status_key_considered (keyblock, infoflags);
|
||||||
if (found_key)
|
if (found_key)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
kbnode_t get_pubkeyblock_for_sig (ctrl_t ctrl, PKT_signature *sig);
|
||||||
|
|
||||||
/* Return the key block for the key with KEYID. */
|
/* 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);
|
kbnode_t get_pubkeyblock (ctrl_t ctrl, u32 *keyid);
|
||||||
|
|
||||||
/* A list used by get_pubkeys to gather all of the matches. */
|
/* A list used by get_pubkeys to gather all of the matches. */
|
||||||
|
@ -60,10 +60,14 @@
|
|||||||
#define PUBKEY_USAGE_RENC 1024 /* Restricted encryption. */
|
#define PUBKEY_USAGE_RENC 1024 /* Restricted encryption. */
|
||||||
#define PUBKEY_USAGE_TIME 2048 /* Timestamp use. */
|
#define PUBKEY_USAGE_TIME 2048 /* Timestamp use. */
|
||||||
|
|
||||||
|
|
||||||
/* The usage bits which can be derived from the algo. */
|
/* The usage bits which can be derived from the algo. */
|
||||||
#define PUBKEY_USAGE_BASIC_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC\
|
#define PUBKEY_USAGE_BASIC_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC\
|
||||||
|PUBKEY_USAGE_CERT|PUBKEY_USAGE_AUTH)
|
|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. */
|
/* Bitflags to convey hints on what kind of signature is created. */
|
||||||
#define SIGNHINT_KEYSIG 1
|
#define SIGNHINT_KEYSIG 1
|
||||||
#define SIGNHINT_SELFSIG 2
|
#define SIGNHINT_SELFSIG 2
|
||||||
|
@ -143,7 +143,7 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek)
|
|||||||
else if (opt.try_all_secrets
|
else if (opt.try_all_secrets
|
||||||
|| (k->keyid[0] == keyid[0] && k->keyid[1] == keyid[1]))
|
|| (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"));
|
log_info (_("used key is not marked for encryption use.\n"));
|
||||||
}
|
}
|
||||||
else
|
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])
|
if (!opt.quiet && !k->keyid[0] && !k->keyid[1])
|
||||||
{
|
{
|
||||||
log_info (_("okay, we are the anonymous recipient.\n"));
|
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")
|
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 *pk = NULL;
|
||||||
PKT_public_key *mainpk = 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)
|
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)
|
if (pk && pk->flags.revoked)
|
||||||
{
|
{
|
||||||
log_info (_("Note: key has been 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
|
/* Note that we do not want to create a trustdb just for
|
||||||
* getting the ownertrust: If there is no trustdb there can't
|
* 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. */
|
* value is irrelevant. */
|
||||||
write_status_printf (STATUS_DECRYPTION_KEY, "%s %s %c",
|
write_status_printf (STATUS_DECRYPTION_KEY, "%s %s %c",
|
||||||
pkhex, mainpkhex,
|
pkhex, mainpkhex,
|
||||||
|
Loading…
Reference in New Issue
Block a user