Commit 2442382e authored by Viktor Dukhovni's avatar Viktor Dukhovni
Browse files

Fix buffer overrun in ASN1_parse().



Backport of commits:

        79c7f74d
	bdcd660e

from master.

Reviewed-by: default avatarMatt Caswell <matt@openssl.org>
parent f3277408
Loading
Loading
Loading
Loading
+7 −11
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@
#include <openssl/asn1_mac.h>

static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
                           int max);
                           long max);
static void asn1_put_length(unsigned char **pp, int length);
const char ASN1_version[] = "ASN.1" OPENSSL_VERSION_PTEXT;

@@ -131,7 +131,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
    }
    *ptag = tag;
    *pclass = xclass;
    if (!asn1_get_length(&p, &inf, plength, (int)max))
    if (!asn1_get_length(&p, &inf, plength, max))
        goto err;

    if (inf && !(ret & V_ASN1_CONSTRUCTED))
@@ -159,14 +159,14 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
}

static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
                           int max)
                           long max)
{
    const unsigned char *p = *pp;
    unsigned long ret = 0;
    unsigned int i;
    unsigned long i;

    if (max-- < 1)
        return (0);
        return 0;
    if (*p == 0x80) {
        *inf = 1;
        ret = 0;
@@ -175,15 +175,11 @@ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
        *inf = 0;
        i = *p & 0x7f;
        if (*(p++) & 0x80) {
            if (i > sizeof(long))
            if (i > sizeof(ret) || max < i)
                return 0;
            if (max-- == 0)
                return (0);
            while (i-- > 0) {
                ret <<= 8L;
                ret |= *(p++);
                if (max-- == 0)
                    return (0);
            }
        } else
            ret = i;
@@ -192,7 +188,7 @@ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
        return 0;
    *pp = p;
    *rl = (long)ret;
    return (1);
    return 1;
}

/*
+13 −4
Original line number Diff line number Diff line
@@ -173,6 +173,8 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
        if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
            goto end;
        if (j & V_ASN1_CONSTRUCTED) {
            const unsigned char *sp;

            ep = p + len;
            if (BIO_write(bp, "\n", 1) <= 0)
                goto end;
@@ -182,6 +184,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
                goto end;
            }
            if ((j == 0x21) && (len == 0)) {
                sp = p;
                for (;;) {
                    r = asn1_parse2(bp, &p, (long)(tot - p),
                                    offset + (p - *pp), depth + 1,
@@ -190,18 +193,24 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
                        ret = 0;
                        goto end;
                    }
                    if ((r == 2) || (p >= tot))
                    if ((r == 2) || (p >= tot)) {
                        len = p - sp;
                        break;
                    }
            } else
                }
            } else {
                long tmp = len;

                while (p < ep) {
                    r = asn1_parse2(bp, &p, (long)len,
                                    offset + (p - *pp), depth + 1,
                    sp = p;
                    r = asn1_parse2(bp, &p, tmp, offset + (p - *pp), depth + 1,
                                    indent, dump);
                    if (r == 0) {
                        ret = 0;
                        goto end;
                    }
                    tmp -= p - sp;
                }
            }
        } else if (xclass != 0) {
            p += len;