mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
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 <wk@gnupg.org> (cherry picked from commit b7cd2c2093ae1b47645be50fa1d431a028187cad)
This commit is contained in:
parent
5c67ee160d
commit
a8e24addcc
@ -180,6 +180,9 @@ described here.
|
|||||||
revocation key is also given here, 'x' and 'l' is used the same
|
revocation key is also given here, 'x' and 'l' is used the same
|
||||||
way. This field if not used for X.509.
|
way. This field if not used for X.509.
|
||||||
|
|
||||||
|
"rev" and "rvs" may be followed by a comma and a 2 digit hexnumber
|
||||||
|
with the revocation reason.
|
||||||
|
|
||||||
*** Field 12 - Key capabilities
|
*** Field 12 - Key capabilities
|
||||||
|
|
||||||
The defined capabilities are:
|
The defined capabilities are:
|
||||||
@ -260,6 +263,12 @@ described here.
|
|||||||
optionally followed by a space and an URL. This goes along with
|
optionally followed by a space and an URL. This goes along with
|
||||||
the previous field. The URL is quoted in C style.
|
the previous field. The URL is quoted in C style.
|
||||||
|
|
||||||
|
*** Field 21 - Comment
|
||||||
|
|
||||||
|
This is currently only used in "rev" and "rvs" records to carry
|
||||||
|
the the comment field of the recocation reason. The value is
|
||||||
|
quoted in C style.
|
||||||
|
|
||||||
** Special fields
|
** Special fields
|
||||||
|
|
||||||
*** PKD - Public key data
|
*** PKD - Public key data
|
||||||
|
119
g10/import.c
119
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
|
/* List the recocation signature as a "rvs" record. SIGRC shows the
|
||||||
* character from the signature verification or 0 if no public key was
|
* character from the signature verification or 0 if no public key was
|
||||||
* found. */
|
* found. */
|
||||||
@ -2623,6 +2686,10 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc)
|
|||||||
char *siguid = NULL;
|
char *siguid = NULL;
|
||||||
size_t siguidlen = 0;
|
size_t siguidlen = 0;
|
||||||
char *issuer_fpr = NULL;
|
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)
|
if (sigrc != '%' && sigrc != '?' && !opt.fast_list_mode)
|
||||||
{
|
{
|
||||||
@ -2632,6 +2699,9 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc)
|
|||||||
sigrc = '?';
|
sigrc = '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reason_code = get_revocation_reason (sig, &reason_text,
|
||||||
|
&reason_comment, &reason_commentlen);
|
||||||
|
|
||||||
if (opt.with_colons)
|
if (opt.with_colons)
|
||||||
{
|
{
|
||||||
es_fputs ("rvs:", es_stdout);
|
es_fputs ("rvs:", es_stdout);
|
||||||
@ -2646,13 +2716,25 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc)
|
|||||||
if (siguid)
|
if (siguid)
|
||||||
es_write_sanitized (es_stdout, siguid, siguidlen, ":", NULL);
|
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');
|
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)))
|
if ((issuer_fpr = issuer_fpr_string (sig)))
|
||||||
es_fputs (issuer_fpr, es_stdout);
|
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)
|
if (opt.show_subpackets)
|
||||||
print_subpackets_colon (sig);
|
print_subpackets_colon (sig);
|
||||||
@ -2693,10 +2775,43 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc)
|
|||||||
if (sig->flags.pref_ks
|
if (sig->flags.pref_ks
|
||||||
&& (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
|
&& (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
|
||||||
show_keyserver_url (sig, 3, 0);
|
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);
|
es_fflush (es_stdout);
|
||||||
|
|
||||||
|
xfree (reason_text);
|
||||||
|
xfree (reason_comment);
|
||||||
xfree (siguid);
|
xfree (siguid);
|
||||||
xfree (issuer_fpr);
|
xfree (issuer_fpr);
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ void
|
|||||||
show_revocation_reason (ctrl_t ctrl, PKT_public_key *pk, int mode)
|
show_revocation_reason (ctrl_t ctrl, PKT_public_key *pk, int mode)
|
||||||
{
|
{
|
||||||
/* Hmmm, this is not so easy because we have to duplicate the code
|
/* Hmmm, this is not so easy because we have to duplicate the code
|
||||||
* used in the trustbd to calculate the keyflags. We need to find
|
* used in the trustdb to calculate the keyflags. We need to find
|
||||||
* a clean way to check revocation certificates on keys and
|
* a clean way to check revocation certificates on keys and
|
||||||
* signatures. And there should be no duplicate code. Because we
|
* signatures. And there should be no duplicate code. Because we
|
||||||
* enter this function only when the trustdb told us that we have
|
* enter this function only when the trustdb told us that we have
|
||||||
|
Loading…
x
Reference in New Issue
Block a user