summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/asn1/tasn_dec.c183
1 files changed, 125 insertions, 58 deletions
diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c
index de0b819064..f3e032c1c1 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.62 2022/05/10 05:19:22 jsing Exp $ */ 1/* $OpenBSD: tasn_dec.c,v 1.63 2022/05/10 18:40:06 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,13 +83,16 @@ static int asn1_collect(CBB *cbb, CBS *cbs, char indefinite, int expected_tag,
83 int expected_class, int depth); 83 int expected_class, int depth);
84 84
85static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, 85static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
86 long len, const ASN1_ITEM *it, int tag, int aclass, char opt, int depth); 86 long len, const ASN1_ITEM *it, int tag_number, int tag_class, char optional,
87 int depth);
88static int asn1_template_ex_d2i_cbs(ASN1_VALUE **pval, CBS *cbs,
89 const ASN1_TEMPLATE *tt, char optional, int depth);
87static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, 90static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
88 long len, const ASN1_TEMPLATE *tt, char opt, int depth); 91 long len, const ASN1_TEMPLATE *tt, char opt, int depth);
89static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, 92static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in,
90 long len, const ASN1_TEMPLATE *tt, char opt, int depth); 93 long len, const ASN1_TEMPLATE *tt, char opt, int depth);
91static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, 94static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, CBS *cbs,
92 long len, const ASN1_ITEM *it, int tag, int aclass, char opt); 95 const ASN1_ITEM *it, int tag_number, int tag_class, char optional);
93static int asn1_ex_c2i(ASN1_VALUE **pval, CBS *content, int utype, 96static int asn1_ex_c2i(ASN1_VALUE **pval, CBS *content, int utype,
94 const ASN1_ITEM *it); 97 const ASN1_ITEM *it);
95 98
@@ -218,6 +221,26 @@ asn1_item_ex_d2i_choice(ASN1_VALUE **pval, const unsigned char **in, long len,
218} 221}
219 222
220static int 223static int
224asn1_item_ex_d2i_choice_cbs(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it,
225 int tag_number, int tag_class, char optional, int depth)
226{
227 const unsigned char *p;
228 int ret;
229
230 if (CBS_len(cbs) > LONG_MAX)
231 return 0;
232
233 p = CBS_data(cbs);
234 ret = asn1_item_ex_d2i_choice(pval, &p, (long)CBS_len(cbs), it,
235 tag_number, tag_class, optional, depth);
236 if (ret == 1) {
237 if (!CBS_skip(cbs, p - CBS_data(cbs)))
238 return 0;
239 }
240 return ret;
241}
242
243static int
221asn1_item_ex_d2i_sequence(ASN1_VALUE **pval, const unsigned char **in, long len, 244asn1_item_ex_d2i_sequence(ASN1_VALUE **pval, const unsigned char **in, long len,
222 const ASN1_ITEM *it, int tag, int aclass, char opt, int depth) 245 const ASN1_ITEM *it, int tag, int aclass, char opt, int depth)
223{ 246{
@@ -390,22 +413,43 @@ asn1_item_ex_d2i_sequence(ASN1_VALUE **pval, const unsigned char **in, long len,
390 return 0; 413 return 0;
391} 414}
392 415
416static int
417asn1_item_ex_d2i_sequence_cbs(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it,
418 int tag_number, int tag_class, char optional, int depth)
419{
420 const unsigned char *p;
421 int ret;
422
423 if (CBS_len(cbs) > LONG_MAX)
424 return 0;
425
426 p = CBS_data(cbs);
427 ret = asn1_item_ex_d2i_sequence(pval, &p, (long)CBS_len(cbs), it,
428 tag_number, tag_class, optional, depth);
429 if (ret == 1) {
430 if (!CBS_skip(cbs, p - CBS_data(cbs)))
431 return 0;
432 }
433 return ret;
434}
435
393/* 436/*
394 * Decode an item, taking care of IMPLICIT tagging, if any. 437 * Decode an item, taking care of IMPLICIT tagging, if any.
395 * If 'opt' set and tag mismatch return -1 to handle OPTIONAL 438 * If 'opt' set and tag mismatch return -1 to handle OPTIONAL
396 */ 439 */
397static int 440static int
398asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, 441asn1_item_ex_d2i_cbs(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it,
399 const ASN1_ITEM *it, int tag, int aclass, char opt, int depth) 442 int tag_number, int tag_class, char optional, int depth)
400{ 443{
401 const ASN1_EXTERN_FUNCS *ef; 444 const ASN1_EXTERN_FUNCS *ef = it->funcs;
402 ASN1_TLC ctx = { 0 };
403 const unsigned char *p = NULL; 445 const unsigned char *p = NULL;
446 ASN1_TLC ctx = { 0 };
447 CBS cbs_mstring;
404 unsigned char oclass; 448 unsigned char oclass;
405 int otag; 449 int otag;
406 int ret = 0; 450 int ret = 0;
407 451
408 if (!pval) 452 if (pval == NULL)
409 return 0; 453 return 0;
410 454
411 if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { 455 if (++depth > ASN1_MAX_CONSTRUCTED_NEST) {
@@ -415,23 +459,23 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
415 459
416 switch (it->itype) { 460 switch (it->itype) {
417 case ASN1_ITYPE_PRIMITIVE: 461 case ASN1_ITYPE_PRIMITIVE:
418 if (it->templates) { 462 if (it->templates != NULL) {
419 /* tagging or OPTIONAL is currently illegal on an item 463 /*
464 * Tagging or OPTIONAL is currently illegal on an item
420 * template because the flags can't get passed down. 465 * template because the flags can't get passed down.
421 * In practice this isn't a problem: we include the 466 * In practice this isn't a problem: we include the
422 * relevant flags from the item template in the 467 * relevant flags from the item template in the
423 * template itself. 468 * template itself.
424 */ 469 */
425 if ((tag != -1) || opt) { 470 if (tag_number != -1 || optional) {
426 ASN1error(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); 471 ASN1error(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
427 goto err; 472 goto err;
428 } 473 }
429 return asn1_template_ex_d2i(pval, in, len, 474 return asn1_template_ex_d2i_cbs(pval, cbs,
430 it->templates, opt, depth); 475 it->templates, optional, depth);
431 } 476 }
432 return asn1_d2i_ex_primitive(pval, in, len, it, 477 return asn1_d2i_ex_primitive(pval, cbs, it, tag_number,
433 tag, aclass, opt); 478 tag_class, optional);
434 break;
435 479
436 case ASN1_ITYPE_MSTRING: 480 case ASN1_ITYPE_MSTRING:
437 /* 481 /*
@@ -439,52 +483,54 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
439 * tagging, so if tag != -1, then this looks like an error in 483 * tagging, so if tag != -1, then this looks like an error in
440 * the template. 484 * the template.
441 */ 485 */
442 if (tag != -1) { 486 if (tag_number != -1) {
443 ASN1error(ASN1_R_BAD_TEMPLATE); 487 ASN1error(ASN1_R_BAD_TEMPLATE);
444 goto err; 488 goto err;
445 } 489 }
446 490
447 p = *in; 491 /* XXX - avoid reading the header twice for MSTRING. */
448 /* Just read in tag and class */ 492 CBS_dup(cbs, &cbs_mstring);
449 ret = asn1_check_tag(NULL, &otag, &oclass, NULL, NULL, &p, len, 493 if (asn1_check_tag_cbs(&cbs_mstring, NULL, &otag, &oclass,
450 -1, 0, 1); 494 NULL, NULL, -1, 0, 1) != 1) {
451 if (!ret) {
452 ASN1error(ERR_R_NESTED_ASN1_ERROR); 495 ASN1error(ERR_R_NESTED_ASN1_ERROR);
453 goto err; 496 goto err;
454 } 497 }
455 498
456 /* Must be UNIVERSAL class */ 499 /* Must be UNIVERSAL class */
457 if (oclass != V_ASN1_UNIVERSAL) { 500 if (oclass != V_ASN1_UNIVERSAL) {
458 /* If OPTIONAL, assume this is OK */ 501 if (optional)
459 if (opt)
460 return -1; 502 return -1;
461 ASN1error(ASN1_R_MSTRING_NOT_UNIVERSAL); 503 ASN1error(ASN1_R_MSTRING_NOT_UNIVERSAL);
462 goto err; 504 goto err;
463 } 505 }
464 /* Check tag matches bit map */ 506 /* Check tag matches bit map */
465 if (!(ASN1_tag2bit(otag) & it->utype)) { 507 if (!(ASN1_tag2bit(otag) & it->utype)) {
466 /* If OPTIONAL, assume this is OK */ 508 if (optional)
467 if (opt)
468 return -1; 509 return -1;
469 ASN1error(ASN1_R_MSTRING_WRONG_TAG); 510 ASN1error(ASN1_R_MSTRING_WRONG_TAG);
470 goto err; 511 goto err;
471 } 512 }
472 return asn1_d2i_ex_primitive(pval, in, len, 513 return asn1_d2i_ex_primitive(pval, cbs, it, otag, 0, 0);
473 it, otag, 0, 0);
474 514
475 case ASN1_ITYPE_EXTERN: 515 case ASN1_ITYPE_EXTERN:
476 /* Use new style d2i */ 516 if (CBS_len(cbs) > LONG_MAX)
477 ef = it->funcs; 517 return 0;
478 return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, &ctx); 518 p = CBS_data(cbs);
519 if ((ret = ef->asn1_ex_d2i(pval, &p, (long)CBS_len(cbs), it,
520 tag_number, tag_class, optional, &ctx)) == 1) {
521 if (!CBS_skip(cbs, p - CBS_data(cbs)))
522 goto err;
523 }
524 return ret;
479 525
480 case ASN1_ITYPE_CHOICE: 526 case ASN1_ITYPE_CHOICE:
481 return asn1_item_ex_d2i_choice(pval, in, len, it, tag, 527 return asn1_item_ex_d2i_choice_cbs(pval, cbs, it, tag_number,
482 aclass, opt, depth); 528 tag_class, optional, depth);
483 529
484 case ASN1_ITYPE_NDEF_SEQUENCE: 530 case ASN1_ITYPE_NDEF_SEQUENCE:
485 case ASN1_ITYPE_SEQUENCE: 531 case ASN1_ITYPE_SEQUENCE:
486 return asn1_item_ex_d2i_sequence(pval, in, len, it, tag, 532 return asn1_item_ex_d2i_sequence_cbs(pval, cbs, it, tag_number,
487 aclass, opt, depth); 533 tag_class, optional, depth);
488 534
489 default: 535 default:
490 return 0; 536 return 0;
@@ -498,6 +544,28 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
498 return 0; 544 return 0;
499} 545}
500 546
547static int
548asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long inlen,
549 const ASN1_ITEM *it, int tag_number, int tag_class, char optional,
550 int depth)
551{
552 CBS cbs;
553 int ret;
554
555 if (inlen < 0)
556 return 0;
557
558 CBS_init(&cbs, *in, inlen);
559
560 ret = asn1_item_ex_d2i_cbs(pval, &cbs, it, tag_number, tag_class,
561 optional, depth);
562
563 if (ret == 1)
564 *in = CBS_data(&cbs);
565
566 return ret;
567}
568
501int 569int
502ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, 570ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
503 const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx) 571 const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
@@ -579,6 +647,26 @@ asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen,
579} 647}
580 648
581static int 649static int
650asn1_template_ex_d2i_cbs(ASN1_VALUE **pval, CBS *cbs, const ASN1_TEMPLATE *tt,
651 char optional, int depth)
652{
653 const unsigned char *p;
654 int ret;
655
656 if (CBS_len(cbs) > LONG_MAX)
657 return 0;
658
659 p = CBS_data(cbs);
660 ret = asn1_template_ex_d2i(pval, &p, (long)CBS_len(cbs), tt,
661 optional, depth);
662 if (ret == 1) {
663 if (!CBS_skip(cbs, p - CBS_data(cbs)))
664 return 0;
665 }
666 return ret;
667}
668
669static int
582asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, 670asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len,
583 const ASN1_TEMPLATE *tt, char opt, int depth) 671 const ASN1_TEMPLATE *tt, char opt, int depth)
584{ 672{
@@ -696,7 +784,7 @@ asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len,
696} 784}
697 785
698static int 786static int
699asn1_d2i_ex_primitive_cbs(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, 787asn1_d2i_ex_primitive(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it,
700 int tag_number, int tag_class, char optional) 788 int tag_number, int tag_class, char optional)
701{ 789{
702 CBS cbs_any, cbs_content, cbs_object, cbs_initial; 790 CBS cbs_any, cbs_content, cbs_object, cbs_initial;
@@ -816,27 +904,6 @@ asn1_d2i_ex_primitive_cbs(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it,
816} 904}
817 905
818static int 906static int
819asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen,
820 const ASN1_ITEM *it, int tag_number, int tag_class, char optional)
821{
822 CBS cbs;
823 int ret;
824
825 if (inlen < 0)
826 return 0;
827
828 CBS_init(&cbs, *in, inlen);
829
830 ret = asn1_d2i_ex_primitive_cbs(pval, &cbs, it, tag_number, tag_class,
831 optional);
832
833 if (ret == 1)
834 *in = CBS_data(&cbs);
835
836 return ret;
837}
838
839static int
840asn1_ex_c2i_primitive(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it) 907asn1_ex_c2i_primitive(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it)
841{ 908{
842 ASN1_STRING *stmp; 909 ASN1_STRING *stmp;