]> granicus.if.org Git - file/commitdiff
Fix error checking in the simple case (one digit length) of der magic.
authorChristos Zoulas <christos@zoulas.com>
Mon, 7 Nov 2016 15:51:23 +0000 (15:51 +0000)
committerChristos Zoulas <christos@zoulas.com>
Mon, 7 Nov 2016 15:51:23 +0000 (15:51 +0000)
(Jonas Wagner)

src/der.c

index ee7a7aec6de432cac98d77db97d7d6c95f9d0ef3..fbb5d83896bb7de3418f11a57d0eef2b7c008cb3 100644 (file)
--- a/src/der.c
+++ b/src/der.c
@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: der.c,v 1.9 2016/10/24 15:19:08 christos Exp $")
+FILE_RCSID("@(#)$File: der.c,v 1.10 2016/10/24 18:02:17 christos Exp $")
 #endif
 #endif
 
@@ -159,31 +159,49 @@ gettag(const uint8_t *c, size_t *p, size_t l)
        return tag;
 }
 
+/*
+ * Read the length of a DER tag from the input.
+ *
+ * `c` is the input, `p` is an output parameter that specifies how much of the
+ * input we consumed, and `l` is the maximum input length.
+ *
+ * Returns the length, or DER_BAD if the end of the input is reached or the
+ * length exceeds the remaining input.
+ */
 static uint32_t
 getlength(const uint8_t *c, size_t *p, size_t l)
 {
        uint8_t digits, i;
        size_t len;
+       int is_onebyte_result;
 
        if (*p >= l)
                return DER_BAD;
 
-       digits = c[(*p)++];
+       /*
+        * Digits can either be 0b0 followed by the result, or 0b1
+        * followed by the number of digits of the result. In either case,
+        * we verify that we can read so many bytes from the input.
+        */
+       is_onebyte_result = (c[*p] & 0x80) == 0;
+       digits = c[(*p)++] & 0x7f;
+       if (*p + digits >= l)
+               return DER_BAD;
 
-        if ((digits & 0x80) == 0)
+       if (is_onebyte_result)
                return digits;
 
-        digits &= 0x7f;
+       /*
+        * Decode len. We've already verified that we're allowed to read
+        * `digits` bytes.
+        */
        len = 0;
-
-       if (*p + digits >= l)
-               return DER_BAD;
-
        for (i = 0; i < digits; i++)
                len = (len << 8) | c[(*p)++];
+
        if (*p + len >= l)
                return DER_BAD;
-        return len;
+       return len;
 }
 
 static const char *