aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-10-31 14:11:55 +0000
committerWerner Koch <[email protected]>2024-10-31 14:20:16 +0000
commit6c58694a885bb9e6b0d0324eeb59e22c29ec4d30 (patch)
tree589a0d7cfa5d6303159ee5bdd8cf750efb05dfb4
parentagent: Fix status output for LISTTRUSTED. (diff)
downloadgnupg-6c58694a885bb9e6b0d0324eeb59e22c29ec4d30.tar.gz
gnupg-6c58694a885bb9e6b0d0324eeb59e22c29ec4d30.zip
gpg: Allow the use of an ADSK subkey as ADSK subkey.
* g10/packet.h (PKT_public_key): Increased size of req_usage to 16. * g10/getkey.c (key_byname): Set allow_adsk in the context if ir was requested via req_usage. (finish_lookup): Allow RENC usage matching. * g10/keyedit.c (append_adsk_to_key): Adjust the assert. * g10/keygen.c (prepare_adsk): Also allow to find an RENC subkey. -- If an ADSK is to be added it may happen that an ADSK subkey is found first and this should then be used even that it does not have the E usage. However, it used to have that E usage when it was added. While testing this I found another pecularity: If you do gpg -k ADSK_SUBKEY_FPR without the '!' suffix and no corresponding encryption subkey is dound, you will get an unusabe key error. I hesitate to fix that due to possible side-effects. GnuPG-bug-id: 6882 Backported-from-master: d30e345692440b9c6677118c1d20b9d17d80f873 Note that we still use the NO_AKL and not the newer TRY_LDAP in 2.2. We may want to backport that change as well.
-rw-r--r--g10/getkey.c13
-rw-r--r--g10/keyedit.c4
-rw-r--r--g10/keygen.c2
-rw-r--r--g10/packet.h5
4 files changed, 15 insertions, 9 deletions
diff --git a/g10/getkey.c b/g10/getkey.c
index d7e3909c0..105c95232 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -77,7 +77,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. */
@@ -978,7 +979,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);
@@ -3702,7 +3708,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;
@@ -3807,7 +3813,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 e31f13935..8c61e637e 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -4757,8 +4757,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 79565b2ae..c9122f79e 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -4046,7 +4046,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_NO_AKL,
NULL, adsk_pk, name, NULL, NULL, 1);
if (err)
diff --git a/g10/packet.h b/g10/packet.h
index 7621d85e6..4d9b68a62 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -400,10 +400,9 @@ 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;
+ byte pubkey_algo; /* The public key algorithm. (PGP format) */
u16 pubkey_usage; /* carries the usage info. */
- byte req_usage; /* hack to pass a request to getkey() */
+ 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(). */