Commit bd95d64a authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Check for overflows in EOC.



RT#4474 (partial)

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent f59d0131
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <limits.h>
#include "internal/cryptlib.h"
#include "internal/numbers.h"
#include <openssl/buffer.h>
#include <openssl/asn1.h>

@@ -97,7 +98,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
    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 +153,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 +215,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;
+9 −3
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include "internal/numbers.h"
#include "asn1_locl.h"

static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
@@ -895,7 +896,7 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,

static int asn1_find_end(const unsigned char **in, long len, char inf)
{
    int expected_eoc;
    uint32_t expected_eoc;
    long plen;
    const unsigned char *p = *in, *q;
    /* If not indefinite length constructed just add length */
@@ -925,10 +926,15 @@ static int asn1_find_end(const unsigned char **in, long len, char inf)
            ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
            return 0;
        }
        if (inf)
        if (inf) {
            if (expected_eoc == UINT32_MAX) {
                ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
                return 0;
            }
            expected_eoc++;
        else
        } else {
            p += plen;
        }
        len -= p - q;
    }
    if (expected_eoc) {