aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Klöcker <[email protected]>2026-08-03 15:55:35 +0200
committerIngo Klöcker <[email protected]>2026-08-03 15:55:35 +0200
commit7ba3ef8e40518ec109b6e0551ac3cc076c95b53f (patch)
tree51580823e08fa69e5a3158b8918b13ded20e128c
parentAdd helper to decode percent-plus encoded strings (diff)
downloadgpgme-7ba3ef8e40518ec109b6e0551ac3cc076c95b53f.tar.gz
gpgme-7ba3ef8e40518ec109b6e0551ac3cc076c95b53f.zip
Provide serial number and issuer of unknown S/MIME signing certificates
* src/gpgme.h.in (_gpgme_signature): Add fields issuer_serial and issuer_name. * src/verify.c (release_op_data): Free new fields. (parse_no_pubkey): New. (_gpgme_verify_status_handler): Handle NO_PUBKEY status code. * tests/run-verify.c (print_result): Print issuer_serial and issuer_name. -- GnuPG-bug-id: 8369
-rw-r--r--NEWS9
-rw-r--r--src/gpgme.h.in8
-rw-r--r--src/verify.c52
-rw-r--r--tests/run-verify.c2
4 files changed, 71 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 3d2fac10..8be0a280 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,15 @@
Noteworthy changes in version 2.1.3 (unreleased) [C46/A1/R_]
------------------------------------------------
+ * gpgme_verify_result_t now provides issuer serial number and issuer name
+ for S/MIME certificates used for signing that are not included in a
+ signature. [T8369]
+
+ * Interface changes relative to the 2.0.0 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gpgme_signature_t EXT: New fields "issuer_serial",
+ "issuer_name".
+
Release-info: https://dev.gnupg.org/T8311
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index c3fb843a..54dba0be 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -1731,6 +1731,14 @@ struct _gpgme_signature
/* If non-NULL, a possible incomplete key object with the data
* available for the signature. */
gpgme_key_t key;
+
+ /* If protocol is GPGME_PROTOCOL_CMS, this string may contain the
+ issuer serial. */
+ char *issuer_serial;
+
+ /* If protocol is GPGME_PROTOCOL_CMS, this string may contain the
+ issuer name. */
+ char *issuer_name;
};
typedef struct _gpgme_signature *gpgme_signature_t;
diff --git a/src/verify.c b/src/verify.c
index 8179e4a8..d221c30e 100644
--- a/src/verify.c
+++ b/src/verify.c
@@ -75,6 +75,10 @@ release_op_data (void *hook)
free (sig->pka_address);
if (sig->key)
gpgme_key_unref (sig->key);
+ if (sig->issuer_serial)
+ free (sig->issuer_serial);
+ if (sig->issuer_name)
+ free (sig->issuer_name);
free (sig);
sig = next;
}
@@ -944,6 +948,49 @@ parse_error (gpgme_signature_t sig, char *args, int set_status)
}
+static gpgme_error_t
+parse_no_pubkey (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol)
+{
+ gpgme_error_t err;
+ char *end;
+ char *name;
+
+ if (protocol != GPGME_PROTOCOL_CMS)
+ return 0;
+
+ /* Check that we only get one of these status codes per
+ signature; if not the crypto backend misbehaves. */
+ if (sig->issuer_serial || sig->issuer_name)
+ return trace_gpg_error (GPG_ERR_INV_ENGINE);
+
+ /* Parse #serialno/issuer */
+ end = strchr (args, ' ');
+ if (end)
+ *end = '\0';
+
+ if (*args != '#')
+ return trace_gpg_error (GPG_ERR_INV_ENGINE);
+ args++;
+
+ name = strchr (args, '/');
+ if (name)
+ {
+ *name = '\0';
+ name++;
+ }
+ if (!name || !*args || !*name)
+ return trace_gpg_error (GPG_ERR_INV_ENGINE);
+
+ err = _gpgme_decode_percent_plus_string (args, &sig->issuer_serial, 0, 0);
+ if (err)
+ return err;
+
+ err = _gpgme_decode_percent_plus_string (name, &sig->issuer_name, 0, 0);
+
+ return err;
+}
+
+
gpgme_error_t
_gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
{
@@ -1134,6 +1181,11 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
PARSE_COMPLIANCE_FLAGS (args, opd->current_sig);
break;
+ case GPGME_STATUS_NO_PUBKEY:
+ opd->only_newsig_seen = 0;
+ return sig ? parse_no_pubkey (sig, args, ctx->protocol)
+ : trace_gpg_error (GPG_ERR_INV_ENGINE);
+
default:
break;
}
diff --git a/tests/run-verify.c b/tests/run-verify.c
index b4f2e06f..93d492f4 100644
--- a/tests/run-verify.c
+++ b/tests/run-verify.c
@@ -145,6 +145,8 @@ print_result (gpgme_verify_result_t result)
printf (" status ....: %s\n", gpgme_strerror (sig->status));
printf (" summary ...:"); print_summary (sig->summary); putchar ('\n');
printf (" fingerprint: %s\n", nonnull (sig->fpr));
+ printf (" s/n .......: %s\n", nonnull (sig->issuer_serial));
+ printf (" issuer ....: %s\n", nonnull (sig->issuer_name));
printf (" created ...: %lu\n", sig->timestamp);
printf (" expires ...: %lu\n", sig->exp_timestamp);
printf (" validity ..: ");