]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Fix possible wrap in uint32_t addition in DER parser
authorPierre Chifflier <pierre.chifflier@ssi.gouv.fr>
Sat, 18 Apr 2015 12:24:45 +0000 (14:24 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 6 May 2015 18:30:05 +0000 (20:30 +0200)
Signed-off-by: Pierre Chifflier <pierre.chifflier@ssi.gouv.fr>
src/util-decode-der.c

index 3e7324be9cdb65f485834a6017b4901749825f84..1687668bd5fd8abebdb91589f5cef40945e6194c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2012 ANSSI
+ * Copyright (C) 2011-2015 ANSSI
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -466,8 +466,11 @@ static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_
             return NULL;
         }
     }
-    if (length > max_size)
+    if (length == UINT32_MAX || length > max_size) {
+        if (errcode)
+            *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
         return NULL;
+    }
 
     a = Asn1GenericNew();
     if (a == NULL)
@@ -508,8 +511,11 @@ static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer, uint3
             return NULL;
         }
     }
-    if (length > max_size)
+    if (length == UINT32_MAX || length > max_size) {
+        if (errcode)
+            *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
         return NULL;
+    }
 
     a = Asn1GenericNew();
     if (a == NULL)
@@ -561,8 +567,11 @@ static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, u
             return NULL;
         }
     }
-    if (length > max_size)
+    if (length == UINT32_MAX || length > max_size) {
+        if (errcode)
+            *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
         return NULL;
+    }
 
     a = Asn1GenericNew();
     if (a == NULL)
@@ -612,7 +621,9 @@ static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t
         }
     }
     node->length = d_length + (d_ptr - buffer);
-    if (node->length > max_size) {
+    if (node->length > max_size || node->length < d_length /* wrap */) {
+        if (errcode)
+            *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
         SCFree(node);
         return NULL;
     }
@@ -626,6 +637,10 @@ static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t
 
         Asn1Generic *child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index, errcode);
         if (child == NULL) {
+            if (errcode && *errcode != 0) {
+                DerFree(node);
+                return NULL;
+            }
             break;
         }
 
@@ -676,7 +691,7 @@ static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t max_
     }
     node->length = d_length + (d_ptr - buffer);
 
-    if (node->length > max_size) {
+    if (node->length > max_size || node->length < d_length /* wrap */) {
         if (errcode)
             *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
         SCFree(node);
@@ -687,6 +702,10 @@ static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t max_
 
     el_max_size = max_size - (d_ptr-buffer);
     child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index, errcode);
+    if (child == NULL) {
+        DerFree(node);
+        return NULL;
+    }
 
     node->data = child;