diff options
author | Werner Koch <[email protected]> | 2016-09-01 14:00:06 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2016-09-01 14:39:41 +0000 |
commit | 37e3c897252babc203447be9d2f286a4507875ad (patch) | |
tree | 0ad165e090729c083de46cc973115e6ef9a3ea0e /g10/mainproc.c | |
parent | g10: Fix typo. (diff) | |
download | gnupg-37e3c897252babc203447be9d2f286a4507875ad.tar.gz gnupg-37e3c897252babc203447be9d2f286a4507875ad.zip |
gpg: Fix printing of pubkey algo in --verbose signature verify.
* g10/sig-check.c (check_signature2): Replace arg PK by R_PK and
change the semantics. Also clear the other R_ args on function entry,
use gpg_error() and change retturn type to gpg_error_t.
* g10/mainproc.c (do_check_sig): Add arg R_PK.
(list_node): Pass NULL for new arg.
(check_sig_and_print): Rework to make use of the returned PK.
--
The output
gpg: textmode signature, digest algorithm SHA256, key algorithm rsa2048
showed the pubkey algo of the primary key which was surprising.
Changed to print the algo of the subkey used for verification.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to '')
-rw-r--r-- | g10/mainproc.c | 130 |
1 files changed, 73 insertions, 57 deletions
diff --git a/g10/mainproc.c b/g10/mainproc.c index f861a3ea2..716363f4c 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -839,12 +839,13 @@ proc_compressed (CTX c, PACKET *pkt) /* - * check the signature - * Returns: 0 = valid signature or an error code + * Check the signature. If R_PK is not NULL a copy of the public key + * used to verify the signature will be stored tehre, or NULL if not + * found. Returns: 0 = valid signature or an error code */ static int do_check_sig (CTX c, kbnode_t node, int *is_selfsig, - int *is_expkey, int *is_revkey) + int *is_expkey, int *is_revkey, PKT_public_key **r_pk) { PKT_signature *sig; gcry_md_hd_t md = NULL; @@ -852,6 +853,9 @@ do_check_sig (CTX c, kbnode_t node, int *is_selfsig, gcry_md_hd_t md_good = NULL; int algo, rc; + if (r_pk) + *r_pk = NULL; + log_assert (node->pkt->pkttype == PKT_SIGNATURE); if (is_selfsig) *is_selfsig = 0; @@ -926,14 +930,24 @@ do_check_sig (CTX c, kbnode_t node, int *is_selfsig, /* We only get here if we are checking the signature of a binary (0x00) or text document (0x01). */ - rc = check_signature2 (sig, md, NULL, is_expkey, is_revkey, NULL); + rc = check_signature2 (sig, md, NULL, is_expkey, is_revkey, r_pk); if (! rc) md_good = md; else if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2) { - rc = check_signature2 (sig, md2, NULL, is_expkey, is_revkey, NULL); - if (! rc) - md_good = md2; + PKT_public_key *pk2; + + rc = check_signature2 (sig, md2, NULL, is_expkey, is_revkey, + r_pk? &pk2 : NULL); + if (!rc) + { + md_good = md2; + if (r_pk) + { + free_public_key (*r_pk); + *r_pk = pk2; + } + } } if (md_good) @@ -1096,7 +1110,7 @@ list_node (CTX c, kbnode_t node) if (opt.check_sigs) { fflush (stdout); - rc2 = do_check_sig (c, node, &is_selfsig, NULL, NULL); + rc2 = do_check_sig (c, node, &is_selfsig, NULL, NULL, NULL); switch (gpg_err_code (rc2)) { case 0: sigrc = '!'; break; @@ -1603,10 +1617,8 @@ check_sig_and_print (CTX c, kbnode_t node) int rc; int is_expkey = 0; int is_revkey = 0; - char pkstrbuf[PUBKEY_STRING_SIZE]; char *issuer_fpr; - - *pkstrbuf = 0; + PKT_public_key *pk = NULL; /* The public key for the signature or NULL. */ if (opt.skip_verify) { @@ -1754,7 +1766,7 @@ check_sig_and_print (CTX c, kbnode_t node) if (sig->signers_uid) log_info (_(" issuer \"%s\"\n"), sig->signers_uid); - rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); + rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey, &pk); /* If the key isn't found, check for a preferred keyserver. */ if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY && sig->flags.pref_ks) @@ -1783,11 +1795,14 @@ check_sig_and_print (CTX c, kbnode_t node) { int res; + free_public_key (pk); + pk = NULL; glo_ctrl.in_auto_key_retrieve++; res = keyserver_import_keyid (c->ctrl, sig->keyid,spec); glo_ctrl.in_auto_key_retrieve--; if (!res) - rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey ); + rc = do_check_sig (c, node, NULL, + &is_expkey, &is_revkey, &pk); free_keyserver_spec (spec); if (!rc) @@ -1815,12 +1830,14 @@ check_sig_and_print (CTX c, kbnode_t node) spec = parse_keyserver_uri (uri, 1); if (spec) { + free_public_key (pk); + pk = NULL; glo_ctrl.in_auto_key_retrieve++; res = keyserver_import_keyid (c->ctrl, sig->keyid, spec); glo_ctrl.in_auto_key_retrieve--; free_keyserver_spec (spec); if (!res) - rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); + rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey, &pk); } } } @@ -1844,11 +1861,13 @@ check_sig_and_print (CTX c, kbnode_t node) if (p && n == 21 && p[0] == 4) { /* v4 packet with a SHA-1 fingerprint. */ + free_public_key (pk); + pk = NULL; glo_ctrl.in_auto_key_retrieve++; res = keyserver_import_fprint (c->ctrl, p+1, n-1, opt.keyserver); glo_ctrl.in_auto_key_retrieve--; if (!res) - rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); + rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey, &pk); } } @@ -1862,13 +1881,15 @@ check_sig_and_print (CTX c, kbnode_t node) { int res; + free_public_key (pk); + pk = NULL; glo_ctrl.in_auto_key_retrieve++; res = keyserver_import_wkd (c->ctrl, sig->signers_uid, NULL, NULL); glo_ctrl.in_auto_key_retrieve--; /* Fixme: If the fingerprint is embedded in the signature, * compare it to the fingerprint of the returned key. */ if (!res) - rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); + rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey, &pk); } /* If the above methods did't work, our next try is to use a @@ -1879,11 +1900,13 @@ check_sig_and_print (CTX c, kbnode_t node) { int res; + free_public_key (pk); + pk = NULL; glo_ctrl.in_auto_key_retrieve++; res = keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver ); glo_ctrl.in_auto_key_retrieve--; if (!res) - rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); + rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey, &pk); } if (!rc || gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE) @@ -1892,7 +1915,7 @@ check_sig_and_print (CTX c, kbnode_t node) int count = 0; int statno; char keyid_str[50]; - PKT_public_key *pk = NULL; + PKT_public_key *mainpk = NULL; if (rc) statno = STATUS_BADSIG; @@ -1905,6 +1928,10 @@ check_sig_and_print (CTX c, kbnode_t node) else statno = STATUS_GOODSIG; + /* FIXME: We should have the public key in PK and thus the + * keyboock has already been fetched. Thus we could use the + * fingerprint or PK itself to lookup the entire keyblock. That + * would best be done with a cache. */ keyblock = get_pubkeyblock (sig->keyid); snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX [uncertain] ", @@ -1918,7 +1945,7 @@ check_sig_and_print (CTX c, kbnode_t node) if (un->pkt->pkttype==PKT_PUBLIC_KEY) { - pk=un->pkt->pkt.public_key; + mainpk = un->pkt->pkt.public_key; continue; } if (un->pkt->pkttype != PKT_USER_ID) @@ -1935,7 +1962,7 @@ check_sig_and_print (CTX c, kbnode_t node) if (un->pkt->pkt.user_id->attrib_data) continue; - log_assert (pk); + log_assert (mainpk); /* Since this is just informational, don't actually ask the user to update any trust information. (Note: we register @@ -1943,7 +1970,8 @@ check_sig_and_print (CTX c, kbnode_t node) does not print a LF we need to compute the validity before calling that function. */ if ((opt.verify_options & VERIFY_SHOW_UID_VALIDITY)) - valid = get_validity (c->ctrl, pk, un->pkt->pkt.user_id, sig, 0); + valid = get_validity (c->ctrl, mainpk, un->pkt->pkt.user_id, + sig, 0); else valid = 0; /* Not used. */ @@ -1956,13 +1984,11 @@ check_sig_and_print (CTX c, kbnode_t node) else log_printf ("\n"); - /* Get a string description of the algo for informational - output we want to print later. It is convenient to do it - here because we already have the right public key. */ - pubkey_string (pk, pkstrbuf, sizeof pkstrbuf); count++; } + log_assert (mainpk); + /* In case we did not found a valid valid textual userid above we print the first user id packet or a "[?]" instead along with the "Good|Expired|Bad signature" line. */ @@ -2019,13 +2045,13 @@ check_sig_and_print (CTX c, kbnode_t node) /* If this user id has attribute data, print that. */ if (un->pkt->pkt.user_id->attrib_data) { - dump_attribs (un->pkt->pkt.user_id, pk); + dump_attribs (un->pkt->pkt.user_id, mainpk); if (opt.verify_options&VERIFY_SHOW_PHOTOS) show_photos (c->ctrl, un->pkt->pkt.user_id->attribs, un->pkt->pkt.user_id->numattribs, - pk ,un->pkt->pkt.user_id); + mainpk ,un->pkt->pkt.user_id); } p = utf8_to_native (un->pkt->pkt.user_id->name, @@ -2046,7 +2072,7 @@ check_sig_and_print (CTX c, kbnode_t node) actually ask the user to update any trust information. */ valid = (trust_value_to_string - (get_validity (c->ctrl, pk, + (get_validity (c->ctrl, mainpk, un->pkt->pkt.user_id, sig, 0))); log_printf (" [%s]\n",valid); } @@ -2054,7 +2080,6 @@ check_sig_and_print (CTX c, kbnode_t node) log_printf ("\n"); } } - release_kbnode( keyblock ); /* For good signatures print notation data. */ if (!rc) @@ -2081,16 +2106,14 @@ check_sig_and_print (CTX c, kbnode_t node) /* For good signatures print the VALIDSIG status line. */ if (!rc && is_status_enabled ()) { - PKT_public_key *vpk = xmalloc_clear (sizeof *vpk); - - if (!get_pubkey (vpk, sig->keyid)) + if (pk) { byte array[MAX_FINGERPRINT_LEN], *p; char buf[MAX_FINGERPRINT_LEN*4+90], *bufp; size_t i, n; bufp = buf; - fingerprint_from_pk (vpk, array, &n); + fingerprint_from_pk (pk, array, &n); p = array; for(i=0; i < n ; i++, p++, bufp += 2) sprintf (bufp, "%02X", *p ); @@ -2103,29 +2126,13 @@ check_sig_and_print (CTX c, kbnode_t node) sig->version,sig->pubkey_algo,sig->digest_algo, sig->sig_class); bufp = bufp + strlen (bufp); - if (!vpk->flags.primary) - { - u32 akid[2]; - - akid[0] = vpk->main_keyid[0]; - akid[1] = vpk->main_keyid[1]; - free_public_key (vpk); - vpk = xmalloc_clear (sizeof *vpk); - if (get_pubkey (vpk, akid)) - { - /* Impossible error, we simply return a zeroed out fpr */ - n = MAX_FINGERPRINT_LEN < 20? MAX_FINGERPRINT_LEN : 20; - memset (array, 0, n); - } - else - fingerprint_from_pk( vpk, array, &n ); - } + if (!pk->flags.primary) + fingerprint_from_pk (mainpk, array, &n); p = array; for (i=0; i < n ; i++, p++, bufp += 2) sprintf(bufp, "%02X", *p ); write_status_text (STATUS_VALIDSIG, buf); } - free_public_key (vpk); } /* For good signatures compute and print the trust information. @@ -2148,12 +2155,20 @@ check_sig_and_print (CTX c, kbnode_t node) log_info (_("Signature expires %s\n"), asctimestamp(sig->expiredate)); if (opt.verbose) - log_info (_("%s signature, digest algorithm %s%s%s\n"), - sig->sig_class==0x00?_("binary"): - sig->sig_class==0x01?_("textmode"):_("unknown"), - gcry_md_algo_name (sig->digest_algo), - *pkstrbuf?_(", key algorithm "):"", - pkstrbuf); + { + char pkstrbuf[PUBKEY_STRING_SIZE]; + + if (pk) + pubkey_string (pk, pkstrbuf, sizeof pkstrbuf); + else + *pkstrbuf = 0; + + log_info (_("%s signature, digest algorithm %s%s%s\n"), + sig->sig_class==0x00?_("binary"): + sig->sig_class==0x01?_("textmode"):_("unknown"), + gcry_md_algo_name (sig->digest_algo), + *pkstrbuf?_(", key algorithm "):"", pkstrbuf); + } /* Print final warnings. */ if (!rc && !c->signed_data.used) @@ -2194,6 +2209,7 @@ check_sig_and_print (CTX c, kbnode_t node) } } + release_kbnode( keyblock ); if (rc) g10_errors_seen = 1; if (opt.batch && rc) |