aboutsummaryrefslogtreecommitdiffstats
path: root/g10/import.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2018-06-21 16:32:13 +0000
committerWerner Koch <[email protected]>2018-07-03 09:56:04 +0000
commita8e24addcc4e0fdff7d07acdd7e13bf6febf97d2 (patch)
treecf7df3797329367cf25dc8c7cee75f9b6a7f05a9 /g10/import.c
parentgpg: Let --show-keys print revocation certificates. (diff)
downloadgnupg-a8e24addcc4e0fdff7d07acdd7e13bf6febf97d2.tar.gz
gnupg-a8e24addcc4e0fdff7d07acdd7e13bf6febf97d2.zip
gpg: Print revocation reason for "rvs" records.
* g10/import.c (get_revocation_reason): New. (list_standalone_revocation): Extend function. -- Note that this function extends the "rvs" field signature-class (field 11) with the revocation reason. GPGME does not yet parse this but it can be expected that the comma delimiter does not break other parsers. A new field is added to the "rvs" (and in future also the "rev") record to carry a record specific comment. Hopefully all parsers meanwhile learned the lesson from other new fields and don't bail out on more fields than they know about. This is partial solution to GnuPG-bug-id: 1173 Signed-off-by: Werner Koch <[email protected]> (cherry picked from commit b7cd2c2093ae1b47645be50fa1d431a028187cad)
Diffstat (limited to '')
-rw-r--r--g10/import.c119
1 files changed, 117 insertions, 2 deletions
diff --git a/g10/import.c b/g10/import.c
index 0f2ccfddf..49381d4cb 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -2614,6 +2614,69 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock,
+/* Return the recocation reason from signature SIG. If no revocation
+ * reason is availabale 0 is returned, in other cases the reason
+ * (0..255). If R_REASON is not NULL a malloced textual
+ * representation of the code is stored there. If R_COMMENT is not
+ * NULL the comment from the reason is stored there and its length at
+ * R_COMMENTLEN. Note that the value at R_COMMENT is not filtered but
+ * user supplied data in UTF8; thus it needs to be escaped for display
+ * purposes. Both return values are either NULL or a malloced
+ * string/buffer. */
+int
+get_revocation_reason (PKT_signature *sig, char **r_reason,
+ char **r_comment, size_t *r_commentlen)
+{
+ int reason_seq = 0;
+ size_t reason_n;
+ const byte *reason_p;
+ char reason_code_buf[20];
+ const char *reason_text = NULL;
+ int reason_code = 0;
+
+ if (r_reason)
+ *r_reason = NULL;
+ if (r_comment)
+ *r_comment = NULL;
+
+ /* Skip over empty reason packets. */
+ while ((reason_p = enum_sig_subpkt (sig->hashed, SIGSUBPKT_REVOC_REASON,
+ &reason_n, &reason_seq, NULL))
+ && !reason_n)
+ ;
+ if (reason_p)
+ {
+ reason_code = *reason_p;
+ reason_n--; reason_p++;
+ switch (reason_code)
+ {
+ case 0x00: reason_text = _("No reason specified"); break;
+ case 0x01: reason_text = _("Key is superseded"); break;
+ case 0x02: reason_text = _("Key has been compromised"); break;
+ case 0x03: reason_text = _("Key is no longer used"); break;
+ case 0x20: reason_text = _("User ID is no longer valid"); break;
+ default:
+ snprintf (reason_code_buf, sizeof reason_code_buf,
+ "code=%02x", reason_code);
+ reason_text = reason_code_buf;
+ break;
+ }
+
+ if (r_reason)
+ *r_reason = xstrdup (reason_text);
+
+ if (r_comment && reason_n)
+ {
+ *r_comment = xmalloc (reason_n);
+ memcpy (*r_comment, reason_p, reason_n);
+ *r_commentlen = reason_n;
+ }
+ }
+
+ return reason_code;
+}
+
+
/* List the recocation signature as a "rvs" record. SIGRC shows the
* character from the signature verification or 0 if no public key was
* found. */
@@ -2623,6 +2686,10 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc)
char *siguid = NULL;
size_t siguidlen = 0;
char *issuer_fpr = NULL;
+ int reason_code = 0;
+ char *reason_text = NULL;
+ char *reason_comment = NULL;
+ size_t reason_commentlen;
if (sigrc != '%' && sigrc != '?' && !opt.fast_list_mode)
{
@@ -2632,6 +2699,9 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc)
sigrc = '?';
}
+ reason_code = get_revocation_reason (sig, &reason_text,
+ &reason_comment, &reason_commentlen);
+
if (opt.with_colons)
{
es_fputs ("rvs:", es_stdout);
@@ -2646,13 +2716,25 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc)
if (siguid)
es_write_sanitized (es_stdout, siguid, siguidlen, ":", NULL);
- es_fprintf (es_stdout, ":%02x%c::", sig->sig_class,
+ es_fprintf (es_stdout, ":%02x%c", sig->sig_class,
sig->flags.exportable ? 'x' : 'l');
+ if (reason_text)
+ es_fprintf (es_stdout, ",%02x", reason_code);
+ es_fputs ("::", es_stdout);
if ((issuer_fpr = issuer_fpr_string (sig)))
es_fputs (issuer_fpr, es_stdout);
- es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo);
+ es_fprintf (es_stdout, ":::%d:", sig->digest_algo);
+
+ if (reason_comment)
+ {
+ es_fputs ("::::", es_stdout);
+ es_write_sanitized (es_stdout, reason_comment, reason_commentlen,
+ ":", NULL);
+ es_putc (':', es_stdout);
+ }
+ es_putc ('\n', es_stdout);
if (opt.show_subpackets)
print_subpackets_colon (sig);
@@ -2693,10 +2775,43 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc)
if (sig->flags.pref_ks
&& (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
show_keyserver_url (sig, 3, 0);
+
+ if (reason_text)
+ {
+ es_fprintf (es_stdout, " %s%s\n",
+ _("reason for revocation: "), reason_text);
+ if (reason_comment)
+ {
+ const byte *s, *s_lf;
+ size_t n, n_lf;
+
+ s = reason_comment;
+ n = reason_commentlen;
+ s_lf = NULL;
+ do
+ {
+ /* We don't want any empty lines, so we skip them. */
+ for (;n && *s == '\n'; s++, n--)
+ ;
+ if (n)
+ {
+ s_lf = memchr (s, '\n', n);
+ n_lf = s_lf? s_lf - s : n;
+ es_fprintf (es_stdout, " %s",
+ _("revocation comment: "));
+ es_write_sanitized (es_stdout, s, n_lf, NULL, NULL);
+ es_putc ('\n', es_stdout);
+ s += n_lf; n -= n_lf;
+ }
+ } while (s_lf);
+ }
+ }
}
es_fflush (es_stdout);
+ xfree (reason_text);
+ xfree (reason_comment);
xfree (siguid);
xfree (issuer_fpr);
}