aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-03-12 17:01:24 +0000
committerWerner Koch <[email protected]>2024-03-12 17:01:24 +0000
commit14c1b73093e3fcbc43b04dfc520eb35d61241489 (patch)
treea62908e140c613c1834d7f2b3d3c18fb322a092f
parentcard: Use xstrdup for module names. (diff)
downloadgnupg-14c1b73093e3fcbc43b04dfc520eb35d61241489.tar.gz
gnupg-14c1b73093e3fcbc43b04dfc520eb35d61241489.zip
gpg: new list-option show-x509-notations
* g10/gpg.c (parse_list_options): Add new option. * g10/options.h (LIST_SHOW_X509_NOTATIONS): New. * g10/build-packet.c (search_sig_notations): New. * g10/keylist.c (print_x509_notations): New. (list_signature_print): Use macros for the sig classes. Call print_x509_notations. (list_keyblock_print): Call list_signature_print if x509 notation printing is enabled.
-rw-r--r--doc/gpg.texi6
-rw-r--r--g10/build-packet.c66
-rw-r--r--g10/gpg.c1
-rw-r--r--g10/keylist.c69
-rw-r--r--g10/options.h1
-rw-r--r--g10/packet.h7
6 files changed, 134 insertions, 16 deletions
diff --git a/doc/gpg.texi b/doc/gpg.texi
index cb4506049..fb8d0f578 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -1410,6 +1410,12 @@ give the opposite meaning. The options are:
Show all, IETF standard, or user-defined signature notations in the
@option{--check-signatures} listings. Defaults to no.
+ @item show-x509-notations
+ @opindex list-options:show-x509-notations
+ Print X.509 certificates embedded in key signatures as PEM data.
+ This is intended for debugging and the output format may change
+ without notice.
+
@item show-keyserver-urls
@opindex list-options:show-keyserver-urls
Show any preferred keyserver URL in the
diff --git a/g10/build-packet.c b/g10/build-packet.c
index 19a13760a..9927b7695 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -1748,6 +1748,72 @@ sig_to_notation(PKT_signature *sig)
return list;
}
+
+/* Return a list of notation data matching NAME. The caller needs to
+ * to free the list using free_notation. Other than sig_to_notation
+ * this function does not return the notation in human readable format
+ * but always returns the raw data. The human readable flag is set
+ * anyway set but .value is always NULL. */
+struct notation *
+search_sig_notations (PKT_signature *sig, const char *name)
+{
+ const byte *p;
+ size_t len;
+ int seq = 0;
+ int crit;
+ notation_t list = NULL;
+
+ while((p=enum_sig_subpkt (sig, 1, SIGSUBPKT_NOTATION, &len, &seq, &crit)))
+ {
+ int n1,n2;
+ struct notation *n=NULL;
+
+ if (len < 8)
+ {
+ log_info (_("WARNING: invalid notation data found\n"));
+ continue;
+ }
+
+ /* name length. */
+ n1=(p[4]<<8)|p[5];
+ /* value length. */
+ n2=(p[6]<<8)|p[7];
+
+ if (8 + n1 + n2 != len)
+ {
+ log_info (_("WARNING: invalid notation data found\n"));
+ continue;
+ }
+
+ if (!name)
+ ; /* Return everything. */
+ else if (n1 != strlen (name) || memcmp (p+8, name, n1))
+ continue; /* Not the requested name. */
+
+
+ n = xmalloc_clear (sizeof *n);
+ n->name = xmalloc (n1+1);
+
+ memcpy (n->name,p + 8, n1);
+ n->name[n1]='\0';
+
+ /* In any case append a Nul. */
+ n->bdat = xmalloc (n2+1);
+ memcpy (n->bdat, p + 8 + n1, n2);
+ n->bdat[n2] = '\0';
+ n->blen = n2;
+ n->flags.human = !!(p[0] & 0x80);
+
+ n->flags.critical = crit;
+
+ n->next = list;
+ list = n;
+ }
+
+ return list;
+}
+
+
/* Release the resources associated with the *list* of notations. To
release a single notation, make sure that notation->next is
NULL. */
diff --git a/g10/gpg.c b/g10/gpg.c
index bef3b6fbd..8e0c6479e 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -2086,6 +2086,7 @@ parse_list_options(char *str)
NULL},
{"show-user-notations",LIST_SHOW_USER_NOTATIONS,NULL,
N_("show user-supplied notations during signature listings")},
+ {"show-x509-notations",LIST_SHOW_X509_NOTATIONS,NULL, NULL },
{"show-keyserver-urls",LIST_SHOW_KEYSERVER_URLS,NULL,
N_("show preferred keyserver URLs during signature listings")},
{"show-uid-validity",LIST_SHOW_UID_VALIDITY,NULL,
diff --git a/g10/keylist.c b/g10/keylist.c
index d0ebfc86f..20862b0f8 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -1171,6 +1171,36 @@ dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
}
+
+static void
+print_x509_notations (struct notation *nots)
+{
+ gpg_error_t err;
+ gpgrt_b64state_t state;
+
+ for (; nots; nots = nots->next)
+ {
+ state = gpgrt_b64enc_start (es_stdout, "CERTIFICATE");
+ if (!state)
+ {
+ err = gpg_err_code_from_syserror ();
+ goto b64fail;
+ }
+ err = gpgrt_b64enc_write (state, nots->bdat, nots->blen);
+ if (err)
+ goto b64fail;
+ err = gpgrt_b64enc_finish (state);
+ if (err)
+ goto b64fail;
+ }
+ return;
+
+ b64fail:
+ log_error ("error writing base64 encoded notation: %s\n", gpg_strerror (err));
+ gpgrt_b64enc_finish (state);
+}
+
+
/* Order two signatures. We first order by keyid and then by creation
* time. */
int
@@ -1278,19 +1308,18 @@ list_signature_print (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node,
sigrc = ' ';
}
- if (sig->sig_class == 0x20 || sig->sig_class == 0x28
- || sig->sig_class == 0x30)
+ if (IS_KEY_REV (sig) || IS_SUBKEY_REV (sig) || IS_UID_REV (sig))
{
sigstr = "rev";
reason_code = get_revocation_reason (sig, &reason_text,
&reason_comment,
&reason_commentlen);
}
- else if ((sig->sig_class & ~3) == 0x10)
+ else if (IS_UID_SIG (sig))
sigstr = "sig";
- else if (sig->sig_class == 0x18)
+ else if (IS_SUBKEY_SIG (sig))
sigstr = "sig";
- else if (sig->sig_class == 0x1F)
+ else if (IS_KEY_SIG (sig))
sigstr = "sig";
else
{
@@ -1337,13 +1366,27 @@ list_signature_print (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node,
show_policy_url (sig, 3, 0);
if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
- show_notation (sig, 3, 0,
- ((opt.
- list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
- +
- ((opt.
- list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
- 0));
+ show_notation (sig, 3, 0,
+ ((opt.
+ list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
+ +
+ ((opt.
+ list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
+ 0));
+
+ if (sig->flags.notation
+ && (opt.list_options & LIST_SHOW_X509_NOTATIONS))
+ {
+ struct notation *nots;
+
+ if ((IS_KEY_SIG (sig) || IS_SUBKEY_SIG (sig))
+ && (nots = search_sig_notations (sig,
+ {
+ print_x509_notations (nots);
+ free_notation (nots);
+ }
+ }
if (sig->flags.pref_ks
&& (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
@@ -1599,7 +1642,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
if (opt.with_key_screening)
print_pk_screening (pk2, 0);
}
- else if (opt.list_sigs
+ else if ((opt.list_sigs || (opt.list_options & LIST_SHOW_X509_NOTATIONS))
&& node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
{
kbnode_t n;
diff --git a/g10/options.h b/g10/options.h
index 476c30ad5..e4303a801 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -444,6 +444,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
#define LIST_SHOW_PREF (1<<14)
#define LIST_SHOW_PREF_VERBOSE (1<<15)
#define LIST_SHOW_UNUSABLE_SIGS (1<<16)
+#define LIST_SHOW_X509_NOTATIONS (1<<17)
#define VERIFY_SHOW_PHOTOS (1<<0)
#define VERIFY_SHOW_POLICY_URLS (1<<1)
diff --git a/g10/packet.h b/g10/packet.h
index 76ec78017..a13d3cdc8 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -602,8 +602,8 @@ struct notation
/* Sometimes we want to %-expand the value. In these cases, we save
that transformed value here. */
char *altvalue;
- /* If the notation is not human readable, then the value is stored
- here. */
+ /* If the notation is not human readable or the function does not
+ want to distinguish that, then the value is stored here. */
unsigned char *bdat;
/* The amount of data stored in BDAT.
@@ -877,7 +877,8 @@ struct notation *string_to_notation(const char *string,int is_utf8);
struct notation *blob_to_notation(const char *name,
const char *data, size_t len);
struct notation *sig_to_notation(PKT_signature *sig);
-void free_notation(struct notation *notation);
+struct notation *search_sig_notations (PKT_signature *sig, const char *name);
+void free_notation (struct notation *notation);
/*-- free-packet.c --*/
void free_symkey_enc( PKT_symkey_enc *enc );