aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2025-11-18 10:57:37 +0000
committerWerner Koch <[email protected]>2025-11-18 11:14:55 +0000
commit5bcf5f57b8632edb7212f0d58d4b752d7627afeb (patch)
treed07f3ae053e7829e0b2ecdc60f65b92f6be5aa91
parentgpg: Cleanup of the local function key_byname. (diff)
downloadgnupg-5bcf5f57b8632edb7212f0d58d4b752d7627afeb.tar.gz
gnupg-5bcf5f57b8632edb7212f0d58d4b752d7627afeb.zip
gpg: Include ADSK keys in a key listing with fingerprints.
* g10/keydb.h (GET_PUBKEYBLOCK_FLAG_ADSK): Remove. (GETKEY_ALLOW_ADSK): New. * g10/getkey.c (get_pubkeyblock_ext): Use the new flag instead. Change the caller using the old flag. (key_byname): Support the GETKEY_ALLOW_ADSK flag. (getkey_bynames): Change to use aan arg flags instead of want_secret. This allows to pass more flag values. Adjust callers. * g10/keylist.c (list_one): Pass GETKEY_ALLOW_ADSK. -- Updates-commit: 882ab7fef9bf4440900c32d7463469307224f11a When using gpg -k <adsk-subkey-fingerprint> only the actual ADSK key (the one having the E capability set for the subkey) was listed. However, when using gpg -k <adsk-subkey-fingerprint>! all keys having this subkey (with E or R capability) were listed. This is suprising and thus needs to be fixed. With this patch the exact search ('!' suffix) is not anymore required. This bug was found while fixing the unrelated GnuPG-bug-id: 7892
-rw-r--r--g10/getkey.c19
-rw-r--r--g10/keydb.h5
-rw-r--r--g10/keylist.c5
-rw-r--r--g10/pubkey-enc.c2
-rw-r--r--g10/skclist.c3
5 files changed, 23 insertions, 11 deletions
diff --git a/g10/getkey.c b/g10/getkey.c
index d9f35a935..084bd654d 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -613,6 +613,7 @@ get_pubkey_fast (ctrl_t ctrl, PKT_public_key * pk, u32 * keyid)
/* Return the key block for the key with key id KEYID or NULL, if an
* error occurs. Use release_kbnode() to release the key block.
+ * The only supported FLAGS bit is GETKEY_ALLOW_ADSK.
*
* The self-signed data has already been merged into the public key
* using merge_selfsigs. */
@@ -633,7 +634,7 @@ get_pubkeyblock_ext (ctrl_t ctrl, u32 * keyid, unsigned int flags)
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);
+ ctx.allow_adsk = !!(flags & GETKEY_ALLOW_ADSK);
rc = lookup (ctrl, &ctx, 0, &keyblock, NULL);
getkey_end (ctrl, &ctx);
@@ -796,6 +797,10 @@ leave:
(see the documentation for skip_unusable for an exact definition)
are skipped unless they are looked up by key id or by fingerprint.
+ If the GETKEY_ALLOW_ADSK bit is set in FLAGS, ADSK keys are always
+ returned. Without that they are only returned if they have been
+ requested by PK->REQ_USAGE.
+
If RET_KB is not NULL, the keyblock is returned in *RET_KB. This
should be freed using release_kbnode().
@@ -884,6 +889,7 @@ key_byname (ctrl_t ctrl, GETKEY_CTX *retctx, strlist_t namelist,
}
ctx->want_secret = !!(flags & GETKEY_WANT_SECRET);
+ ctx->allow_adsk = !!(flags & GETKEY_ALLOW_ADSK);
ctx->kr_handle = keydb_new (ctrl);
if (!ctx->kr_handle)
{
@@ -898,6 +904,7 @@ key_byname (ctrl_t ctrl, GETKEY_CTX *retctx, strlist_t namelist,
if (ret_kdbhd)
keydb_lock (ctx->kr_handle);
+
if (pk)
{
/* It is a bit tricky to allow returning an ADSK key: lookup
@@ -2302,8 +2309,9 @@ get_seckey_default (ctrl_t ctrl, PKT_public_key *pk)
* database does an OR of the terms, not an AND.) If NAMES is
* NULL, then all results are returned.
*
- * If WANT_SECRET is set, then only keys with an available secret key
- * (either locally or via key registered on a smartcard) are returned.
+ * If GETKEY_WANT_SECRET is set in FLAGS, only keys with an available
+ * secret key (either locally or via key registered on a smartcard)
+ * are returned.
*
* This function does not skip unusable keys (see the documentation
* for skip_unusable for an exact definition).
@@ -2316,11 +2324,10 @@ get_seckey_default (ctrl_t ctrl, PKT_public_key *pk)
* (if want_secret is set) is returned if the key is not found. */
gpg_error_t
getkey_bynames (ctrl_t ctrl, getkey_ctx_t *retctx, PKT_public_key *pk,
- strlist_t names, int want_secret, kbnode_t *ret_keyblock)
+ strlist_t names, unsigned int flags, kbnode_t *ret_keyblock)
{
return key_byname (ctrl, retctx, names, pk,
- ((want_secret ? GETKEY_WANT_SECRET : 0)
- | GETKEY_WITH_UNUSABLE),
+ (flags | GETKEY_WITH_UNUSABLE),
ret_keyblock, NULL);
}
diff --git a/g10/keydb.h b/g10/keydb.h
index 526620ce4..364e1287c 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -357,7 +357,6 @@ 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);
@@ -387,6 +386,8 @@ enum get_pubkey_modes
/* Other flags for functions in getkey.c */
#define GETKEY_WANT_SECRET 1 /* Only return keys having a secret key. */
#define GETKEY_WITH_UNUSABLE 2 /* Include unusable keys. */
+#define GETKEY_ALLOW_ADSK 4 /* Always return ADSK keys. */
+
/* Find a public key identified by NAME. */
int get_pubkey_byname (ctrl_t ctrl, enum get_pubkey_modes mode,
@@ -453,7 +454,7 @@ gpg_error_t get_seckey_default_or_card (ctrl_t ctrl, PKT_public_key *pk,
/* Search for keys matching some criteria. */
gpg_error_t getkey_bynames (ctrl_t ctrl,
getkey_ctx_t *retctx, PKT_public_key *pk,
- strlist_t names, int want_secret,
+ strlist_t names, unsigned int flags,
kbnode_t *ret_keyblock);
/* Search for one key matching some criteria. */
diff --git a/g10/keylist.c b/g10/keylist.c
index e45471e87..aabffe9bb 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -934,7 +934,10 @@ list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret)
* functions) or to have the search function return indicators for
* found names. Yet another way is to use the keydb search
* facilities directly. */
- rc = getkey_bynames (ctrl, &ctx, NULL, names, secret, &keyblock);
+ rc = getkey_bynames (ctrl, &ctx, NULL, names,
+ (GETKEY_ALLOW_ADSK
+ | (secret ? GETKEY_WANT_SECRET : 0)),
+ &keyblock);
if (rc)
{
log_error ("error reading key: %s\n", gpg_strerror (rc));
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index d9a68d587..396e125d9 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -461,7 +461,7 @@ get_it (ctrl_t ctrl,
{
PKT_public_key *pk = NULL;
PKT_public_key *mainpk = NULL;
- KBNODE pkb = get_pubkeyblock_ext (ctrl, keyid, GET_PUBKEYBLOCK_FLAG_ADSK);
+ kbnode_t pkb = get_pubkeyblock_ext (ctrl, keyid, GETKEY_ALLOW_ADSK);
if (!pkb)
{
diff --git a/g10/skclist.c b/g10/skclist.c
index fe77aaede..6b16879ce 100644
--- a/g10/skclist.c
+++ b/g10/skclist.c
@@ -444,7 +444,8 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
break;
case 5: /* Init search context to enum all secret keys. */
- err = getkey_bynames (ctrl, &c->ctx, NULL, NULL, 1,
+ err = getkey_bynames (ctrl, &c->ctx, NULL, NULL,
+ GETKEY_WANT_SECRET,
&keyblock);
if (err)
{