aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2023-09-04 15:03:01 +0000
committerWerner Koch <[email protected]>2023-09-04 15:03:52 +0000
commite36b2d1bce4bb6281e18f53d06d7831e6d6f5a09 (patch)
tree0bb1000300dbd0370f2d4b60605a35f88e6adcfd
parentbuild: Change the default for --with-libtool-modification. (diff)
downloadgpgme-e36b2d1bce4bb6281e18f53d06d7831e6d6f5a09.tar.gz
gpgme-e36b2d1bce4bb6281e18f53d06d7831e6d6f5a09.zip
New mode to list a v5 fingerprint for v4 packets.
* src/gpgme.h.in (GPGME_KEYLIST_MODE_WITH_V5FPR): New. (struct _gpgme_subkey): Add field v5fpr. * src/engine-gpg.c (gpg_keylist_build_options): Pass new option to gpg. * src/key.c (gpgme_key_unref): Free new field. * src/keylist.c (op_data_t): Parse and add "fp2" line. * tests/run-keylist.c (show_usage): Add option --v5fpr. * src/keylist.c (op_data_t): Add field failure_code. (keylist_status_handler): Handle special value. (gpgme_op_keylist_end): Return an error if a FAILURE line has been seen. -- Note that the failure code part has been added to better diagnose problems if a wrong gpg version is used. If verything works right we should not get this because we check that the gnupg version sis either >= 2.4.4 or less than 2.3 and >= 2.2.42. Note further that the v5fpr field may also be used to get the SHA-256 fingerprint of X.509 certificates (even without passing the new mode flag). GnuPG-bug-id: 6705
-rw-r--r--NEWS3
-rw-r--r--doc/gpgme.texi10
-rw-r--r--src/engine-gpg.c6
-rw-r--r--src/gpgme.h.in4
-rw-r--r--src/key.c1
-rw-r--r--src/keylist.c46
-rw-r--r--tests/run-keylist.c12
7 files changed, 78 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 1862faf8..6fcb6182 100644
--- a/NEWS
+++ b/NEWS
@@ -3,10 +3,13 @@ Noteworthy changes in version 1.23.0 (unreleased)
* Support GPGME_ENCRYPT_ALWAYS_TRUST also for S/MIME. [T6559]
+ * New keylist mode GPGME_KEYLIST_MODE_WITH_V5FPR. [T6705]
+
* qt: Support refreshing keys via WKD. [T6672]
* Interface changes relative to the 1.22.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ GPGME_KEYLIST_MODE_WITH_V5FPR NEW.
qt: Protocol::wkdRefreshJob NEW.
qt: WKDRefreshJob NEW.
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index 714ff916..bce1b163 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -2901,6 +2901,12 @@ option also makes sure that the keygrip is available in the output.
The @code{GPGME_KEYLIST_MODE_EPHEMERAL} symbol specifies that keys
flagged as ephemeral are included in the listing.
+@item GPGME_KEYLIST_MODE_WITH_V5FPR
+@since{1.23.0}
+
+The @code{GPGME_KEYLIST_MODE_WITH_V5FPR} symbol specifies that key
+listings shall also provide v5 style fingerprints for v4 OpenPGp keys.
+
@item GPGME_KEYLIST_MODE_VALIDATE
@since{0.4.5}
@@ -3610,6 +3616,10 @@ This is the key ID of the subkey in hexadecimal digits.
This is the fingerprint of the subkey in hexadecimal digits, if
available.
+@item char *v5fpr
+For a v4 OpenPGP key this is its v5 style fingerprint of the subkey in
+hexadecimal digits, if available.
+
@item char *keygrip
@since{1.7.0}
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 99667c6d..8c9f62fb 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -3267,6 +3267,12 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
err = add_arg (gpg, "--with-fingerprint");
}
+ if (!err && (mode & GPGME_KEYLIST_MODE_WITH_V5FPR)
+ && (have_gpg_version (gpg, "2.4.4")
+ || (have_gpg_version (gpg, "2.2.42")
+ && !have_gpg_version (gpg, "2.3.0"))))
+ err = add_arg (gpg, "--with-v5-fingerprint");
+
if (!err && (mode & GPGME_KEYLIST_MODE_WITH_TOFU)
&& have_gpg_version (gpg, "2.1.16"))
err = add_arg (gpg, "--with-tofu-info");
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 1d3c1445..7110648e 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -384,6 +384,7 @@ gpgme_protocol_t;
#define GPGME_KEYLIST_MODE_EPHEMERAL 128
#define GPGME_KEYLIST_MODE_VALIDATE 256
#define GPGME_KEYLIST_MODE_FORCE_EXTERN 512
+#define GPGME_KEYLIST_MODE_WITH_V5FPR 1024
#define GPGME_KEYLIST_MODE_LOCATE (1|2)
#define GPGME_KEYLIST_MODE_LOCATE_EXTERNAL (1|2|512)
@@ -616,6 +617,9 @@ struct _gpgme_subkey
/* The keygrip of the subkey in hex digit form or NULL if not available. */
char *keygrip;
+
+ /* For OpenPGP the v5 fpr of a v4 key. For X.509 the SHA256 fingerprint. */
+ char *v5fpr;
};
typedef struct _gpgme_subkey *gpgme_subkey_t;
diff --git a/src/key.c b/src/key.c
index 322bd0ac..93cdc1c8 100644
--- a/src/key.c
+++ b/src/key.c
@@ -342,6 +342,7 @@ gpgme_key_unref (gpgme_key_t key)
{
gpgme_subkey_t next = subkey->next;
free (subkey->fpr);
+ free (subkey->v5fpr);
free (subkey->curve);
free (subkey->keygrip);
free (subkey->card_number);
diff --git a/src/keylist.c b/src/keylist.c
index 3375f2ef..56836b5a 100644
--- a/src/keylist.c
+++ b/src/keylist.c
@@ -58,6 +58,9 @@ typedef struct
/* The error code from ERROR keydb_search. */
gpgme_error_t keydb_search_err;
+ /* The error code from a FAILURE status line or 0. */
+ gpg_error_t failure_code;
+
gpgme_key_t tmp_key;
/* This points to the last uid in tmp_key. */
@@ -146,6 +149,13 @@ keylist_status_handler (void *priv, gpgme_status_code_t code, char *args)
err = 0;
break;
+ case GPGME_STATUS_FAILURE:
+ opd->failure_code = _gpgme_parse_failure (args);
+ if (opd->failure_code && !strcmp (args, "option-parser")
+ && gpg_err_code (opd->failure_code) == GPG_ERR_GENERAL)
+ err = gpg_error (GPG_ERR_INV_ENGINE);
+ break;
+
case GPGME_STATUS_IMPORT_OK:
case GPGME_STATUS_IMPORT_PROBLEM:
case GPGME_STATUS_IMPORT_RES:
@@ -570,7 +580,7 @@ keylist_colon_handler (void *priv, char *line)
gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
enum
{
- RT_NONE, RT_SIG, RT_UID, RT_TFS, RT_SUB, RT_PUB, RT_FPR, RT_GRP,
+ RT_NONE, RT_SIG, RT_UID, RT_TFS, RT_SUB, RT_PUB, RT_FPR, RT_FP2, RT_GRP,
RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK
}
rectype = RT_NONE;
@@ -623,6 +633,8 @@ keylist_colon_handler (void *priv, char *line)
rectype = RT_CRS;
else if (!strcmp (field[0], "fpr") && key)
rectype = RT_FPR;
+ else if (!strcmp (field[0], "fp2") && key)
+ rectype = RT_FP2;
else if (!strcmp (field[0], "grp") && key)
rectype = RT_GRP;
else if (!strcmp (field[0], "uid") && key)
@@ -914,6 +926,27 @@ keylist_colon_handler (void *priv, char *line)
}
break;
+ case RT_FP2:
+ /* Either the SHA256 fingerprint of an X.509 cert or the
+ * alternate fingerprint of a v4 OpenPGP packet. (We take only
+ * the first one). */
+ if (fields >= 10 && field[9] && *field[9])
+ {
+ /* Need to apply it to the last subkey because all subkeys
+ do have fingerprints. */
+ subkey = key->_last_subkey;
+ if (!subkey->v5fpr)
+ {
+ subkey->v5fpr = strdup (field[9]);
+ if (!subkey->v5fpr)
+ return gpg_error_from_syserror ();
+ }
+ /* Note that we don't store a copy in the key object as we
+ * do with the standard fingerprint. */
+ }
+ break;
+
+
case RT_GRP:
/* Field 10 has the keygrip. */
if (fields >= 10 && field[9] && *field[9])
@@ -1299,12 +1332,21 @@ gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key)
gpgme_error_t
gpgme_op_keylist_end (gpgme_ctx_t ctx)
{
+ void *hook;
+ op_data_t opd;
+ gpg_error_t err;
+
TRACE (DEBUG_CTX, "gpgme_op_keylist_end", ctx, "");
if (!ctx)
return gpg_error (GPG_ERR_INV_VALUE);
- return 0;
+ err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
+ opd = hook;
+ if (!err && opd && opd->failure_code)
+ err = opd->failure_code;
+
+ return err;
}
diff --git a/tests/run-keylist.c b/tests/run-keylist.c
index c662e902..d517cac5 100644
--- a/tests/run-keylist.c
+++ b/tests/run-keylist.c
@@ -55,6 +55,7 @@ show_usage (int ex)
" --tofu use GPGME_KEYLIST_MODE_TOFU\n"
" --sig-notations use GPGME_KEYLIST_MODE_SIG_NOTATIONS\n"
" --ephemeral use GPGME_KEYLIST_MODE_EPHEMERAL\n"
+ " --v5fpr use GPGME_KEYLIST_MODE_V5FPR\n"
" --validate use GPGME_KEYLIST_MODE_VALIDATE\n"
" --import import all keys\n"
" --offline use offline mode\n"
@@ -179,9 +180,14 @@ main (int argc, char **argv)
mode |= GPGME_KEYLIST_MODE_VALIDATE;
argc--; argv++;
}
- else if (!strcmp (*argv, "--with-secret"))
+ else if (!strcmp (*argv, "--validate"))
+ {
+ mode |= GPGME_KEYLIST_MODE_VALIDATE;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--v5fpr"))
{
- mode |= GPGME_KEYLIST_MODE_WITH_SECRET;
+ mode |= GPGME_KEYLIST_MODE_WITH_V5FPR;
argc--; argv++;
}
else if (!strcmp (*argv, "--import"))
@@ -305,6 +311,8 @@ main (int argc, char **argv)
for (nsub=0; subkey; subkey = subkey->next, nsub++)
{
printf ("fpr %2d: %s\n", nsub, nonnull (subkey->fpr));
+ if (subkey->v5fpr)
+ printf ("v5fpr %2d: %s\n", nsub, nonnull (subkey->v5fpr));
if (subkey->keygrip)
printf ("grip %2d: %s\n", nsub, subkey->keygrip);
if (subkey->curve)