diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2009-03-14 18:33:49 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2009-03-14 18:33:49 +0000 |
commit | 854a225a2737e6252772821b86c1200c92f60e53 (patch) | |
tree | 977dc7f510d090bc339fd6c1ae1bfacdc61a006c | |
parent | e39acc1c90f5a41916d857ace42c7b9a47f8e7a6 (diff) |
Update from stable branch.
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | crypto/asn1/tasn_dec.c | 30 |
2 files changed, 25 insertions, 9 deletions
@@ -748,6 +748,10 @@ Changes between 0.9.8j and 0.9.8k [xx XXX xxxx] + *) Permit restricted recursion of ASN1 strings. This is needed in practice + to handle some structures. + [Steve Henson] + *) Improve efficiency of mem_gets: don't search whole buffer each time for a '\n' [Jeremy Shapiro <jnshapir@us.ibm.com>] diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c index 6bab6d4a6f..b8fa20896b 100644 --- a/crypto/asn1/tasn_dec.c +++ b/crypto/asn1/tasn_dec.c @@ -69,7 +69,7 @@ static int asn1_check_eoc(const unsigned char **in, long len); static int asn1_find_end(const unsigned char **in, long len, char inf); static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, - char inf, int tag, int aclass); + char inf, int tag, int aclass, int depth); static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen); @@ -882,7 +882,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, * internally irrespective of the type. So instead just check * for UNIVERSAL class and ignore the tag. */ - if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL)) + if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) { free_cont = 1; goto err; @@ -1132,8 +1132,18 @@ static int asn1_find_end(const unsigned char **in, long len, char inf) * if it is indefinite length. */ +#ifndef ASN1_MAX_STRING_NEST +/* This determines how many levels of recursion are permitted in ASN1 + * string types. If it is not limited stack overflows can occur. If set + * to zero no recursion is allowed at all. Although zero should be adequate + * examples exist that require a value of 1. So 5 should be more than enough. + */ +#define ASN1_MAX_STRING_NEST 5 +#endif + + static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, - char inf, int tag, int aclass) + char inf, int tag, int aclass, int depth) { const unsigned char *p, *q; long plen; @@ -1175,13 +1185,15 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, /* If indefinite length constructed update max length */ if (cst) { -#ifdef OPENSSL_ALLOW_NESTED_ASN1_STRINGS - if (!asn1_collect(buf, &p, plen, ininf, tag, aclass)) + if (depth >= ASN1_MAX_STRING_NEST) + { + ASN1err(ASN1_F_ASN1_COLLECT, + ASN1_R_NESTED_ASN1_STRING); + return 0; + } + if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, + depth + 1)) return 0; -#else - ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING); - return 0; -#endif } else if (plen && !collect_data(buf, &p, plen)) return 0; |