16 | 16 |
#include "internal/numbers.h"
|
17 | 17 |
#include "asn1_locl.h"
|
18 | 18 |
|
|
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 |
|
19 | 27 |
static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
|
20 | 28 |
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);
|
22 | 31 |
|
23 | 32 |
static int asn1_check_eoc(const unsigned char **in, long len);
|
24 | 33 |
static int asn1_find_end(const unsigned char **in, long len, char inf);
|
|
36 | 45 |
static int asn1_template_ex_d2i(ASN1_VALUE **pval,
|
37 | 46 |
const unsigned char **in, long len,
|
38 | 47 |
const ASN1_TEMPLATE *tt, char opt,
|
39 | |
ASN1_TLC *ctx);
|
|
48 |
ASN1_TLC *ctx, int depth);
|
40 | 49 |
static int asn1_template_noexp_d2i(ASN1_VALUE **val,
|
41 | 50 |
const unsigned char **in, long len,
|
42 | 51 |
const ASN1_TEMPLATE *tt, char opt,
|
43 | |
ASN1_TLC *ctx);
|
|
52 |
ASN1_TLC *ctx, int depth);
|
44 | 53 |
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
|
45 | 54 |
const unsigned char **in, long len,
|
46 | 55 |
const ASN1_ITEM *it,
|
|
110 | 119 |
int tag, int aclass, char opt, ASN1_TLC *ctx)
|
111 | 120 |
{
|
112 | 121 |
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);
|
114 | 123 |
if (rv <= 0)
|
115 | 124 |
ASN1_item_ex_free(pval, it);
|
116 | 125 |
return rv;
|
|
123 | 132 |
|
124 | 133 |
static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
|
125 | 134 |
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)
|
127 | 137 |
{
|
128 | 138 |
const ASN1_TEMPLATE *tt, *errtt = NULL;
|
129 | 139 |
const ASN1_EXTERN_FUNCS *ef;
|
|
144 | 154 |
else
|
145 | 155 |
asn1_cb = 0;
|
146 | 156 |
|
|
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 |
|
147 | 162 |
switch (it->itype) {
|
148 | 163 |
case ASN1_ITYPE_PRIMITIVE:
|
149 | 164 |
if (it->templates) {
|
|
159 | 174 |
goto err;
|
160 | 175 |
}
|
161 | 176 |
return asn1_template_ex_d2i(pval, in, len,
|
162 | |
it->templates, opt, ctx);
|
|
177 |
it->templates, opt, ctx, depth);
|
163 | 178 |
}
|
164 | 179 |
return asn1_d2i_ex_primitive(pval, in, len, it,
|
165 | 180 |
tag, aclass, opt, ctx);
|
|
220 | 235 |
/*
|
221 | 236 |
* We mark field as OPTIONAL so its absence can be recognised.
|
222 | 237 |
*/
|
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);
|
224 | 239 |
/* If field not present, try the next one */
|
225 | 240 |
if (ret == -1)
|
226 | 241 |
continue;
|
|
343 | 358 |
* attempt to read in field, allowing each to be OPTIONAL
|
344 | 359 |
*/
|
345 | 360 |
|
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);
|
347 | 363 |
if (!ret) {
|
348 | 364 |
errtt = seqtt;
|
349 | 365 |
goto err;
|
|
419 | 435 |
static int asn1_template_ex_d2i(ASN1_VALUE **val,
|
420 | 436 |
const unsigned char **in, long inlen,
|
421 | 437 |
const ASN1_TEMPLATE *tt, char opt,
|
422 | |
ASN1_TLC *ctx)
|
|
438 |
ASN1_TLC *ctx, int depth)
|
423 | 439 |
{
|
424 | 440 |
int flags, aclass;
|
425 | 441 |
int ret;
|
|
454 | 470 |
return 0;
|
455 | 471 |
}
|
456 | 472 |
/* 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);
|
458 | 474 |
if (!ret) {
|
459 | 475 |
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
|
460 | 476 |
return 0;
|
|
478 | 494 |
}
|
479 | 495 |
}
|
480 | 496 |
} 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);
|
482 | 498 |
|
483 | 499 |
*in = p;
|
484 | 500 |
return 1;
|
|
490 | 506 |
static int asn1_template_noexp_d2i(ASN1_VALUE **val,
|
491 | 507 |
const unsigned char **in, long len,
|
492 | 508 |
const ASN1_TEMPLATE *tt, char opt,
|
493 | |
ASN1_TLC *ctx)
|
|
509 |
ASN1_TLC *ctx, int depth)
|
494 | 510 |
{
|
495 | 511 |
int flags, aclass;
|
496 | 512 |
int ret;
|
|
572 | 588 |
}
|
573 | 589 |
skfield = NULL;
|
574 | 590 |
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)) {
|
576 | 593 |
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
|
577 | 594 |
ERR_R_NESTED_ASN1_ERROR);
|
578 | 595 |
/* |skfield| may be partially allocated despite failure. */
|
|
594 | 611 |
/* IMPLICIT tagging */
|
595 | 612 |
ret = asn1_item_embed_d2i(val, &p, len,
|
596 | 613 |
ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt,
|
597 | |
ctx);
|
|
614 |
ctx, depth);
|
598 | 615 |
if (!ret) {
|
599 | 616 |
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
|
600 | 617 |
goto err;
|
|
603 | 620 |
} else {
|
604 | 621 |
/* Nothing special */
|
605 | 622 |
ret = asn1_item_embed_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
|
606 | |
-1, 0, opt, ctx);
|
|
623 |
-1, 0, opt, ctx, depth);
|
607 | 624 |
if (!ret) {
|
608 | 625 |
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
|
609 | 626 |
goto err;
|