diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/asn1/tasn_dec.c | 127 |
1 files changed, 37 insertions, 90 deletions
diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c index 5c68834461..3936ecba63 100644 --- a/src/lib/libcrypto/asn1/tasn_dec.c +++ b/src/lib/libcrypto/asn1/tasn_dec.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tasn_dec.c,v 1.51 2022/04/26 20:00:18 jsing Exp $ */ | 1 | /* $OpenBSD: tasn_dec.c,v 1.52 2022/04/27 17:28:34 jsing Exp $ */ |
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 | * project 2000. | 3 | * project 2000. |
4 | */ | 4 | */ |
@@ -83,40 +83,28 @@ static int asn1_collect(CBB *cbb, const unsigned char **in, long len, | |||
83 | 83 | ||
84 | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, | 84 | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, |
85 | char *inf, char *cst, const unsigned char **in, long len, int exptag, | 85 | char *inf, char *cst, const unsigned char **in, long len, int exptag, |
86 | int expclass, char opt, ASN1_TLC *ctx); | 86 | int expclass, char opt); |
87 | 87 | ||
88 | static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, | 88 | static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, |
89 | long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx, | 89 | long len, const ASN1_ITEM *it, int tag, int aclass, char opt, int depth); |
90 | int depth); | ||
91 | static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, | 90 | static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, |
92 | long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx, int depth); | 91 | long len, const ASN1_TEMPLATE *tt, char opt, int depth); |
93 | static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, | 92 | static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, |
94 | long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx, int depth); | 93 | long len, const ASN1_TEMPLATE *tt, char opt, int depth); |
95 | static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, | 94 | static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, |
96 | long len, const ASN1_ITEM *it, int tag, int aclass, char opt, | 95 | long len, const ASN1_ITEM *it, int tag, int aclass, char opt); |
97 | ASN1_TLC *ctx); | ||
98 | static int asn1_ex_c2i(ASN1_VALUE **pval, CBS *content, int utype, | 96 | static int asn1_ex_c2i(ASN1_VALUE **pval, CBS *content, int utype, |
99 | const ASN1_ITEM *it); | 97 | const ASN1_ITEM *it); |
100 | 98 | ||
101 | static void | ||
102 | asn1_tlc_invalidate(ASN1_TLC *ctx) | ||
103 | { | ||
104 | if (ctx != NULL) | ||
105 | ctx->valid = 0; | ||
106 | } | ||
107 | |||
108 | ASN1_VALUE * | 99 | ASN1_VALUE * |
109 | ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | 100 | ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, |
110 | const ASN1_ITEM *it) | 101 | const ASN1_ITEM *it) |
111 | { | 102 | { |
112 | ASN1_VALUE *ptmpval = NULL; | 103 | ASN1_VALUE *ptmpval = NULL; |
113 | ASN1_TLC ctx; | ||
114 | |||
115 | asn1_tlc_invalidate(&ctx); | ||
116 | 104 | ||
117 | if (pval == NULL) | 105 | if (pval == NULL) |
118 | pval = &ptmpval; | 106 | pval = &ptmpval; |
119 | if (asn1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &ctx, 0) <= 0) | 107 | if (asn1_item_ex_d2i(pval, in, len, it, -1, 0, 0, 0) <= 0) |
120 | return NULL; | 108 | return NULL; |
121 | 109 | ||
122 | return *pval; | 110 | return *pval; |
@@ -126,11 +114,7 @@ int | |||
126 | ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | 114 | ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, |
127 | const ASN1_TEMPLATE *tt) | 115 | const ASN1_TEMPLATE *tt) |
128 | { | 116 | { |
129 | ASN1_TLC ctx; | 117 | return asn1_template_ex_d2i(pval, in, len, tt, 0, 0); |
130 | |||
131 | asn1_tlc_invalidate(&ctx); | ||
132 | |||
133 | return asn1_template_ex_d2i(pval, in, len, tt, 0, &ctx, 0); | ||
134 | } | 118 | } |
135 | 119 | ||
136 | /* Decode an item, taking care of IMPLICIT tagging, if any. | 120 | /* Decode an item, taking care of IMPLICIT tagging, if any. |
@@ -139,13 +123,13 @@ ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | |||
139 | 123 | ||
140 | static int | 124 | static int |
141 | asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | 125 | asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, |
142 | const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx, | 126 | const ASN1_ITEM *it, int tag, int aclass, char opt, int depth) |
143 | int depth) | ||
144 | { | 127 | { |
145 | const ASN1_TEMPLATE *tt, *errtt = NULL; | 128 | const ASN1_TEMPLATE *tt, *errtt = NULL; |
146 | const ASN1_EXTERN_FUNCS *ef; | 129 | const ASN1_EXTERN_FUNCS *ef; |
147 | const ASN1_AUX *aux = it->funcs; | 130 | const ASN1_AUX *aux = it->funcs; |
148 | ASN1_aux_cb *asn1_cb = NULL; | 131 | ASN1_aux_cb *asn1_cb = NULL; |
132 | ASN1_TLC ctx = { 0 }; | ||
149 | const unsigned char *p = NULL, *q; | 133 | const unsigned char *p = NULL, *q; |
150 | unsigned char oclass; | 134 | unsigned char oclass; |
151 | char seq_eoc, seq_nolen, cst, isopt; | 135 | char seq_eoc, seq_nolen, cst, isopt; |
@@ -184,10 +168,10 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | |||
184 | goto err; | 168 | goto err; |
185 | } | 169 | } |
186 | return asn1_template_ex_d2i(pval, in, len, | 170 | return asn1_template_ex_d2i(pval, in, len, |
187 | it->templates, opt, ctx, depth); | 171 | it->templates, opt, depth); |
188 | } | 172 | } |
189 | return asn1_d2i_ex_primitive(pval, in, len, it, | 173 | return asn1_d2i_ex_primitive(pval, in, len, it, |
190 | tag, aclass, opt, ctx); | 174 | tag, aclass, opt); |
191 | break; | 175 | break; |
192 | 176 | ||
193 | case ASN1_ITYPE_MSTRING: | 177 | case ASN1_ITYPE_MSTRING: |
@@ -204,7 +188,7 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | |||
204 | p = *in; | 188 | p = *in; |
205 | /* Just read in tag and class */ | 189 | /* Just read in tag and class */ |
206 | ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, | 190 | ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, |
207 | &p, len, -1, 0, 1, ctx); | 191 | &p, len, -1, 0, 1); |
208 | if (!ret) { | 192 | if (!ret) { |
209 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 193 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
210 | goto err; | 194 | goto err; |
@@ -227,13 +211,12 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | |||
227 | goto err; | 211 | goto err; |
228 | } | 212 | } |
229 | return asn1_d2i_ex_primitive(pval, in, len, | 213 | return asn1_d2i_ex_primitive(pval, in, len, |
230 | it, otag, 0, 0, ctx); | 214 | it, otag, 0, 0); |
231 | 215 | ||
232 | case ASN1_ITYPE_EXTERN: | 216 | case ASN1_ITYPE_EXTERN: |
233 | /* Use new style d2i */ | 217 | /* Use new style d2i */ |
234 | ef = it->funcs; | 218 | ef = it->funcs; |
235 | return ef->asn1_ex_d2i(pval, in, len, | 219 | return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, &ctx); |
236 | it, tag, aclass, opt, ctx); | ||
237 | 220 | ||
238 | case ASN1_ITYPE_CHOICE: | 221 | case ASN1_ITYPE_CHOICE: |
239 | /* | 222 | /* |
@@ -269,8 +252,8 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | |||
269 | /* We mark field as OPTIONAL so its absence | 252 | /* We mark field as OPTIONAL so its absence |
270 | * can be recognised. | 253 | * can be recognised. |
271 | */ | 254 | */ |
272 | ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, | 255 | ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, |
273 | depth); | 256 | depth); |
274 | /* If field not present, try the next one */ | 257 | /* If field not present, try the next one */ |
275 | if (ret == -1) | 258 | if (ret == -1) |
276 | continue; | 259 | continue; |
@@ -313,7 +296,7 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | |||
313 | } | 296 | } |
314 | /* Get SEQUENCE length and update len, p */ | 297 | /* Get SEQUENCE length and update len, p */ |
315 | ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, | 298 | ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, |
316 | &p, len, tag, aclass, opt, ctx); | 299 | &p, len, tag, aclass, opt); |
317 | if (!ret) { | 300 | if (!ret) { |
318 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 301 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
319 | goto err; | 302 | goto err; |
@@ -388,7 +371,7 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | |||
388 | * OPTIONAL */ | 371 | * OPTIONAL */ |
389 | 372 | ||
390 | ret = asn1_template_ex_d2i(pseqval, &p, len, | 373 | ret = asn1_template_ex_d2i(pseqval, &p, len, |
391 | seqtt, isopt, ctx, depth); | 374 | seqtt, isopt, depth); |
392 | if (!ret) { | 375 | if (!ret) { |
393 | errtt = seqtt; | 376 | errtt = seqtt; |
394 | goto err; | 377 | goto err; |
@@ -464,7 +447,7 @@ int | |||
464 | ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | 447 | ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, |
465 | const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx) | 448 | const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx) |
466 | { | 449 | { |
467 | return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); | 450 | return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, 0); |
468 | } | 451 | } |
469 | 452 | ||
470 | /* Templates are handled with two separate functions. | 453 | /* Templates are handled with two separate functions. |
@@ -473,7 +456,7 @@ ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | |||
473 | 456 | ||
474 | static int | 457 | static int |
475 | asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, | 458 | asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, |
476 | const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx, int depth) | 459 | const ASN1_TEMPLATE *tt, char opt, int depth) |
477 | { | 460 | { |
478 | int flags, aclass; | 461 | int flags, aclass; |
479 | int ret; | 462 | int ret; |
@@ -496,7 +479,7 @@ asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, | |||
496 | * get the info. | 479 | * get the info. |
497 | */ | 480 | */ |
498 | ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, | 481 | ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, |
499 | &p, inlen, tt->tag, aclass, opt, ctx); | 482 | &p, inlen, tt->tag, aclass, opt); |
500 | q = p; | 483 | q = p; |
501 | if (!ret) { | 484 | if (!ret) { |
502 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 485 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
@@ -508,7 +491,7 @@ asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, | |||
508 | return 0; | 491 | return 0; |
509 | } | 492 | } |
510 | /* We've found the field so it can't be OPTIONAL now */ | 493 | /* We've found the field so it can't be OPTIONAL now */ |
511 | ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); | 494 | ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, depth); |
512 | if (!ret) { | 495 | if (!ret) { |
513 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 496 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
514 | return 0; | 497 | return 0; |
@@ -530,8 +513,7 @@ asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, | |||
530 | } | 513 | } |
531 | } | 514 | } |
532 | } else | 515 | } else |
533 | return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, | 516 | return asn1_template_noexp_d2i(val, in, inlen, tt, opt, depth); |
534 | depth); | ||
535 | 517 | ||
536 | *in = p; | 518 | *in = p; |
537 | return 1; | 519 | return 1; |
@@ -543,7 +525,7 @@ asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, | |||
543 | 525 | ||
544 | static int | 526 | static int |
545 | asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, | 527 | asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, |
546 | const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx, int depth) | 528 | const ASN1_TEMPLATE *tt, char opt, int depth) |
547 | { | 529 | { |
548 | int flags, aclass; | 530 | int flags, aclass; |
549 | int ret; | 531 | int ret; |
@@ -574,7 +556,7 @@ asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, | |||
574 | } | 556 | } |
575 | /* Get the tag */ | 557 | /* Get the tag */ |
576 | ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, | 558 | ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, |
577 | &p, len, sktag, skaclass, opt, ctx); | 559 | &p, len, sktag, skaclass, opt); |
578 | if (!ret) { | 560 | if (!ret) { |
579 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 561 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
580 | return 0; | 562 | return 0; |
@@ -615,7 +597,7 @@ asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, | |||
615 | } | 597 | } |
616 | skfield = NULL; | 598 | skfield = NULL; |
617 | if (!asn1_item_ex_d2i(&skfield, &p, len, | 599 | if (!asn1_item_ex_d2i(&skfield, &p, len, |
618 | tt->item, -1, 0, 0, ctx, depth)) { | 600 | tt->item, -1, 0, 0, depth)) { |
619 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 601 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
620 | goto err; | 602 | goto err; |
621 | } | 603 | } |
@@ -633,7 +615,7 @@ asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, | |||
633 | } else if (flags & ASN1_TFLG_IMPTAG) { | 615 | } else if (flags & ASN1_TFLG_IMPTAG) { |
634 | /* IMPLICIT tagging */ | 616 | /* IMPLICIT tagging */ |
635 | ret = asn1_item_ex_d2i(val, &p, len, | 617 | ret = asn1_item_ex_d2i(val, &p, len, |
636 | tt->item, tt->tag, aclass, opt, ctx, depth); | 618 | tt->item, tt->tag, aclass, opt, depth); |
637 | if (!ret) { | 619 | if (!ret) { |
638 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 620 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
639 | goto err; | 621 | goto err; |
@@ -642,7 +624,7 @@ asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, | |||
642 | } else { | 624 | } else { |
643 | /* Nothing special */ | 625 | /* Nothing special */ |
644 | ret = asn1_item_ex_d2i(val, &p, len, tt->item, | 626 | ret = asn1_item_ex_d2i(val, &p, len, tt->item, |
645 | -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx, depth); | 627 | -1, tt->flags & ASN1_TFLG_COMBINE, opt, depth); |
646 | if (!ret) { | 628 | if (!ret) { |
647 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 629 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
648 | goto err; | 630 | goto err; |
@@ -660,7 +642,7 @@ asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, | |||
660 | 642 | ||
661 | static int | 643 | static int |
662 | asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, | 644 | asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, |
663 | const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx) | 645 | const ASN1_ITEM *it, int tag, int aclass, char opt) |
664 | { | 646 | { |
665 | int ret = 0, utype; | 647 | int ret = 0, utype; |
666 | long plen; | 648 | long plen; |
@@ -699,7 +681,7 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, | |||
699 | } | 681 | } |
700 | p = *in; | 682 | p = *in; |
701 | ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, | 683 | ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, |
702 | &p, inlen, -1, 0, 0, ctx); | 684 | &p, inlen, -1, 0, 0); |
703 | if (!ret) { | 685 | if (!ret) { |
704 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 686 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
705 | return 0; | 687 | return 0; |
@@ -714,7 +696,7 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, | |||
714 | p = *in; | 696 | p = *in; |
715 | /* Check header */ | 697 | /* Check header */ |
716 | ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, | 698 | ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, |
717 | &p, inlen, tag, aclass, opt, ctx); | 699 | &p, inlen, tag, aclass, opt); |
718 | if (!ret) { | 700 | if (!ret) { |
719 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 701 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
720 | return 0; | 702 | return 0; |
@@ -724,12 +706,7 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, | |||
724 | /* SEQUENCE, SET and "OTHER" are left in encoded form */ | 706 | /* SEQUENCE, SET and "OTHER" are left in encoded form */ |
725 | if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || | 707 | if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || |
726 | (utype == V_ASN1_OTHER)) { | 708 | (utype == V_ASN1_OTHER)) { |
727 | /* Clear context cache for type OTHER because the auto clear | 709 | if (utype != V_ASN1_OTHER && !cst) { |
728 | * when we have a exact match wont work | ||
729 | */ | ||
730 | if (utype == V_ASN1_OTHER) { | ||
731 | asn1_tlc_invalidate(ctx); | ||
732 | } else if (!cst) { | ||
733 | /* SEQUENCE and SET must be constructed */ | 710 | /* SEQUENCE and SET must be constructed */ |
734 | ASN1error(ASN1_R_TYPE_NOT_CONSTRUCTED); | 711 | ASN1error(ASN1_R_TYPE_NOT_CONSTRUCTED); |
735 | return 0; | 712 | return 0; |
@@ -964,7 +941,7 @@ asn1_find_end(const unsigned char **in, long len, char inf) | |||
964 | q = p; | 941 | q = p; |
965 | /* Just read in a header: only care about the length */ | 942 | /* Just read in a header: only care about the length */ |
966 | if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len, | 943 | if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len, |
967 | -1, 0, 0, NULL)) { | 944 | -1, 0, 0)) { |
968 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 945 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
969 | return 0; | 946 | return 0; |
970 | } | 947 | } |
@@ -1027,7 +1004,7 @@ asn1_collect(CBB *cbb, const unsigned char **in, long len, char inf, | |||
1027 | } | 1004 | } |
1028 | 1005 | ||
1029 | if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, | 1006 | if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, |
1030 | len, tag, aclass, 0, NULL)) { | 1007 | len, tag, aclass, 0)) { |
1031 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 1008 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
1032 | return 0; | 1009 | return 0; |
1033 | } | 1010 | } |
@@ -1079,7 +1056,7 @@ asn1_check_eoc(const unsigned char **in, long len) | |||
1079 | static int | 1056 | static int |
1080 | asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, | 1057 | asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, |
1081 | char *cst, const unsigned char **in, long len, int exptag, int expclass, | 1058 | char *cst, const unsigned char **in, long len, int exptag, int expclass, |
1082 | char opt, ASN1_TLC *ctx) | 1059 | char opt) |
1083 | { | 1060 | { |
1084 | int i; | 1061 | int i; |
1085 | int ptag, pclass; | 1062 | int ptag, pclass; |
@@ -1089,35 +1066,9 @@ asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, | |||
1089 | p = *in; | 1066 | p = *in; |
1090 | q = p; | 1067 | q = p; |
1091 | 1068 | ||
1092 | if (ctx && ctx->valid) { | 1069 | i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); |
1093 | i = ctx->ret; | ||
1094 | plen = ctx->plen; | ||
1095 | pclass = ctx->pclass; | ||
1096 | ptag = ctx->ptag; | ||
1097 | p += ctx->hdrlen; | ||
1098 | } else { | ||
1099 | i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); | ||
1100 | if (ctx) { | ||
1101 | ctx->ret = i; | ||
1102 | ctx->plen = plen; | ||
1103 | ctx->pclass = pclass; | ||
1104 | ctx->ptag = ptag; | ||
1105 | ctx->hdrlen = p - q; | ||
1106 | ctx->valid = 1; | ||
1107 | /* If definite length, and no error, length + | ||
1108 | * header can't exceed total amount of data available. | ||
1109 | */ | ||
1110 | if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) { | ||
1111 | ASN1error(ASN1_R_TOO_LONG); | ||
1112 | asn1_tlc_invalidate(ctx); | ||
1113 | return 0; | ||
1114 | } | ||
1115 | } | ||
1116 | } | ||
1117 | |||
1118 | if (i & 0x80) { | 1070 | if (i & 0x80) { |
1119 | ASN1error(ASN1_R_BAD_OBJECT_HEADER); | 1071 | ASN1error(ASN1_R_BAD_OBJECT_HEADER); |
1120 | asn1_tlc_invalidate(ctx); | ||
1121 | return 0; | 1072 | return 0; |
1122 | } | 1073 | } |
1123 | if (exptag >= 0) { | 1074 | if (exptag >= 0) { |
@@ -1127,13 +1078,9 @@ asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, | |||
1127 | */ | 1078 | */ |
1128 | if (opt) | 1079 | if (opt) |
1129 | return -1; | 1080 | return -1; |
1130 | asn1_tlc_invalidate(ctx); | ||
1131 | ASN1error(ASN1_R_WRONG_TAG); | 1081 | ASN1error(ASN1_R_WRONG_TAG); |
1132 | return 0; | 1082 | return 0; |
1133 | } | 1083 | } |
1134 | /* We have a tag and class match: | ||
1135 | * assume we are going to do something with it */ | ||
1136 | asn1_tlc_invalidate(ctx); | ||
1137 | } | 1084 | } |
1138 | 1085 | ||
1139 | if (i & 1) | 1086 | if (i & 1) |