aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2025-05-05 13:52:08 +0000
committerWerner Koch <[email protected]>2025-05-05 14:01:10 +0000
commitbfd320abfeaf0c7a16af3057279c77a45bfa961a (patch)
treef5d006d0bd9eeb672bafe6c4ec17a5756c66cadf
parentMark the subkey used to find a key. (diff)
downloadgpgme-bfd320abfeaf0c7a16af3057279c77a45bfa961a.tar.gz
gpgme-bfd320abfeaf0c7a16af3057279c77a45bfa961a.zip
Allow signing using an exactly specified subkey.
* src/engine-gpg.c (append_args_from_signers): Detect exactly specified keys and apped the '!' suffix. -- Due to the ABI break which removed long long deprecated functions we can also risk to introduce a slight semantic change in the way signer keys are specified. The change is that iff a subkey-fingerprint with the '!' suffix was used to lookup a signer's key we now use this specific subkey and not any key gpg considers to be a good signing subkey. Most people would have considered the old behaviour anyway as a bug because it differs from what gpg uses at the command line. GnuPG-bug-id: 3325 Suggested-by: Benjamin Kibbey
-rw-r--r--NEWS5
-rw-r--r--doc/gpgme.texi9
-rw-r--r--src/engine-gpg.c38
-rw-r--r--src/keylist.c2
4 files changed, 44 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index df59388c..4e081683 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,11 @@ Noteworthy changes in version 2.0.0 (unreleased)
* New decrypt flag to skip the actual decryption so that information
about the recipients can be retrieved.
+ * If the key passed to gpgme_signers_add was retrieved with an exact
+ pattern (fingerprint with '!' suffix), the requested subkey is used
+ for signing. This reflects the behaviour of gpg but is a minor
+ semantic change. [T3325]
+
* Removed the gpgme_attr_t enums and their functions which were
deprecated since 2003. [rMd54d6eaa64]
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index bc4b1ac5..aadf9654 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -3658,6 +3658,11 @@ Brainpool curve.
The compliance flags (e.g. is_de_vs) are set but the software has not
yet been approved or is in a beta state.
+@item unsigned int subkey_match : 1;
+@since{2.0.0}
+This flag is set iff the key has been looked up using a
+fingerprint with a '!' suffix.
+
@item unsigned int secret : 1
This is true if the subkey is a secret key. Note that it will be
false if the key is actually a stub key; i.e., a secret key operation
@@ -6476,7 +6481,9 @@ Every context starts with an empty list.
@deftypefun gpgme_error_t gpgme_signers_add (@w{gpgme_ctx_t @var{ctx}}, @w{const gpgme_key_t @var{key}})
The function @code{gpgme_signers_add} adds the key @var{key} to the
-list of signers in the context @var{ctx}.
+list of signers in the context @var{ctx}. If the key has the
+subkey_match flag set (i.e. it was found via a fingerprint with '!'
+suffix) that specific subkey is used for signing.
Calling this function acquires an additional reference for the key.
@end deftypefun
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index c0391d11..eeb09c7b 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -2103,17 +2103,39 @@ append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
gpgme_error_t err = 0;
int i;
gpgme_key_t key;
+ gpgme_subkey_t subkey;
+ const char *s;
for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
{
- const char *s = key->subkeys ? key->subkeys->keyid : NULL;
- if (s)
- {
- if (!err)
- err = add_arg (gpg, "-u");
- if (!err)
- err = add_arg (gpg, s);
- }
+ if (key->subkeys)
+ {
+ /* First check whether any subkey has the subkey_match set
+ * and use that one. If that is not the case we use the
+ * fingerprint of the primary key or if that does not exist
+ * the keyid. */
+ for (subkey = key->subkeys; subkey; subkey = subkey->next)
+ if (subkey->subkey_match)
+ break;
+ if (subkey && subkey->fpr)
+ {
+ if (!err)
+ err = add_arg (gpg, "-u");
+ if (!err)
+ err = add_arg_pfx (gpg, subkey->fpr, "!");
+ }
+ else
+ {
+ subkey = key->subkeys; /* Reset to the primary key. */
+ if ((s=subkey->fpr) || (s=subkey->keyid))
+ {
+ if (!err)
+ err = add_arg (gpg, "-u");
+ if (!err)
+ err = add_arg (gpg, s);
+ }
+ }
+ }
gpgme_key_unref (key);
if (err)
break;
diff --git a/src/keylist.c b/src/keylist.c
index 11b68408..c0bf2155 100644
--- a/src/keylist.c
+++ b/src/keylist.c
@@ -1359,7 +1359,7 @@ gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
err = maybe_setup_for_requested_subkey (opd, pattern[i]);
if (err)
return TRACE_ERR (err);
- /* We can only handle one exact subnkey request. Thus we
+ /* We can only handle one exact subkey request. Thus we
* stop after the first seen. */
if (opd->requested_subkey)
break;