diff --git a/g10/getkey.c b/g10/getkey.c index f91ec34eb..a5effb606 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -79,7 +79,8 @@ struct getkey_ctx_s /* Part of the search criteria: The type of the requested key. A mask of PUBKEY_USAGE_SIG, PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT. If non-zero, then for a key to match, it must implement one of - the required uses. */ + the required uses. FWIW: the req_usage field in PKT_public_key + used to be an u8 but meanwhile is an u16. */ int req_usage; /* The database handle. */ @@ -870,7 +871,12 @@ key_byname (ctrl_t ctrl, GETKEY_CTX *retctx, strlist_t namelist, if (pk) { + /* It is a bit tricky to allow returning an ADSK key: lookup + * masks the req_usage flags using the standard usage maps and + * only if ctx->allow_adsk is set, sets the RENC flag again. */ ctx->req_usage = pk->req_usage; + if ((pk->req_usage & PUBKEY_USAGE_RENC)) + ctx->allow_adsk = 1; } rc = lookup (ctrl, ctx, want_secret, ret_kb, &found_key); @@ -3684,7 +3690,7 @@ 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. */ + /* In allow ADSK mode make sure both encryption bits are set. */ if (allow_adsk && (req_usage & PUBKEY_USAGE_XENC_MASK)) req_usage |= PUBKEY_USAGE_XENC_MASK; @@ -3790,7 +3796,8 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact, log_debug ("\tsubkey not valid\n"); continue; } - if (!((pk->pubkey_usage & USAGE_MASK) & req_usage)) + if (!((pk->pubkey_usage & (USAGE_MASK | PUBKEY_USAGE_RENC)) + & req_usage)) { if (DBG_LOOKUP) log_debug ("\tusage does not match: want=%x have=%x\n", diff --git a/g10/keyedit.c b/g10/keyedit.c index b2018a2bd..9f4e4d9e5 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -4935,8 +4935,8 @@ append_adsk_to_key (ctrl_t ctrl, kbnode_t keyblock, PKT_public_key *adsk) /* Prepare and append the adsk. */ keyid_from_pk (main_pk, adsk->main_keyid); /* Fixup main keyid. */ - log_assert ((adsk->pubkey_usage & PUBKEY_USAGE_ENC)); - adsk->pubkey_usage = PUBKEY_USAGE_RENC; /* 'e' -> 'r' */ + log_assert ((adsk->pubkey_usage & PUBKEY_USAGE_XENC_MASK)); + adsk->pubkey_usage = PUBKEY_USAGE_RENC; /* 'e' or 'r' -> 'r' */ pkt = xtrycalloc (1, sizeof *pkt); if (!pkt) { diff --git a/g10/keygen.c b/g10/keygen.c index 81f03fdfb..bdb3cd43a 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -4646,7 +4646,7 @@ prepare_adsk (ctrl_t ctrl, const char *name) } adsk_pk = xcalloc (1, sizeof *adsk_pk); - adsk_pk->req_usage = PUBKEY_USAGE_ENC; + adsk_pk->req_usage = PUBKEY_USAGE_ENC | PUBKEY_USAGE_RENC; err = get_pubkey_byname (ctrl, GET_PUBKEY_TRY_LDAP, NULL, adsk_pk, name, NULL, NULL, 1); if (err) diff --git a/g10/packet.h b/g10/packet.h index 5cef17543..375392807 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -400,11 +400,10 @@ typedef struct when serializing. (Serialized.) */ byte version; byte selfsigversion; /* highest version of all of the self-sigs */ - /* The public key algorithm. (Serialized.) */ - byte pubkey_algo; - u16 pubkey_usage; /* carries the usage info. */ - byte req_usage; /* hack to pass a request to getkey() */ byte fprlen; /* 0 or length of FPR. */ + byte pubkey_algo; /* The public key algorithm. (PGP format) */ + u16 pubkey_usage; /* carries the usage info. */ + u16 req_usage; /* hack to pass a request to getkey() */ u32 has_expired; /* set to the expiration date if expired */ /* keyid of the primary key. Never access this value directly. Instead, use pk_main_keyid(). */