Guard against DoS in name constraints handling.
[openssl.git] / crypto / asn1 / a_d2i_fp.c
index 9676ab7bc2855b203d9aa212da67a605b41f550d..5fa4d0fa71bb48fbc0ac8fc617a83efea5375666 100644 (file)
 #include <stdio.h>
 #include <limits.h>
 #include "internal/cryptlib.h"
+#include "internal/numbers.h"
 #include <openssl/buffer.h>
 #include <openssl/asn1.h>
-
-static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
+#include "internal/asn1_int.h"
 
 #ifndef NO_OLD_ASN1
 # ifndef OPENSSL_NO_STDIO
@@ -91,13 +91,13 @@ void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
 
 #define HEADER_SIZE   8
 #define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
-static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
+int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
 {
     BUF_MEM *b;
     unsigned char *p;
     int i;
     size_t want = HEADER_SIZE;
-    int eos = 0;
+    uint32_t eos = 0;
     size_t off = 0;
     size_t len = 0;
 
@@ -152,16 +152,16 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
 
         if (inf & 1) {
             /* no data body so go round again */
-            eos++;
-            if (eos < 0) {
+            if (eos == UINT32_MAX) {
                 ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG);
                 goto err;
             }
+            eos++;
             want = HEADER_SIZE;
         } else if (eos && (slen == 0) && (tag == V_ASN1_EOC)) {
             /* eos value, so go back and read another header */
             eos--;
-            if (eos <= 0)
+            if (eos == 0)
                 break;
             else
                 want = HEADER_SIZE;
@@ -214,7 +214,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
                 goto err;
             }
             off += slen;
-            if (eos <= 0) {
+            if (eos == 0) {
                 break;
             } else
                 want = HEADER_SIZE;