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.
Backported-from-master: 6fa4d7973d
This commit is contained in:
parent
6fa4d7973d
commit
1af3c09831
@ -4040,7 +4040,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
|
||||||
|
|
||||||
|
28
g10/getkey.c
28
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);
|
||||||
@ -3653,7 +3664,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;
|
||||||
|
|
||||||
@ -3674,6 +3685,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
|
||||||
@ -3701,7 +3715,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");
|
||||||
@ -4021,7 +4036,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
|
||||||
|
@ -142,7 +142,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
|
||||||
@ -155,7 +155,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")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -385,7 +385,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)
|
||||||
{
|
{
|
||||||
@ -434,6 +434,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"));
|
||||||
@ -451,7 +458,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