asn1/a_int.c: fix "next negative minimum" corner case in c2i_ibuf.
authorAndy Polyakov <appro@openssl.org>
Fri, 28 Apr 2017 08:06:35 +0000 (10:06 +0200)
committerAndy Polyakov <appro@openssl.org>
Sun, 30 Apr 2017 13:19:20 +0000 (15:19 +0200)
"Next" refers to negative minimum "next" to one presentable by given
number of bytes. For example, -128 is negative minimum presentable by
one byte, and -256 is "next" one.

Thanks to Kazuki Yamaguchi for report, GH#3339

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(cherry picked from commit 1e93d619b78832834ae32f5c0c1b0e466267f72d)

crypto/asn1/a_int.c

index e1543439252e0311cbdf9f88732dcb0e886ec5dd..217650a036c98b3452f3cb29f594bcd8b6c59080 100644 (file)
@@ -167,10 +167,21 @@ static size_t c2i_ibuf(unsigned char *b, int *pneg,
         }
         return 1;
     }
-    if (p[0] == 0 || p[0] == 0xFF)
+
+    pad = 0;
+    if (p[0] == 0) {
         pad = 1;
-    else
-        pad = 0;
+    } else if (p[0] == 0xFF) {
+        size_t i;
+
+        /*
+         * Special case [of "one less minimal negative" for given length]:
+         * if any other bytes non zero it was padded, otherwise not.
+         */
+        for (pad = 0, i = 1; i < plen; i++)
+            pad |= p[i];
+        pad = pad != 0 ? 1 : 0;
+    }
     /* reject illegal padding: first two octets MSB can't match */
     if (pad && (neg == (p[1] & 0x80))) {
         ASN1err(ASN1_F_C2I_IBUF, ASN1_R_ILLEGAL_PADDING);