diff options
Diffstat (limited to 'g10/parse-packet.c')
-rw-r--r-- | g10/parse-packet.c | 82 |
1 files changed, 63 insertions, 19 deletions
diff --git a/g10/parse-packet.c b/g10/parse-packet.c index e933abfa0..c0f2ca12e 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -43,11 +43,15 @@ #define MAX_COMMENT_PACKET_LENGTH ( 64 * 1024) #define MAX_ATTR_PACKET_LENGTH ( 16 * 1024*1024) - static int mpi_print_mode; static int list_mode; static estream_t listfp; +/* A linked list of known notation names. Note that the FLAG is used + * to store the length of the name to speed up the check. */ +static strlist_t known_notations_list; + + static int parse (parse_packet_ctx_t ctx, PACKET *pkt, int onlykeypkts, off_t * retpos, int *skip, IOBUF out, int do_skip #if DEBUG_PARSE_PACKET @@ -189,6 +193,36 @@ mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure) } +/* Register STRING as a known critical notation name. */ +void +register_known_notation (const char *string) +{ + strlist_t sl; + + if (!known_notations_list) + { + sl = add_to_strlist (&known_notations_list, + "[email protected]"); + sl->flags = 32; + sl = add_to_strlist (&known_notations_list, "[email protected]"); + sl->flags = 21; + } + if (!string) + return; /* Only initialized the default known notations. */ + + /* In --set-notation we use an exclamation mark to indicate a + * critical notation. As a convenience skip this here. */ + if (*string == '!') + string++; + + if (!*string || strlist_find (known_notations_list, string)) + return; /* Empty string or already registered. */ + + sl = add_to_strlist (&known_notations_list, string); + sl->flags = strlen (string); +} + + int set_packet_list_mode (int mode) { @@ -1186,7 +1220,7 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, } if (s2kmode == 3) { - k->s2k.count = iobuf_get (inp); + k->s2k.count = iobuf_get_noeof (inp); pktlen--; } k->seskeylen = seskeylen; @@ -1640,14 +1674,24 @@ parse_one_sig_subpkt (const byte * buffer, size_t n, int type) /* Return true if we understand the critical notation. */ static int -can_handle_critical_notation (const byte * name, size_t len) +can_handle_critical_notation (const byte *name, size_t len) { - if (len == 32 && memcmp (name, "[email protected]", 32) == 0) - return 1; - if (len == 21 && memcmp (name, "[email protected]", 21) == 0) - return 1; + strlist_t sl; - return 0; + register_known_notation (NULL); /* Make sure it is initialized. */ + + for (sl = known_notations_list; sl; sl = sl->next) + if (sl->flags == len && !memcmp (sl->d, name, len)) + return 1; /* Known */ + + if (opt.verbose) + { + log_info(_("Unknown critical signature notation: ") ); + print_utf8_buffer (log_get_stream(), name, len); + log_printf ("\n"); + } + + return 0; /* Unknown. */ } @@ -1888,7 +1932,7 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, { int md5_len = 0; unsigned n; - int is_v4 = 0; + int is_v4or5 = 0; int rc = 0; int i, ndata; @@ -1901,8 +1945,8 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, } sig->version = iobuf_get_noeof (inp); pktlen--; - if (sig->version == 4) - is_v4 = 1; + if (sig->version == 4 || sig->version == 5) + is_v4or5 = 1; else if (sig->version != 2 && sig->version != 3) { log_error ("packet(%d) with unknown version %d\n", @@ -1913,7 +1957,7 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, goto leave; } - if (!is_v4) + if (!is_v4or5) { if (pktlen == 0) goto underflow; @@ -1924,7 +1968,7 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, goto underflow; sig->sig_class = iobuf_get_noeof (inp); pktlen--; - if (!is_v4) + if (!is_v4or5) { if (pktlen < 12) goto underflow; @@ -1943,7 +1987,7 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, pktlen--; sig->flags.exportable = 1; sig->flags.revocable = 1; - if (is_v4) /* Read subpackets. */ + if (is_v4or5) /* Read subpackets. */ { if (pktlen < 2) goto underflow; @@ -2014,7 +2058,7 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, sig->digest_start[1] = iobuf_get_noeof (inp); pktlen--; - if (is_v4 && sig->pubkey_algo) /* Extract required information. */ + if (is_v4or5 && sig->pubkey_algo) /* Extract required information. */ { const byte *p; size_t len; @@ -2115,7 +2159,7 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, (ulong) sig->keyid[0], (ulong) sig->keyid[1], sig->version, (ulong) sig->timestamp, md5_len, sig->sig_class, sig->digest_algo, sig->digest_start[0], sig->digest_start[1]); - if (is_v4) + if (is_v4or5) { parse_sig_subpkt (sig->hashed, SIGSUBPKT_LIST_HASHED, NULL); parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL); @@ -2307,7 +2351,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, { log_error ("packet(%d) too large\n", pkttype); if (list_mode) - es_fputs (":key packet: [too larget]\n", listfp); + es_fputs (":key packet: [too large]\n", listfp); err = gpg_error (GPG_ERR_INV_PACKET); goto leave; } @@ -2528,7 +2572,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, err = gpg_error (GPG_ERR_INV_PACKET); goto leave; } - ski->s2k.count = iobuf_get (inp); + ski->s2k.count = iobuf_get_noeof (inp); pktlen--; if (list_mode) es_fprintf (listfp, "\tprotect count: %lu (%lu)\n", @@ -3136,7 +3180,7 @@ parse_plaintext (IOBUF inp, int pkttype, unsigned long pktlen, pt->name[i] = c; } /* Fill up NAME so that a check with valgrind won't complain about - * reading from uninitalized memory. This case may be triggred by + * reading from uninitialized memory. This case may be triggred by * corrupted packets. */ for (; i < namelen; i++) pt->name[i] = 0; |