diff options
Diffstat (limited to 'src')
| -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) |
