Fix buffer overrun in ASN1_parse().
Fix buffer overrun in asn1_get_length(). Reproducer: asn1parse-reproduce crash-6bfd417f47bc940f6984f5e639b637fd4e6074bc Fix length calculations. Reproducer: asn1parse-reproduce crash-1819d0e54cd2b0430626c59053e6077ef04c2ffb Reproducer: asn1parse-reproduce crash-9969db8603e644ddc0ba3459b51eac7a2c4b729b Make i long. Reviewed-by: Rich Salz <rsalz@openssl.org>
This commit is contained in:
		@@ -61,7 +61,7 @@
 | 
				
			|||||||
#include <openssl/asn1.h>
 | 
					#include <openssl/asn1.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
 | 
					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);
 | 
					static void asn1_put_length(unsigned char **pp, int length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int _asn1_check_infinite_end(const unsigned char **p, long len)
 | 
					static int _asn1_check_infinite_end(const unsigned char **p, long len)
 | 
				
			||||||
@@ -128,7 +128,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    *ptag = tag;
 | 
					    *ptag = tag;
 | 
				
			||||||
    *pclass = xclass;
 | 
					    *pclass = xclass;
 | 
				
			||||||
    if (!asn1_get_length(&p, &inf, plength, (int)max))
 | 
					    if (!asn1_get_length(&p, &inf, plength, max))
 | 
				
			||||||
        goto err;
 | 
					        goto err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (inf && !(ret & V_ASN1_CONSTRUCTED))
 | 
					    if (inf && !(ret & V_ASN1_CONSTRUCTED))
 | 
				
			||||||
@@ -150,14 +150,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,
 | 
					static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
 | 
				
			||||||
                           int max)
 | 
					                           long max)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const unsigned char *p = *pp;
 | 
					    const unsigned char *p = *pp;
 | 
				
			||||||
    unsigned long ret = 0;
 | 
					    unsigned long ret = 0;
 | 
				
			||||||
    unsigned int i;
 | 
					    unsigned long i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (max-- < 1)
 | 
					    if (max-- < 1)
 | 
				
			||||||
        return (0);
 | 
					        return 0;
 | 
				
			||||||
    if (*p == 0x80) {
 | 
					    if (*p == 0x80) {
 | 
				
			||||||
        *inf = 1;
 | 
					        *inf = 1;
 | 
				
			||||||
        ret = 0;
 | 
					        ret = 0;
 | 
				
			||||||
@@ -166,7 +166,7 @@ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
 | 
				
			|||||||
        *inf = 0;
 | 
					        *inf = 0;
 | 
				
			||||||
        i = *p & 0x7f;
 | 
					        i = *p & 0x7f;
 | 
				
			||||||
        if (*(p++) & 0x80) {
 | 
					        if (*(p++) & 0x80) {
 | 
				
			||||||
            if (max < (int)i)
 | 
					            if (max < (long)i + 1)
 | 
				
			||||||
                return 0;
 | 
					                return 0;
 | 
				
			||||||
            /* Skip leading zeroes */
 | 
					            /* Skip leading zeroes */
 | 
				
			||||||
            while (i && *p == 0) {
 | 
					            while (i && *p == 0) {
 | 
				
			||||||
@@ -186,7 +186,7 @@ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
 | 
				
			|||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    *pp = p;
 | 
					    *pp = p;
 | 
				
			||||||
    *rl = (long)ret;
 | 
					    *rl = (long)ret;
 | 
				
			||||||
    return (1);
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -164,6 +164,8 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
 | 
				
			|||||||
        if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
 | 
					        if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
 | 
				
			||||||
            goto end;
 | 
					            goto end;
 | 
				
			||||||
        if (j & V_ASN1_CONSTRUCTED) {
 | 
					        if (j & V_ASN1_CONSTRUCTED) {
 | 
				
			||||||
 | 
					            const unsigned char *sp = p;
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
            ep = p + len;
 | 
					            ep = p + len;
 | 
				
			||||||
            if (BIO_write(bp, "\n", 1) <= 0)
 | 
					            if (BIO_write(bp, "\n", 1) <= 0)
 | 
				
			||||||
                goto end;
 | 
					                goto end;
 | 
				
			||||||
@@ -181,19 +183,25 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
 | 
				
			|||||||
                        ret = 0;
 | 
					                        ret = 0;
 | 
				
			||||||
                        goto end;
 | 
					                        goto end;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if ((r == 2) || (p >= tot))
 | 
					                    if ((r == 2) || (p >= tot)) {
 | 
				
			||||||
 | 
					                        len = p - sp;
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else
 | 
					            } else {
 | 
				
			||||||
                while (p < ep) {
 | 
					                while (p < ep) {
 | 
				
			||||||
                    r = asn1_parse2(bp, &p, (long)len,
 | 
					                    sp = p;
 | 
				
			||||||
 | 
					                    r = asn1_parse2(bp, &p, len,
 | 
				
			||||||
                                    offset + (p - *pp), depth + 1,
 | 
					                                    offset + (p - *pp), depth + 1,
 | 
				
			||||||
                                    indent, dump);
 | 
					                                    indent, dump);
 | 
				
			||||||
                    if (r == 0) {
 | 
					                    if (r == 0) {
 | 
				
			||||||
                        ret = 0;
 | 
					                        ret = 0;
 | 
				
			||||||
                        goto end;
 | 
					                        goto end;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    len -= p - sp;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                len = length;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        } else if (xclass != 0) {
 | 
					        } else if (xclass != 0) {
 | 
				
			||||||
            p += len;
 | 
					            p += len;
 | 
				
			||||||
            if (BIO_write(bp, "\n", 1) <= 0)
 | 
					            if (BIO_write(bp, "\n", 1) <= 0)
 | 
				
			||||||
@@ -229,7 +237,8 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
 | 
				
			|||||||
                        goto end;
 | 
					                        goto end;
 | 
				
			||||||
                    dump_cont = 1;
 | 
					                    dump_cont = 1;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                BIO_printf(bp, ":%u", p[0]);
 | 
					                if (len > 0)
 | 
				
			||||||
 | 
					                    BIO_printf(bp, ":%u", p[0]);
 | 
				
			||||||
            } else if (tag == V_ASN1_BMPSTRING) {
 | 
					            } else if (tag == V_ASN1_BMPSTRING) {
 | 
				
			||||||
                /* do the BMP thang */
 | 
					                /* do the BMP thang */
 | 
				
			||||||
            } else if (tag == V_ASN1_OCTET_STRING) {
 | 
					            } else if (tag == V_ASN1_OCTET_STRING) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user