diff options
Diffstat (limited to 'g10/parse-packet.c')
-rw-r--r-- | g10/parse-packet.c | 122 |
1 files changed, 78 insertions, 44 deletions
diff --git a/g10/parse-packet.c b/g10/parse-packet.c index ab82d475a..874ff76b0 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -270,7 +270,7 @@ unknown_pubkey_warning (int algo) encryption/signing. */ if (pubkey_get_npkey (algo)) { - if (opt.verbose) + if (opt.verbose && !glo_ctrl.silence_parse_warnings) { if (!pubkey_get_nsig (algo)) log_info ("public key algorithm %s not suitable for %s\n", @@ -285,7 +285,7 @@ unknown_pubkey_warning (int algo) algo &= 0xff; if (!unknown_pubkey_algos[algo]) { - if (opt.verbose) + if (opt.verbose && !glo_ctrl.silence_parse_warnings) log_info (_("can't handle public key algorithm %d\n"), algo); unknown_pubkey_algos[algo] = 1; } @@ -1360,17 +1360,20 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, /* Dump a subpacket to LISTFP. BUFFER contains the subpacket in - question and points to the type field in the subpacket header (not - the start of the header). TYPE is the subpacket's type with the - critical bit cleared. CRITICAL is the value of the CRITICAL bit. - BUFLEN is the length of the buffer and LENGTH is the length of the - subpacket according to the subpacket's header. */ + * question and points to the type field in the subpacket header (not + * the start of the header). TYPE is the subpacket's type with the + * critical bit cleared. CRITICAL is the value of the CRITICAL bit. + * BUFLEN is the length of the buffer and LENGTH is the length of the + * subpacket according to the subpacket's header. DIGEST_ALGO is the + * digest algo of the signature. */ static void dump_sig_subpkt (int hashed, int type, int critical, - const byte * buffer, size_t buflen, size_t length) + const byte * buffer, size_t buflen, size_t length, + int digest_algo) { const char *p = NULL; int i; + int nprinted; /* The CERT has warning out with explains how to use GNUPG to detect * the ARRs - we print our old message here when it is a faked ARR @@ -1388,9 +1391,11 @@ dump_sig_subpkt (int hashed, int type, int critical, buffer++; length--; - es_fprintf (listfp, "\t%s%ssubpkt %d len %u (", /*) */ - critical ? "critical " : "", - hashed ? "hashed " : "", type, (unsigned) length); + nprinted = es_fprintf (listfp, "\t%s%ssubpkt %d len %u (", /*) */ + critical ? "critical " : "", + hashed ? "hashed " : "", type, (unsigned) length); + if (nprinted < 1) + nprinted = 1; /*(we use (nprinted-1) later.)*/ if (length > buflen) { es_fprintf (listfp, "too short: buffer is only %u)\n", (unsigned) buflen); @@ -1585,6 +1590,32 @@ dump_sig_subpkt (int hashed, int type, int critical, buffer[0] == 3 ? buffer[15] : buffer[2], buffer[0] == 3 ? buffer[16] : buffer[3]); break; + + case SIGSUBPKT_ATTST_SIGS: + { + unsigned int hlen; + + es_fputs ("attst-sigs: ", listfp); + hlen = gcry_md_get_algo_dlen (map_md_openpgp_to_gcry (digest_algo)); + if (!hlen) + p = "[unknown digest algo]"; + else if ((length % hlen)) + p = "[invalid length]"; + else + { + es_fprintf (listfp, "%d", length/hlen); + while (length) + { + es_fprintf (listfp, "\n\t%*s", nprinted-1, ""); + es_write_hexstring (listfp, buffer, hlen, 0, NULL); + buffer += hlen; + length -= hlen; + } + } + } + break; + + default: if (type >= 100 && type <= 110) p = "experimental / private subpacket"; @@ -1627,6 +1658,7 @@ parse_one_sig_subpkt (const byte * buffer, size_t n, int type) case SIGSUBPKT_PREF_KS: case SIGSUBPKT_FEATURES: case SIGSUBPKT_REGEXP: + case SIGSUBPKT_ATTST_SIGS: return 0; case SIGSUBPKT_SIGNATURE: case SIGSUBPKT_EXPORTABLE: @@ -1679,7 +1711,7 @@ can_handle_critical_notation (const byte *name, size_t len) if (sl->flags == len && !memcmp (sl->d, name, len)) return 1; /* Known */ - if (opt.verbose) + if (opt.verbose && !glo_ctrl.silence_parse_warnings) { log_info(_("Unknown critical signature notation: ") ); print_utf8_buffer (log_get_stream(), name, len); @@ -1721,6 +1753,7 @@ can_handle_critical (const byte * buffer, size_t n, int type) case SIGSUBPKT_FEATURES: case SIGSUBPKT_TRUST: case SIGSUBPKT_REGEXP: + case SIGSUBPKT_ATTST_SIGS: /* Is it enough to show the policy or keyserver? */ case SIGSUBPKT_POLICY: case SIGSUBPKT_PREF_KS: @@ -1734,8 +1767,8 @@ can_handle_critical (const byte * buffer, size_t n, int type) const byte * -enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype, - size_t * ret_n, int *start, int *critical) +enum_sig_subpkt (PKT_signature *sig, int want_hashed, sigsubpkttype_t reqtype, + size_t *ret_n, int *start, int *critical) { const byte *buffer; int buflen; @@ -1743,6 +1776,7 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype, int critical_dummy; int offset; size_t n; + const subpktarea_t *pktbuf = want_hashed? sig->hashed : sig->unhashed; int seq = 0; int reqseq = start ? *start : 0; @@ -1800,7 +1834,7 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype, goto too_short; if (!can_handle_critical (buffer + 1, n - 1, type)) { - if (opt.verbose) + if (opt.verbose && !glo_ctrl.silence_parse_warnings) log_info (_("subpacket of type %d has " "critical bit set\n"), type); if (start) @@ -1811,7 +1845,7 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype, } else if (reqtype < 0) /* List packets. */ dump_sig_subpkt (reqtype == SIGSUBPKT_LIST_HASHED, - type, *critical, buffer, buflen, n); + type, *critical, buffer, buflen, n, sig->digest_algo); else if (type == reqtype) /* Found. */ { buffer++; @@ -1851,14 +1885,14 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype, return NULL; /* End of packets; not found. */ too_short: - if (opt.verbose) + if (opt.verbose && !glo_ctrl.silence_parse_warnings) log_info ("buffer shorter than subpacket\n"); if (start) *start = -1; return NULL; no_type_byte: - if (opt.verbose) + if (opt.verbose && !glo_ctrl.silence_parse_warnings) log_info ("type octet missing in subpacket\n"); if (start) *start = -1; @@ -1867,21 +1901,21 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype, const byte * -parse_sig_subpkt (const subpktarea_t * buffer, sigsubpkttype_t reqtype, - size_t * ret_n) +parse_sig_subpkt (PKT_signature *sig, int want_hashed, sigsubpkttype_t reqtype, + size_t *ret_n) { - return enum_sig_subpkt (buffer, reqtype, ret_n, NULL, NULL); + return enum_sig_subpkt (sig, want_hashed, reqtype, ret_n, NULL, NULL); } const byte * -parse_sig_subpkt2 (PKT_signature * sig, sigsubpkttype_t reqtype) +parse_sig_subpkt2 (PKT_signature *sig, sigsubpkttype_t reqtype) { const byte *p; - p = parse_sig_subpkt (sig->hashed, reqtype, NULL); + p = parse_sig_subpkt (sig, 1, reqtype, NULL); if (!p) - p = parse_sig_subpkt (sig->unhashed, reqtype, NULL); + p = parse_sig_subpkt (sig, 0, reqtype, NULL); return p; } @@ -1897,8 +1931,8 @@ parse_revkeys (PKT_signature * sig) if (sig->sig_class != 0x1F) return; - while ((revkey = enum_sig_subpkt (sig->hashed, SIGSUBPKT_REV_KEY, - &len, &seq, NULL))) + while ((revkey = enum_sig_subpkt (sig, 1, SIGSUBPKT_REV_KEY, + &len, &seq, NULL))) { /* Consider only valid packets. They must have a length of * either 2+20 or 2+32 octets and bit 7 of the class octet must @@ -2062,21 +2096,21 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, /* Set sig->flags.unknown_critical if there is a critical bit * set for packets which we do not understand. */ - if (!parse_sig_subpkt (sig->hashed, SIGSUBPKT_TEST_CRITICAL, NULL) - || !parse_sig_subpkt (sig->unhashed, SIGSUBPKT_TEST_CRITICAL, NULL)) + if (!parse_sig_subpkt (sig, 1, SIGSUBPKT_TEST_CRITICAL, NULL) + || !parse_sig_subpkt (sig, 0, SIGSUBPKT_TEST_CRITICAL, NULL)) sig->flags.unknown_critical = 1; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL); + p = parse_sig_subpkt (sig, 1, SIGSUBPKT_SIG_CREATED, NULL); if (p) sig->timestamp = buf32_to_u32 (p); else if (!(sig->pubkey_algo >= 100 && sig->pubkey_algo <= 110) - && opt.verbose) + && opt.verbose && !glo_ctrl.silence_parse_warnings) log_info ("signature packet without timestamp\n"); /* Set the key id. We first try the issuer fingerprint and if * it is a v4 signature the fallback to the issuer. Note that * only the issuer packet is also searched in the unhashed area. */ - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_ISSUER_FPR, &len); + p = parse_sig_subpkt (sig, 1, SIGSUBPKT_ISSUER_FPR, &len); if (p && len == 21 && p[0] == 4) { sig->keyid[0] = buf32_to_u32 (p + 1 + 12); @@ -2093,24 +2127,24 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, sig->keyid[1] = buf32_to_u32 (p + 4); } else if (!(sig->pubkey_algo >= 100 && sig->pubkey_algo <= 110) - && opt.verbose) + && opt.verbose && !glo_ctrl.silence_parse_warnings) log_info ("signature packet without keyid\n"); - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL); + p = parse_sig_subpkt (sig, 1, SIGSUBPKT_SIG_EXPIRE, NULL); if (p && buf32_to_u32 (p)) sig->expiredate = sig->timestamp + buf32_to_u32 (p); if (sig->expiredate && sig->expiredate <= make_timestamp ()) sig->flags.expired = 1; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_POLICY, NULL); + p = parse_sig_subpkt (sig, 1, SIGSUBPKT_POLICY, NULL); if (p) sig->flags.policy_url = 1; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, NULL); + p = parse_sig_subpkt (sig, 1, SIGSUBPKT_PREF_KS, NULL); if (p) sig->flags.pref_ks = 1; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIGNERS_UID, &len); + p = parse_sig_subpkt (sig, 1, SIGSUBPKT_SIGNERS_UID, &len); if (p && len) { char *mbox; @@ -2129,15 +2163,15 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, } } - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_NOTATION, NULL); + p = parse_sig_subpkt (sig, 1, SIGSUBPKT_NOTATION, NULL); if (p) sig->flags.notation = 1; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_REVOCABLE, NULL); + p = parse_sig_subpkt (sig, 1, SIGSUBPKT_REVOCABLE, NULL); if (p && *p == 0) sig->flags.revocable = 0; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_TRUST, &len); + p = parse_sig_subpkt (sig, 1, SIGSUBPKT_TRUST, &len); if (p && len == 2) { sig->trust_depth = p[0]; @@ -2146,7 +2180,7 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, /* Only look for a regexp if there is also a trust subpacket. */ sig->trust_regexp = - parse_sig_subpkt (sig->hashed, SIGSUBPKT_REGEXP, &len); + parse_sig_subpkt (sig, 1, SIGSUBPKT_REGEXP, &len); /* If the regular expression is of 0 length, there is no regular expression. */ @@ -2179,8 +2213,8 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, sig->digest_algo, sig->digest_start[0], sig->digest_start[1]); if (is_v4or5) { - parse_sig_subpkt (sig->hashed, SIGSUBPKT_LIST_HASHED, NULL); - parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL); + parse_sig_subpkt (sig, 1, SIGSUBPKT_LIST_HASHED, NULL); + parse_sig_subpkt (sig, 0, SIGSUBPKT_LIST_UNHASHED, NULL); } } @@ -2344,7 +2378,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, { /* Not anymore supported since 2.1. Use an older gpg version * (i.e. gpg 1.4) to parse v3 packets. */ - if (opt.verbose > 1) + if (opt.verbose > 1 && !glo_ctrl.silence_parse_warnings) log_info ("packet(%d) with obsolete version %d\n", pkttype, version); if (list_mode) es_fprintf (listfp, ":key packet: [obsolete version %d]\n", version); @@ -2866,7 +2900,7 @@ parse_attribute_subpkts (PKT_user_id * uid) return count; too_short: - if (opt.verbose) + if (opt.verbose && !glo_ctrl.silence_parse_warnings) log_info ("buffer shorter than attribute subpacket\n"); uid->attribs = attribs; uid->numattribs = count; |