mirror of
git://git.gnupg.org/gnupg.git
synced 2025-06-22 21:07:56 +02:00
gpg: Show revocation reason with a standard -k listing.
* g10/packet.h (struct revoke_info): Extend to carry the recocation reason. * g10/getkey.c (sig_to_revoke_info): Extend to strore the reason. (merge_selfsigs): Extend to also store the reason in the public key. * g10/keylist.c (list_signature_print): Factor some code out to ... (print_revocation_reason_comment): new function. (print_revocation_reason): New. (print_key_line): Call new function to print the reason. * g10/import.c (get_revocation_reason): Use print_revocation_reason_comment and factor some code out to ... (revocation_reason_code_to_str): new function. * g10/gpgv.c (revocation_reason_code_to_str): Add stub. * g10/test-stubs.c (revocation_reason_code_to_str): Ditto. -- With this change the revocation reason of a revoked key (but not for a revoked uid or subkey) is now displayed in "gpg -k" listing right below the primary key fingerprint. Before that "gpg --checks-sigs" was required to do show this info. GnuPG-bug-id: 7083
This commit is contained in:
parent
22fc07640a
commit
3f825b044b
@ -161,6 +161,11 @@ release_public_key_parts (PKT_public_key *pk)
|
|||||||
xfree (pk->updateurl);
|
xfree (pk->updateurl);
|
||||||
pk->updateurl = NULL;
|
pk->updateurl = NULL;
|
||||||
}
|
}
|
||||||
|
if (pk->revoked.reason_comment)
|
||||||
|
{
|
||||||
|
xfree (pk->revoked.reason_comment);
|
||||||
|
pk->revoked.reason_comment = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -231,6 +236,10 @@ copy_public_key_basics (PKT_public_key *d, PKT_public_key *s)
|
|||||||
d->seckey_info = NULL;
|
d->seckey_info = NULL;
|
||||||
d->user_id = NULL;
|
d->user_id = NULL;
|
||||||
d->prefs = NULL;
|
d->prefs = NULL;
|
||||||
|
d->revoked.got_reason = 0;
|
||||||
|
d->revoked.reason_code = 0;
|
||||||
|
d->revoked.reason_comment = NULL;
|
||||||
|
d->revoked.reason_comment_len = 0;
|
||||||
|
|
||||||
n = pubkey_get_npkey (s->pubkey_algo);
|
n = pubkey_get_npkey (s->pubkey_algo);
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -274,6 +283,18 @@ copy_public_key (PKT_public_key *d, PKT_public_key *s)
|
|||||||
d->serialno = xstrdup (s->serialno);
|
d->serialno = xstrdup (s->serialno);
|
||||||
if (s->updateurl)
|
if (s->updateurl)
|
||||||
d->updateurl = xstrdup (s->updateurl);
|
d->updateurl = xstrdup (s->updateurl);
|
||||||
|
if (s->revoked.got_reason)
|
||||||
|
{
|
||||||
|
d->revoked.got_reason = s->revoked.got_reason;
|
||||||
|
d->revoked.reason_code = s->revoked.reason_code;
|
||||||
|
if (s->revoked.reason_comment_len)
|
||||||
|
{
|
||||||
|
d->revoked.reason_comment = xmalloc (s->revoked.reason_comment_len);
|
||||||
|
memcpy (d->revoked.reason_comment, s->revoked.reason_comment,
|
||||||
|
s->revoked.reason_comment_len);
|
||||||
|
d->revoked.reason_comment_len = s->revoked.reason_comment_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
47
g10/getkey.c
47
g10/getkey.c
@ -2738,13 +2738,42 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated)
|
|||||||
uid->flags.ks_modify = 0;
|
uid->flags.ks_modify = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Store the revocation signature into the RINFO struct. */
|
||||||
static void
|
static void
|
||||||
sig_to_revoke_info (PKT_signature * sig, struct revoke_info *rinfo)
|
sig_to_revoke_info (PKT_signature * sig, struct revoke_info *rinfo)
|
||||||
{
|
{
|
||||||
|
int reason_seq = 0;
|
||||||
|
size_t reason_n;
|
||||||
|
const byte *reason_p;
|
||||||
|
|
||||||
rinfo->date = sig->timestamp;
|
rinfo->date = sig->timestamp;
|
||||||
rinfo->algo = sig->pubkey_algo;
|
rinfo->algo = sig->pubkey_algo;
|
||||||
rinfo->keyid[0] = sig->keyid[0];
|
rinfo->keyid[0] = sig->keyid[0];
|
||||||
rinfo->keyid[1] = sig->keyid[1];
|
rinfo->keyid[1] = sig->keyid[1];
|
||||||
|
xfree (rinfo->reason_comment);
|
||||||
|
rinfo->reason_comment = NULL;
|
||||||
|
rinfo->reason_comment_len = 0;
|
||||||
|
rinfo->reason_code = 0;
|
||||||
|
rinfo->got_reason = 0;
|
||||||
|
|
||||||
|
while ((reason_p = enum_sig_subpkt (sig, 1, SIGSUBPKT_REVOC_REASON,
|
||||||
|
&reason_n, &reason_seq, NULL))
|
||||||
|
&& !reason_n)
|
||||||
|
; /* Skip over empty reason packets. */
|
||||||
|
|
||||||
|
if (reason_p)
|
||||||
|
{
|
||||||
|
rinfo->got_reason = 1;
|
||||||
|
rinfo->reason_code = *reason_p;
|
||||||
|
reason_n--; reason_p++;
|
||||||
|
if (reason_n)
|
||||||
|
{
|
||||||
|
rinfo->reason_comment = xmalloc (reason_n);
|
||||||
|
memcpy (rinfo->reason_comment, reason_p, reason_n);
|
||||||
|
rinfo->reason_comment_len = reason_n;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3564,7 +3593,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
|
|||||||
{
|
{
|
||||||
KBNODE k;
|
KBNODE k;
|
||||||
int revoked;
|
int revoked;
|
||||||
struct revoke_info rinfo;
|
struct revoke_info rinfo = { 0 };
|
||||||
PKT_public_key *main_pk;
|
PKT_public_key *main_pk;
|
||||||
prefitem_t *prefs;
|
prefitem_t *prefs;
|
||||||
unsigned int mdc_feature;
|
unsigned int mdc_feature;
|
||||||
@ -3611,8 +3640,19 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
|
|||||||
pk->flags.valid = 0;
|
pk->flags.valid = 0;
|
||||||
if (revoked && !pk->flags.revoked)
|
if (revoked && !pk->flags.revoked)
|
||||||
{
|
{
|
||||||
|
/* Copy RINFO reason part only the first time
|
||||||
|
* because we don't want to propagate the reason to
|
||||||
|
* the subkeys. This assumes that we get the public
|
||||||
|
* key first. */
|
||||||
pk->flags.revoked = revoked;
|
pk->flags.revoked = revoked;
|
||||||
memcpy (&pk->revoked, &rinfo, sizeof (rinfo));
|
memcpy (&pk->revoked, &rinfo, sizeof (rinfo));
|
||||||
|
if (rinfo.got_reason)
|
||||||
|
{
|
||||||
|
rinfo.got_reason = 0;
|
||||||
|
rinfo.reason_code = 0;
|
||||||
|
rinfo.reason_comment = NULL; /*(owner is pk->revoked)*/
|
||||||
|
rinfo.reason_comment_len = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (main_pk->has_expired)
|
if (main_pk->has_expired)
|
||||||
{
|
{
|
||||||
@ -3622,7 +3662,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the preference list of all keys to those of the primary real
|
/* Set the preference list of all keys to those of the primary real
|
||||||
@ -3660,6 +3700,9 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
|
|||||||
pk->flags.aead = aead_feature;
|
pk->flags.aead = aead_feature;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave:
|
||||||
|
xfree (rinfo.reason_comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -831,6 +831,14 @@ tofu_notice_key_changed (ctrl_t ctrl, kbnode_t kb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
revocation_reason_code_to_str (int code, char **freeme)
|
||||||
|
{
|
||||||
|
(void)code;
|
||||||
|
*freeme = NULL;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
get_revocation_reason (PKT_signature *sig, char **r_reason,
|
get_revocation_reason (PKT_signature *sig, char **r_reason,
|
||||||
char **r_comment, size_t *r_commentlen)
|
char **r_comment, size_t *r_commentlen)
|
||||||
|
77
g10/import.c
77
g10/import.c
@ -3366,6 +3366,33 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return a string for the revocation reason CODE. R_FREEM must be an
|
||||||
|
* possibly unintialized ptr which should be freed by the caller after
|
||||||
|
* the return value has been consumed. */
|
||||||
|
const char *
|
||||||
|
revocation_reason_code_to_str (int code, char **freeme)
|
||||||
|
{
|
||||||
|
/* Take care: get_revocation_reason has knowledge of the internal
|
||||||
|
* working of this fucntion. */
|
||||||
|
const char *result;
|
||||||
|
|
||||||
|
*freeme = NULL;
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case 0x00: result = _("No reason specified"); break;
|
||||||
|
case 0x01: result = _("Key is superseded"); break;
|
||||||
|
case 0x02: result = _("Key has been compromised"); break;
|
||||||
|
case 0x03: result = _("Key is no longer used"); break;
|
||||||
|
case 0x20: result = _("User ID is no longer valid"); break;
|
||||||
|
default:
|
||||||
|
*freeme = xasprintf ("code=%02x", code);
|
||||||
|
result = *freeme;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return the recocation reason from signature SIG. If no revocation
|
/* Return the recocation reason from signature SIG. If no revocation
|
||||||
* reason is available 0 is returned, in other cases the reason
|
* reason is available 0 is returned, in other cases the reason
|
||||||
@ -3383,9 +3410,8 @@ get_revocation_reason (PKT_signature *sig, char **r_reason,
|
|||||||
int reason_seq = 0;
|
int reason_seq = 0;
|
||||||
size_t reason_n;
|
size_t reason_n;
|
||||||
const byte *reason_p;
|
const byte *reason_p;
|
||||||
char reason_code_buf[20];
|
|
||||||
const char *reason_text = NULL;
|
|
||||||
int reason_code = 0;
|
int reason_code = 0;
|
||||||
|
char *freeme;
|
||||||
|
|
||||||
if (r_reason)
|
if (r_reason)
|
||||||
*r_reason = NULL;
|
*r_reason = NULL;
|
||||||
@ -3397,26 +3423,15 @@ get_revocation_reason (PKT_signature *sig, char **r_reason,
|
|||||||
&reason_n, &reason_seq, NULL))
|
&reason_n, &reason_seq, NULL))
|
||||||
&& !reason_n)
|
&& !reason_n)
|
||||||
;
|
;
|
||||||
if (reason_p)
|
if (reason_p && reason_n)
|
||||||
{
|
{
|
||||||
reason_code = *reason_p;
|
reason_code = *reason_p;
|
||||||
reason_n--; reason_p++;
|
reason_n--; reason_p++;
|
||||||
switch (reason_code)
|
revocation_reason_code_to_str (reason_code, &freeme);
|
||||||
{
|
|
||||||
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)
|
if (r_reason)
|
||||||
*r_reason = xstrdup (reason_text);
|
*r_reason = freeme;
|
||||||
|
else
|
||||||
|
xfree (freeme);
|
||||||
|
|
||||||
if (r_comment && reason_n)
|
if (r_comment && reason_n)
|
||||||
{
|
{
|
||||||
@ -3533,31 +3548,7 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc)
|
|||||||
{
|
{
|
||||||
es_fprintf (es_stdout, " %s%s\n",
|
es_fprintf (es_stdout, " %s%s\n",
|
||||||
_("reason for revocation: "), reason_text);
|
_("reason for revocation: "), reason_text);
|
||||||
if (reason_comment)
|
print_revocation_reason_comment (reason_comment, reason_commentlen);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1324,6 +1324,58 @@ parse_trust_name (const char *name, size_t namelen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
print_revocation_reason_comment (const char *comment, size_t comment_len)
|
||||||
|
{
|
||||||
|
const byte *s, *s_lf;
|
||||||
|
size_t n, n_lf;
|
||||||
|
|
||||||
|
if (!comment || !comment_len)
|
||||||
|
return;
|
||||||
|
|
||||||
|
s = comment;
|
||||||
|
n = comment_len;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_revocation_reason (PKT_public_key *pk)
|
||||||
|
{
|
||||||
|
char *freeme;
|
||||||
|
const char *codestr;
|
||||||
|
|
||||||
|
if (!pk->revoked.got_reason)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pk->revoked.reason_code && !pk->revoked.reason_comment)
|
||||||
|
return; /* Do not print "revocation reason: No reason specified". */
|
||||||
|
|
||||||
|
codestr = revocation_reason_code_to_str (pk->revoked.reason_code, &freeme);
|
||||||
|
es_fprintf (es_stdout, " %s%s\n",
|
||||||
|
_("reason for revocation: "), codestr);
|
||||||
|
xfree (freeme);
|
||||||
|
print_revocation_reason_comment (pk->revoked.reason_comment,
|
||||||
|
pk->revoked.reason_comment_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Helper for list_keyblock_print. The caller must have set
|
/* Helper for list_keyblock_print. The caller must have set
|
||||||
* NODFLG_MARK_B to indicate self-signatures. */
|
* NODFLG_MARK_B to indicate self-signatures. */
|
||||||
static void
|
static void
|
||||||
@ -1502,31 +1554,7 @@ list_signature_print (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node,
|
|||||||
{
|
{
|
||||||
es_fprintf (es_stdout, " %s%s\n",
|
es_fprintf (es_stdout, " %s%s\n",
|
||||||
_("reason for revocation: "), reason_text);
|
_("reason for revocation: "), reason_text);
|
||||||
if (reason_comment)
|
print_revocation_reason_comment (reason_comment, reason_commentlen);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree (reason_text);
|
xfree (reason_text);
|
||||||
@ -2763,6 +2791,10 @@ print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret)
|
|||||||
if (pk->flags.primary &&
|
if (pk->flags.primary &&
|
||||||
!opt.fingerprint && !opt.with_fingerprint)
|
!opt.fingerprint && !opt.with_fingerprint)
|
||||||
print_fingerprint (ctrl, fp, pk, 20);
|
print_fingerprint (ctrl, fp, pk, 20);
|
||||||
|
|
||||||
|
/* Print the revocation reason. */
|
||||||
|
if (pk->flags.revoked)
|
||||||
|
print_revocation_reason (pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -407,6 +407,7 @@ gpg_error_t transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats,
|
|||||||
int collapse_uids (kbnode_t *keyblock);
|
int collapse_uids (kbnode_t *keyblock);
|
||||||
int collapse_subkeys (kbnode_t *keyblock);
|
int collapse_subkeys (kbnode_t *keyblock);
|
||||||
|
|
||||||
|
const char *revocation_reason_code_to_str (int code, char **r_freeme);
|
||||||
int get_revocation_reason (PKT_signature *sig, char **r_reason,
|
int get_revocation_reason (PKT_signature *sig, char **r_reason,
|
||||||
char **r_comment, size_t *r_commentlen);
|
char **r_comment, size_t *r_commentlen);
|
||||||
|
|
||||||
@ -495,6 +496,7 @@ void print_key_info_log (ctrl_t ctrl, int loglevel, int indent,
|
|||||||
PKT_public_key *pk, int secret);
|
PKT_public_key *pk, int secret);
|
||||||
void print_card_key_info (estream_t fp, KBNODE keyblock);
|
void print_card_key_info (estream_t fp, KBNODE keyblock);
|
||||||
void print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret);
|
void print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret);
|
||||||
|
void print_revocation_reason_comment (const char *comment, size_t comment_len);
|
||||||
|
|
||||||
/*-- verify.c --*/
|
/*-- verify.c --*/
|
||||||
void print_file_status( int status, const char *name, int what );
|
void print_file_status( int status, const char *name, int what );
|
||||||
|
14
g10/packet.h
14
g10/packet.h
@ -339,12 +339,20 @@ typedef struct
|
|||||||
|
|
||||||
struct revoke_info
|
struct revoke_info
|
||||||
{
|
{
|
||||||
/* revoked at this date */
|
/* Revoked at this date */
|
||||||
u32 date;
|
u32 date;
|
||||||
/* the keyid of the revoking key (selfsig or designated revoker) */
|
/* The keyid of the revoking key (selfsig or designated revoker) */
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
/* the algo of the revoking key */
|
/* A malloced string of len reason_comment_len with the raw reason
|
||||||
|
* string or NULL if not given. */
|
||||||
|
char *reason_comment;
|
||||||
|
size_t reason_comment_len;
|
||||||
|
/* The algo of the revoking key */
|
||||||
byte algo;
|
byte algo;
|
||||||
|
/* The reason code. */
|
||||||
|
byte reason_code;
|
||||||
|
/* Whether the above reason fields are valid. */
|
||||||
|
byte got_reason;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -571,6 +571,15 @@ tofu_notice_key_changed (ctrl_t ctrl, kbnode_t kb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
revocation_reason_code_to_str (int code, char **freeme)
|
||||||
|
{
|
||||||
|
(void)code;
|
||||||
|
*freeme = NULL;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
get_revocation_reason (PKT_signature *sig, char **r_reason,
|
get_revocation_reason (PKT_signature *sig, char **r_reason,
|
||||||
char **r_comment, size_t *r_commentlen)
|
char **r_comment, size_t *r_commentlen)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user