Codebase list openssl / 2ac4c6f
Limit ASN.1 constructed types recursive definition depth Constructed types with a recursive definition (such as can be found in PKCS7) could eventually exceed the stack given malicious input with excessive recursion. Therefore we limit the stack depth. CVE-2018-0739 Credit to OSSFuzz for finding this issue. Reviewed-by: Rich Salz <rsalz@openssl.org> Matt Caswell 6 years ago
3 changed file(s) with 35 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
00 /*
11 * Generated by util/mkerr.pl DO NOT EDIT
2 * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
33 *
44 * Licensed under the OpenSSL license (the "License"). You may not use
55 * this file except in compliance with the License. You can obtain a copy
202202 {ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"},
203203 {ERR_REASON(ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"},
204204 {ERR_REASON(ASN1_R_NESTED_ASN1_STRING), "nested asn1 string"},
205 {ERR_REASON(ASN1_R_NESTED_TOO_DEEP), "nested too deep"},
205206 {ERR_REASON(ASN1_R_NON_HEX_CHARACTERS), "non hex characters"},
206207 {ERR_REASON(ASN1_R_NOT_ASCII_FORMAT), "not ascii format"},
207208 {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA), "not enough data"},
1616 #include "internal/numbers.h"
1717 #include "asn1_locl.h"
1818
19 /*
20 * Constructed types with a recursive definition (such as can be found in PKCS7)
21 * could eventually exceed the stack given malicious input with excessive
22 * recursion. Therefore we limit the stack depth. This is the maximum number of
23 * recursive invocations of asn1_item_embed_d2i().
24 */
25 #define ASN1_MAX_CONSTRUCTED_NEST 30
26
1927 static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
2028 long len, const ASN1_ITEM *it,
21 int tag, int aclass, char opt, ASN1_TLC *ctx);
29 int tag, int aclass, char opt, ASN1_TLC *ctx,
30 int depth);
2231
2332 static int asn1_check_eoc(const unsigned char **in, long len);
2433 static int asn1_find_end(const unsigned char **in, long len, char inf);
3645 static int asn1_template_ex_d2i(ASN1_VALUE **pval,
3746 const unsigned char **in, long len,
3847 const ASN1_TEMPLATE *tt, char opt,
39 ASN1_TLC *ctx);
48 ASN1_TLC *ctx, int depth);
4049 static int asn1_template_noexp_d2i(ASN1_VALUE **val,
4150 const unsigned char **in, long len,
4251 const ASN1_TEMPLATE *tt, char opt,
43 ASN1_TLC *ctx);
52 ASN1_TLC *ctx, int depth);
4453 static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
4554 const unsigned char **in, long len,
4655 const ASN1_ITEM *it,
110119 int tag, int aclass, char opt, ASN1_TLC *ctx)
111120 {
112121 int rv;
113 rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx);
122 rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0);
114123 if (rv <= 0)
115124 ASN1_item_ex_free(pval, it);
116125 return rv;
123132
124133 static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
125134 long len, const ASN1_ITEM *it,
126 int tag, int aclass, char opt, ASN1_TLC *ctx)
135 int tag, int aclass, char opt, ASN1_TLC *ctx,
136 int depth)
127137 {
128138 const ASN1_TEMPLATE *tt, *errtt = NULL;
129139 const ASN1_EXTERN_FUNCS *ef;
144154 else
145155 asn1_cb = 0;
146156
157 if (++depth > ASN1_MAX_CONSTRUCTED_NEST) {
158 ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_NESTED_TOO_DEEP);
159 goto err;
160 }
161
147162 switch (it->itype) {
148163 case ASN1_ITYPE_PRIMITIVE:
149164 if (it->templates) {
159174 goto err;
160175 }
161176 return asn1_template_ex_d2i(pval, in, len,
162 it->templates, opt, ctx);
177 it->templates, opt, ctx, depth);
163178 }
164179 return asn1_d2i_ex_primitive(pval, in, len, it,
165180 tag, aclass, opt, ctx);
220235 /*
221236 * We mark field as OPTIONAL so its absence can be recognised.
222237 */
223 ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
238 ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth);
224239 /* If field not present, try the next one */
225240 if (ret == -1)
226241 continue;
343358 * attempt to read in field, allowing each to be OPTIONAL
344359 */
345360
346 ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
361 ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx,
362 depth);
347363 if (!ret) {
348364 errtt = seqtt;
349365 goto err;
419435 static int asn1_template_ex_d2i(ASN1_VALUE **val,
420436 const unsigned char **in, long inlen,
421437 const ASN1_TEMPLATE *tt, char opt,
422 ASN1_TLC *ctx)
438 ASN1_TLC *ctx, int depth)
423439 {
424440 int flags, aclass;
425441 int ret;
454470 return 0;
455471 }
456472 /* We've found the field so it can't be OPTIONAL now */
457 ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
473 ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth);
458474 if (!ret) {
459475 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
460476 return 0;
478494 }
479495 }
480496 } else
481 return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx);
497 return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth);
482498
483499 *in = p;
484500 return 1;
490506 static int asn1_template_noexp_d2i(ASN1_VALUE **val,
491507 const unsigned char **in, long len,
492508 const ASN1_TEMPLATE *tt, char opt,
493 ASN1_TLC *ctx)
509 ASN1_TLC *ctx, int depth)
494510 {
495511 int flags, aclass;
496512 int ret;
572588 }
573589 skfield = NULL;
574590 if (!asn1_item_embed_d2i(&skfield, &p, len,
575 ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
591 ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx,
592 depth)) {
576593 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
577594 ERR_R_NESTED_ASN1_ERROR);
578595 /* |skfield| may be partially allocated despite failure. */
594611 /* IMPLICIT tagging */
595612 ret = asn1_item_embed_d2i(val, &p, len,
596613 ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt,
597 ctx);
614 ctx, depth);
598615 if (!ret) {
599616 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
600617 goto err;
603620 } else {
604621 /* Nothing special */
605622 ret = asn1_item_embed_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
606 -1, 0, opt, ctx);
623 -1, 0, opt, ctx, depth);
607624 if (!ret) {
608625 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
609626 goto err;
10501050 # define ASN1_R_MSTRING_NOT_UNIVERSAL 139
10511051 # define ASN1_R_MSTRING_WRONG_TAG 140
10521052 # define ASN1_R_NESTED_ASN1_STRING 197
1053 # define ASN1_R_NESTED_TOO_DEEP 201
10531054 # define ASN1_R_NON_HEX_CHARACTERS 141
10541055 # define ASN1_R_NOT_ASCII_FORMAT 190
10551056 # define ASN1_R_NOT_ENOUGH_DATA 142