Check for overflows in ASN1_object_size().
authorDr. Stephen Henson <steve@openssl.org>
Mon, 1 Aug 2016 23:30:47 +0000 (00:30 +0100)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 2 Aug 2016 12:40:32 +0000 (13:40 +0100)
Reviewed-by: Richard Levitte <levitte@openssl.org>
crypto/asn1/asn1_lib.c

index 92604ead86b564b4346ca4197011140c29ac47e1..1b521077a9e5c885860129eb52984ddbb0ff69d7 100644 (file)
@@ -206,26 +206,30 @@ static void asn1_put_length(unsigned char **pp, int length)
 
 int ASN1_object_size(int constructed, int length, int tag)
 {
 
 int ASN1_object_size(int constructed, int length, int tag)
 {
-    int ret;
-
-    ret = length;
-    ret++;
+    int ret = 1;
+    if (length < 0)
+        return -1;
     if (tag >= 31) {
         while (tag > 0) {
             tag >>= 7;
             ret++;
         }
     }
     if (tag >= 31) {
         while (tag > 0) {
             tag >>= 7;
             ret++;
         }
     }
-    if (constructed == 2)
-        return ret + 3;
-    ret++;
-    if (length > 127) {
-        while (length > 0) {
-            length >>= 8;
-            ret++;
+    if (constructed == 2) {
+        ret += 3;
+    } else {
+        ret++;
+        if (length > 127) {
+            int tmplen = length;
+            while (tmplen > 0) {
+                tmplen >>= 8;
+                ret++;
+            }
         }
     }
         }
     }
-    return (ret);
+    if (ret >= INT_MAX - length)
+        return -1;
+    return ret + length;
 }
 
 int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
 }
 
 int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)