aboutsummaryrefslogtreecommitdiffstats
path: root/g10/parse-packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/parse-packet.c')
-rw-r--r--g10/parse-packet.c82
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,
+ 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;