From: Dr. Stephen Henson Date: Sat, 30 Apr 2005 13:08:56 +0000 (+0000) Subject: Update from HEAD. X-Git-Tag: BEN_FIPS_TEST_8~54 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=c1668fe59d6c50c9ac1f7bae651948ee25ac1266;p=oweals%2Fopenssl.git Update from HEAD. --- diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h index ceaeb4cbe3..d75aa0dc03 100644 --- a/crypto/asn1/asn1.h +++ b/crypto/asn1/asn1.h @@ -962,6 +962,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_F_ASN1_DUP 111 #define ASN1_F_ASN1_ENUMERATED_SET 112 #define ASN1_F_ASN1_ENUMERATED_TO_BN 113 +#define ASN1_F_ASN1_FIND_END 182 #define ASN1_F_ASN1_GENERALIZEDTIME_SET 178 #define ASN1_F_ASN1_GET_OBJECT 114 #define ASN1_F_ASN1_HEADER_NEW 115 diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c index 887a4295e7..cb39d35a9a 100644 --- a/crypto/asn1/asn1_err.c +++ b/crypto/asn1/asn1_err.c @@ -86,6 +86,7 @@ static ERR_STRING_DATA ASN1_str_functs[]= {ERR_FUNC(ASN1_F_ASN1_DUP), "ASN1_dup"}, {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_SET), "ASN1_ENUMERATED_set"}, {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"}, +{ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"}, {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"}, {ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"}, {ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_new"}, diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c index 2426cb6253..86c901199b 100644 --- a/crypto/asn1/tasn_dec.c +++ b/crypto/asn1/tasn_dec.c @@ -66,6 +66,7 @@ #include static int asn1_check_eoc(unsigned char **in, long len); +static int asn1_find_end(unsigned char **in, long len, char inf); static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass); static int collect_data(BUF_MEM *buf, unsigned char **p, long plen); static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, @@ -644,7 +645,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl cont = *in; /* If indefinite length constructed find the real end */ if(inf) { - if(!asn1_collect(NULL, &p, plen, inf, -1, -1)) goto err; + if(!asn1_find_end(&p, plen, inf)) goto err; len = p - cont; } else { len = p - cont + plen; @@ -807,12 +808,66 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char return ret; } +/* This function finds the end of an ASN1 structure when passed its maximum + * length, whether it is indefinite length and a pointer to the content. + * This is more efficient than calling asn1_collect because it does not + * recurse on each indefinite length header. + */ + +static int asn1_find_end(unsigned char **in, long len, char inf) + { + int expected_eoc; + long plen; + unsigned char *p = *in, *q; + /* If not indefinite length constructed just add length */ + if (inf == 0) + { + *in += len; + return 1; + } + expected_eoc = 1; + /* Indefinite length constructed form. Find the end when enough EOCs + * are found. If more indefinite length constructed headers + * are encountered increment the expected eoc count otherwise justi + * skip to the end of the data. + */ + while (len > 0) + { + if(asn1_check_eoc(&p, len)) + { + expected_eoc--; + if (expected_eoc == 0) + break; + len -= 2; + continue; + } + q = p; + /* Just read in a header: only care about the length */ + if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len, + -1, 0, 0, NULL)) + { + ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR); + return 0; + } + if (inf) + expected_eoc++; + else + p += plen; + len -= p - q; + } + if (expected_eoc) + { + ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC); + return 0; + } + *in = p; + return 1; + } + /* This function collects the asn1 data from a constructred string * type into a buffer. The values of 'in' and 'len' should refer * to the contents of the constructed type and 'inf' should be set - * if it is indefinite length. If 'buf' is NULL then we just want - * to find the end of the current structure: useful for indefinite - * length constructed stuff. + * if it is indefinite length. */ static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass) @@ -822,11 +877,6 @@ static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, in char cst, ininf; p = *in; inf &= 1; - /* If no buffer and not indefinite length constructed just pass over the encoded data */ - if(!buf && !inf) { - *in += len; - return 1; - } while(len > 0) { q = p; /* Check for EOC */