1 /* $OpenBSD: tasn_dec.c,v 1.49 2022/03/13 14:58:14 jsing Exp $ */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project 2000. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59 #include <limits.h> 60 #include <stddef.h> 61 #include <string.h> 62 63 #include <openssl/asn1.h> 64 #include <openssl/asn1t.h> 65 #include <openssl/buffer.h> 66 #include <openssl/err.h> 67 #include <openssl/objects.h> 68 69 #include "asn1_locl.h" 70 #include "bytestring.h" 71 72 /* Constructed types with a recursive definition (such as can be found in PKCS7) 73 * could eventually exceed the stack given malicious input with excessive 74 * recursion. Therefore we limit the stack depth. 75 */ 76 #define ASN1_MAX_CONSTRUCTED_NEST 30 77 78 static int asn1_check_eoc(const unsigned char **in, long len); 79 static int asn1_find_end(const unsigned char **in, long len, char inf); 80 81 static int asn1_collect(CBB *cbb, const unsigned char **in, long len, 82 char inf, int tag, int aclass, int depth); 83 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, 86 int expclass, char opt, ASN1_TLC *ctx); 87 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, 90 int depth); 91 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); 93 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); 95 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, 97 ASN1_TLC *ctx); 98 static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *content, int len, 99 int utype, const ASN1_ITEM *it); 100 101 static void 102 asn1_tlc_invalidate(ASN1_TLC *ctx) 103 { 104 if (ctx != NULL) 105 ctx->valid = 0; 106 } 107 108 ASN1_VALUE * 109 ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, 110 const ASN1_ITEM *it) 111 { 112 ASN1_VALUE *ptmpval = NULL; 113 ASN1_TLC ctx; 114 115 asn1_tlc_invalidate(&ctx); 116 117 if (pval == NULL) 118 pval = &ptmpval; 119 if (asn1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &ctx, 0) <= 0) 120 return NULL; 121 122 return *pval; 123 } 124 125 int 126 ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, 127 const ASN1_TEMPLATE *tt) 128 { 129 ASN1_TLC ctx; 130 131 asn1_tlc_invalidate(&ctx); 132 133 return asn1_template_ex_d2i(pval, in, len, tt, 0, &ctx, 0); 134 } 135 136 /* Decode an item, taking care of IMPLICIT tagging, if any. 137 * If 'opt' set and tag mismatch return -1 to handle OPTIONAL 138 */ 139 140 static int 141 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, 143 int depth) 144 { 145 const ASN1_TEMPLATE *tt, *errtt = NULL; 146 const ASN1_EXTERN_FUNCS *ef; 147 const ASN1_AUX *aux = it->funcs; 148 ASN1_aux_cb *asn1_cb = NULL; 149 const unsigned char *p = NULL, *q; 150 unsigned char oclass; 151 char seq_eoc, seq_nolen, cst, isopt; 152 long tmplen; 153 int i; 154 int otag; 155 int ret = 0; 156 ASN1_VALUE **pchptr; 157 int combine; 158 159 combine = aclass & ASN1_TFLG_COMBINE; 160 aclass &= ~ASN1_TFLG_COMBINE; 161 162 if (!pval) 163 return 0; 164 165 if (aux && aux->asn1_cb) 166 asn1_cb = aux->asn1_cb; 167 168 if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { 169 ASN1error(ASN1_R_NESTED_TOO_DEEP); 170 goto err; 171 } 172 173 switch (it->itype) { 174 case ASN1_ITYPE_PRIMITIVE: 175 if (it->templates) { 176 /* tagging or OPTIONAL is currently illegal on an item 177 * template because the flags can't get passed down. 178 * In practice this isn't a problem: we include the 179 * relevant flags from the item template in the 180 * template itself. 181 */ 182 if ((tag != -1) || opt) { 183 ASN1error(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); 184 goto err; 185 } 186 return asn1_template_ex_d2i(pval, in, len, 187 it->templates, opt, ctx, depth); 188 } 189 return asn1_d2i_ex_primitive(pval, in, len, it, 190 tag, aclass, opt, ctx); 191 break; 192 193 case ASN1_ITYPE_MSTRING: 194 /* 195 * It never makes sense for multi-strings to have implicit 196 * tagging, so if tag != -1, then this looks like an error in 197 * the template. 198 */ 199 if (tag != -1) { 200 ASN1error(ASN1_R_BAD_TEMPLATE); 201 goto err; 202 } 203 204 p = *in; 205 /* Just read in tag and class */ 206 ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, 207 &p, len, -1, 0, 1, ctx); 208 if (!ret) { 209 ASN1error(ERR_R_NESTED_ASN1_ERROR); 210 goto err; 211 } 212 213 /* Must be UNIVERSAL class */ 214 if (oclass != V_ASN1_UNIVERSAL) { 215 /* If OPTIONAL, assume this is OK */ 216 if (opt) 217 return -1; 218 ASN1error(ASN1_R_MSTRING_NOT_UNIVERSAL); 219 goto err; 220 } 221 /* Check tag matches bit map */ 222 if (!(ASN1_tag2bit(otag) & it->utype)) { 223 /* If OPTIONAL, assume this is OK */ 224 if (opt) 225 return -1; 226 ASN1error(ASN1_R_MSTRING_WRONG_TAG); 227 goto err; 228 } 229 return asn1_d2i_ex_primitive(pval, in, len, 230 it, otag, 0, 0, ctx); 231 232 case ASN1_ITYPE_EXTERN: 233 /* Use new style d2i */ 234 ef = it->funcs; 235 return ef->asn1_ex_d2i(pval, in, len, 236 it, tag, aclass, opt, ctx); 237 238 case ASN1_ITYPE_CHOICE: 239 /* 240 * It never makes sense for CHOICE types to have implicit 241 * tagging, so if tag != -1, then this looks like an error in 242 * the template. 243 */ 244 if (tag != -1) { 245 ASN1error(ASN1_R_BAD_TEMPLATE); 246 goto err; 247 } 248 249 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) 250 goto auxerr; 251 252 if (*pval) { 253 /* Free up and zero CHOICE value if initialised */ 254 i = asn1_get_choice_selector(pval, it); 255 if ((i >= 0) && (i < it->tcount)) { 256 tt = it->templates + i; 257 pchptr = asn1_get_field_ptr(pval, tt); 258 ASN1_template_free(pchptr, tt); 259 asn1_set_choice_selector(pval, -1, it); 260 } 261 } else if (!ASN1_item_ex_new(pval, it)) { 262 ASN1error(ERR_R_NESTED_ASN1_ERROR); 263 goto err; 264 } 265 /* CHOICE type, try each possibility in turn */ 266 p = *in; 267 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { 268 pchptr = asn1_get_field_ptr(pval, tt); 269 /* We mark field as OPTIONAL so its absence 270 * can be recognised. 271 */ 272 ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, 273 depth); 274 /* If field not present, try the next one */ 275 if (ret == -1) 276 continue; 277 /* If positive return, read OK, break loop */ 278 if (ret > 0) 279 break; 280 /* Otherwise must be an ASN1 parsing error */ 281 errtt = tt; 282 ASN1error(ERR_R_NESTED_ASN1_ERROR); 283 goto err; 284 } 285 286 /* Did we fall off the end without reading anything? */ 287 if (i == it->tcount) { 288 /* If OPTIONAL, this is OK */ 289 if (opt) { 290 /* Free and zero it */ 291 ASN1_item_ex_free(pval, it); 292 return -1; 293 } 294 ASN1error(ASN1_R_NO_MATCHING_CHOICE_TYPE); 295 goto err; 296 } 297 298 asn1_set_choice_selector(pval, i, it); 299 *in = p; 300 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) 301 goto auxerr; 302 return 1; 303 304 case ASN1_ITYPE_NDEF_SEQUENCE: 305 case ASN1_ITYPE_SEQUENCE: 306 p = *in; 307 tmplen = len; 308 309 /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ 310 if (tag == -1) { 311 tag = V_ASN1_SEQUENCE; 312 aclass = V_ASN1_UNIVERSAL; 313 } 314 /* Get SEQUENCE length and update len, p */ 315 ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, 316 &p, len, tag, aclass, opt, ctx); 317 if (!ret) { 318 ASN1error(ERR_R_NESTED_ASN1_ERROR); 319 goto err; 320 } else if (ret == -1) 321 return -1; 322 if (aux && (aux->flags & ASN1_AFLG_BROKEN)) { 323 len = tmplen - (p - *in); 324 seq_nolen = 1; 325 } 326 /* If indefinite we don't do a length check */ 327 else 328 seq_nolen = seq_eoc; 329 if (!cst) { 330 ASN1error(ASN1_R_SEQUENCE_NOT_CONSTRUCTED); 331 goto err; 332 } 333 334 if (!*pval && !ASN1_item_ex_new(pval, it)) { 335 ASN1error(ERR_R_NESTED_ASN1_ERROR); 336 goto err; 337 } 338 339 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) 340 goto auxerr; 341 342 /* Free up and zero any ADB found */ 343 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { 344 if (tt->flags & ASN1_TFLG_ADB_MASK) { 345 const ASN1_TEMPLATE *seqtt; 346 ASN1_VALUE **pseqval; 347 seqtt = asn1_do_adb(pval, tt, 1); 348 if (!seqtt) 349 goto err; 350 pseqval = asn1_get_field_ptr(pval, seqtt); 351 ASN1_template_free(pseqval, seqtt); 352 } 353 } 354 355 /* Get each field entry */ 356 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { 357 const ASN1_TEMPLATE *seqtt; 358 ASN1_VALUE **pseqval; 359 seqtt = asn1_do_adb(pval, tt, 1); 360 if (!seqtt) 361 goto err; 362 pseqval = asn1_get_field_ptr(pval, seqtt); 363 /* Have we ran out of data? */ 364 if (!len) 365 break; 366 q = p; 367 if (asn1_check_eoc(&p, len)) { 368 if (!seq_eoc) { 369 ASN1error(ASN1_R_UNEXPECTED_EOC); 370 goto err; 371 } 372 len -= p - q; 373 seq_eoc = 0; 374 q = p; 375 break; 376 } 377 /* This determines the OPTIONAL flag value. The field 378 * cannot be omitted if it is the last of a SEQUENCE 379 * and there is still data to be read. This isn't 380 * strictly necessary but it increases efficiency in 381 * some cases. 382 */ 383 if (i == (it->tcount - 1)) 384 isopt = 0; 385 else 386 isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); 387 /* attempt to read in field, allowing each to be 388 * OPTIONAL */ 389 390 ret = asn1_template_ex_d2i(pseqval, &p, len, 391 seqtt, isopt, ctx, depth); 392 if (!ret) { 393 errtt = seqtt; 394 goto err; 395 } else if (ret == -1) { 396 /* OPTIONAL component absent. 397 * Free and zero the field. 398 */ 399 ASN1_template_free(pseqval, seqtt); 400 continue; 401 } 402 /* Update length */ 403 len -= p - q; 404 } 405 406 /* Check for EOC if expecting one */ 407 if (seq_eoc && !asn1_check_eoc(&p, len)) { 408 ASN1error(ASN1_R_MISSING_EOC); 409 goto err; 410 } 411 /* Check all data read */ 412 if (!seq_nolen && len) { 413 ASN1error(ASN1_R_SEQUENCE_LENGTH_MISMATCH); 414 goto err; 415 } 416 417 /* If we get here we've got no more data in the SEQUENCE, 418 * however we may not have read all fields so check all 419 * remaining are OPTIONAL and clear any that are. 420 */ 421 for (; i < it->tcount; tt++, i++) { 422 const ASN1_TEMPLATE *seqtt; 423 seqtt = asn1_do_adb(pval, tt, 1); 424 if (!seqtt) 425 goto err; 426 if (seqtt->flags & ASN1_TFLG_OPTIONAL) { 427 ASN1_VALUE **pseqval; 428 pseqval = asn1_get_field_ptr(pval, seqtt); 429 ASN1_template_free(pseqval, seqtt); 430 } else { 431 errtt = seqtt; 432 ASN1error(ASN1_R_FIELD_MISSING); 433 goto err; 434 } 435 } 436 /* Save encoding */ 437 if (!asn1_enc_save(pval, *in, p - *in, it)) { 438 ASN1error(ERR_R_MALLOC_FAILURE); 439 goto auxerr; 440 } 441 *in = p; 442 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) 443 goto auxerr; 444 return 1; 445 446 default: 447 return 0; 448 } 449 450 auxerr: 451 ASN1error(ASN1_R_AUX_ERROR); 452 err: 453 if (combine == 0) 454 ASN1_item_ex_free(pval, it); 455 if (errtt) 456 ERR_asprintf_error_data("Field=%s, Type=%s", errtt->field_name, 457 it->sname); 458 else 459 ERR_asprintf_error_data("Type=%s", it->sname); 460 return 0; 461 } 462 463 int 464 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) 466 { 467 return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); 468 } 469 470 /* Templates are handled with two separate functions. 471 * One handles any EXPLICIT tag and the other handles the rest. 472 */ 473 474 static int 475 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) 477 { 478 int flags, aclass; 479 int ret; 480 long len; 481 const unsigned char *p, *q; 482 char exp_eoc; 483 484 if (!val) 485 return 0; 486 flags = tt->flags; 487 aclass = flags & ASN1_TFLG_TAG_CLASS; 488 489 p = *in; 490 491 /* Check if EXPLICIT tag expected */ 492 if (flags & ASN1_TFLG_EXPTAG) { 493 char cst; 494 /* Need to work out amount of data available to the inner 495 * content and where it starts: so read in EXPLICIT header to 496 * get the info. 497 */ 498 ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, 499 &p, inlen, tt->tag, aclass, opt, ctx); 500 q = p; 501 if (!ret) { 502 ASN1error(ERR_R_NESTED_ASN1_ERROR); 503 return 0; 504 } else if (ret == -1) 505 return -1; 506 if (!cst) { 507 ASN1error(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); 508 return 0; 509 } 510 /* 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); 512 if (!ret) { 513 ASN1error(ERR_R_NESTED_ASN1_ERROR); 514 return 0; 515 } 516 /* We read the field in OK so update length */ 517 len -= p - q; 518 if (exp_eoc) { 519 /* If NDEF we must have an EOC here */ 520 if (!asn1_check_eoc(&p, len)) { 521 ASN1error(ASN1_R_MISSING_EOC); 522 goto err; 523 } 524 } else { 525 /* Otherwise we must hit the EXPLICIT tag end or its 526 * an error */ 527 if (len) { 528 ASN1error(ASN1_R_EXPLICIT_LENGTH_MISMATCH); 529 goto err; 530 } 531 } 532 } else 533 return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, 534 depth); 535 536 *in = p; 537 return 1; 538 539 err: 540 ASN1_template_free(val, tt); 541 return 0; 542 } 543 544 static int 545 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) 547 { 548 int flags, aclass; 549 int ret; 550 const unsigned char *p, *q; 551 552 if (!val) 553 return 0; 554 flags = tt->flags; 555 aclass = flags & ASN1_TFLG_TAG_CLASS; 556 557 p = *in; 558 q = p; 559 560 if (flags & ASN1_TFLG_SK_MASK) { 561 /* SET OF, SEQUENCE OF */ 562 int sktag, skaclass; 563 char sk_eoc; 564 /* First work out expected inner tag value */ 565 if (flags & ASN1_TFLG_IMPTAG) { 566 sktag = tt->tag; 567 skaclass = aclass; 568 } else { 569 skaclass = V_ASN1_UNIVERSAL; 570 if (flags & ASN1_TFLG_SET_OF) 571 sktag = V_ASN1_SET; 572 else 573 sktag = V_ASN1_SEQUENCE; 574 } 575 /* Get the tag */ 576 ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, 577 &p, len, sktag, skaclass, opt, ctx); 578 if (!ret) { 579 ASN1error(ERR_R_NESTED_ASN1_ERROR); 580 return 0; 581 } else if (ret == -1) 582 return -1; 583 if (!*val) 584 *val = (ASN1_VALUE *)sk_new_null(); 585 else { 586 /* We've got a valid STACK: free up any items present */ 587 STACK_OF(ASN1_VALUE) *sktmp = 588 (STACK_OF(ASN1_VALUE) *)*val; 589 ASN1_VALUE *vtmp; 590 while (sk_ASN1_VALUE_num(sktmp) > 0) { 591 vtmp = sk_ASN1_VALUE_pop(sktmp); 592 ASN1_item_ex_free(&vtmp, 593 tt->item); 594 } 595 } 596 597 if (!*val) { 598 ASN1error(ERR_R_MALLOC_FAILURE); 599 goto err; 600 } 601 602 /* Read as many items as we can */ 603 while (len > 0) { 604 ASN1_VALUE *skfield; 605 q = p; 606 /* See if EOC found */ 607 if (asn1_check_eoc(&p, len)) { 608 if (!sk_eoc) { 609 ASN1error(ASN1_R_UNEXPECTED_EOC); 610 goto err; 611 } 612 len -= p - q; 613 sk_eoc = 0; 614 break; 615 } 616 skfield = NULL; 617 if (!asn1_item_ex_d2i(&skfield, &p, len, 618 tt->item, -1, 0, 0, ctx, depth)) { 619 ASN1error(ERR_R_NESTED_ASN1_ERROR); 620 goto err; 621 } 622 len -= p - q; 623 if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, 624 skfield)) { 625 ASN1error(ERR_R_MALLOC_FAILURE); 626 goto err; 627 } 628 } 629 if (sk_eoc) { 630 ASN1error(ASN1_R_MISSING_EOC); 631 goto err; 632 } 633 } else if (flags & ASN1_TFLG_IMPTAG) { 634 /* IMPLICIT tagging */ 635 ret = asn1_item_ex_d2i(val, &p, len, 636 tt->item, tt->tag, aclass, opt, ctx, depth); 637 if (!ret) { 638 ASN1error(ERR_R_NESTED_ASN1_ERROR); 639 goto err; 640 } else if (ret == -1) 641 return -1; 642 } else { 643 /* Nothing special */ 644 ret = asn1_item_ex_d2i(val, &p, len, tt->item, 645 -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx, depth); 646 if (!ret) { 647 ASN1error(ERR_R_NESTED_ASN1_ERROR); 648 goto err; 649 } else if (ret == -1) 650 return -1; 651 } 652 653 *in = p; 654 return 1; 655 656 err: 657 ASN1_template_free(val, tt); 658 return 0; 659 } 660 661 static int 662 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) 664 { 665 int ret = 0, utype; 666 long plen; 667 char cst, inf; 668 const unsigned char *p; 669 const unsigned char *content = NULL; 670 uint8_t *data = NULL; 671 size_t data_len = 0; 672 CBB cbb; 673 long len; 674 675 memset(&cbb, 0, sizeof(cbb)); 676 677 if (!pval) { 678 ASN1error(ASN1_R_ILLEGAL_NULL); 679 return 0; /* Should never happen */ 680 } 681 682 if (it->itype == ASN1_ITYPE_MSTRING) { 683 utype = tag; 684 tag = -1; 685 } else 686 utype = it->utype; 687 688 if (utype == V_ASN1_ANY) { 689 /* If type is ANY need to figure out type from tag */ 690 unsigned char oclass; 691 if (tag >= 0) { 692 ASN1error(ASN1_R_ILLEGAL_TAGGED_ANY); 693 return 0; 694 } 695 if (opt) { 696 ASN1error(ASN1_R_ILLEGAL_OPTIONAL_ANY); 697 return 0; 698 } 699 p = *in; 700 ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, 701 &p, inlen, -1, 0, 0, ctx); 702 if (!ret) { 703 ASN1error(ERR_R_NESTED_ASN1_ERROR); 704 return 0; 705 } 706 if (oclass != V_ASN1_UNIVERSAL) 707 utype = V_ASN1_OTHER; 708 } 709 if (tag == -1) { 710 tag = utype; 711 aclass = V_ASN1_UNIVERSAL; 712 } 713 p = *in; 714 /* Check header */ 715 ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, 716 &p, inlen, tag, aclass, opt, ctx); 717 if (!ret) { 718 ASN1error(ERR_R_NESTED_ASN1_ERROR); 719 return 0; 720 } else if (ret == -1) 721 return -1; 722 ret = 0; 723 /* SEQUENCE, SET and "OTHER" are left in encoded form */ 724 if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || 725 (utype == V_ASN1_OTHER)) { 726 /* Clear context cache for type OTHER because the auto clear 727 * when we have a exact match wont work 728 */ 729 if (utype == V_ASN1_OTHER) { 730 asn1_tlc_invalidate(ctx); 731 } else if (!cst) { 732 /* SEQUENCE and SET must be constructed */ 733 ASN1error(ASN1_R_TYPE_NOT_CONSTRUCTED); 734 return 0; 735 } 736 737 content = *in; 738 /* If indefinite length constructed find the real end */ 739 if (inf) { 740 if (!asn1_find_end(&p, plen, inf)) 741 goto err; 742 len = p - content; 743 } else { 744 len = p - content + plen; 745 p += plen; 746 } 747 } else if (cst) { 748 /* 749 * Should really check the internal tags are correct but 750 * some things may get this wrong. The relevant specs 751 * say that constructed string types should be OCTET STRINGs 752 * internally irrespective of the type. So instead just check 753 * for UNIVERSAL class and ignore the tag. 754 */ 755 if (!CBB_init(&cbb, 0)) 756 goto err; 757 if (!asn1_collect(&cbb, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) 758 goto err; 759 if (!CBB_finish(&cbb, &data, &data_len)) 760 goto err; 761 762 if (data_len > LONG_MAX) 763 goto err; 764 765 content = data; 766 len = data_len; 767 } else { 768 content = p; 769 len = plen; 770 p += plen; 771 } 772 773 /* We now have content length and type: translate into a structure */ 774 if (!asn1_ex_c2i(pval, content, len, utype, it)) 775 goto err; 776 777 *in = p; 778 ret = 1; 779 780 err: 781 CBB_cleanup(&cbb); 782 freezero(data, data_len); 783 784 return ret; 785 } 786 787 /* Translate ASN1 content octets into a structure */ 788 789 static int 790 asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *content, int len, int utype, 791 const ASN1_ITEM *it) 792 { 793 ASN1_VALUE **opval = NULL; 794 ASN1_STRING *stmp; 795 ASN1_TYPE *typ = NULL; 796 ASN1_INTEGER **tint; 797 int ret = 0; 798 799 if (it->funcs != NULL) { 800 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 801 char free_content = 0; 802 803 if (pf->prim_c2i == NULL) 804 return 0; 805 return pf->prim_c2i(pval, content, len, utype, &free_content, it); 806 } 807 808 /* If ANY type clear type and set pointer to internal value */ 809 if (it->utype == V_ASN1_ANY) { 810 if (!*pval) { 811 typ = ASN1_TYPE_new(); 812 if (typ == NULL) 813 goto err; 814 *pval = (ASN1_VALUE *)typ; 815 } else 816 typ = (ASN1_TYPE *)*pval; 817 818 if (utype != typ->type) 819 ASN1_TYPE_set(typ, utype, NULL); 820 opval = pval; 821 pval = &typ->value.asn1_value; 822 } 823 switch (utype) { 824 case V_ASN1_OBJECT: 825 if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &content, len)) 826 goto err; 827 break; 828 829 case V_ASN1_NULL: 830 if (len) { 831 ASN1error(ASN1_R_NULL_IS_WRONG_LENGTH); 832 goto err; 833 } 834 *pval = (ASN1_VALUE *)1; 835 break; 836 837 case V_ASN1_BOOLEAN: 838 if (len != 1) { 839 ASN1error(ASN1_R_BOOLEAN_IS_WRONG_LENGTH); 840 goto err; 841 } else { 842 ASN1_BOOLEAN *tbool; 843 tbool = (ASN1_BOOLEAN *)pval; 844 *tbool = *content; 845 } 846 break; 847 848 case V_ASN1_BIT_STRING: 849 if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &content, len)) 850 goto err; 851 break; 852 853 case V_ASN1_INTEGER: 854 case V_ASN1_ENUMERATED: 855 tint = (ASN1_INTEGER **)pval; 856 if (!c2i_ASN1_INTEGER(tint, &content, len)) 857 goto err; 858 /* Fixup type to match the expected form */ 859 (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); 860 break; 861 862 case V_ASN1_OCTET_STRING: 863 case V_ASN1_NUMERICSTRING: 864 case V_ASN1_PRINTABLESTRING: 865 case V_ASN1_T61STRING: 866 case V_ASN1_VIDEOTEXSTRING: 867 case V_ASN1_IA5STRING: 868 case V_ASN1_UTCTIME: 869 case V_ASN1_GENERALIZEDTIME: 870 case V_ASN1_GRAPHICSTRING: 871 case V_ASN1_VISIBLESTRING: 872 case V_ASN1_GENERALSTRING: 873 case V_ASN1_UNIVERSALSTRING: 874 case V_ASN1_BMPSTRING: 875 case V_ASN1_UTF8STRING: 876 case V_ASN1_OTHER: 877 case V_ASN1_SET: 878 case V_ASN1_SEQUENCE: 879 default: 880 if (utype == V_ASN1_BMPSTRING && (len & 1)) { 881 ASN1error(ASN1_R_BMPSTRING_IS_WRONG_LENGTH); 882 goto err; 883 } 884 if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) { 885 ASN1error(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); 886 goto err; 887 } 888 /* All based on ASN1_STRING and handled the same way. */ 889 if (*pval == NULL) { 890 if ((stmp = ASN1_STRING_type_new(utype)) == NULL) { 891 ASN1error(ERR_R_MALLOC_FAILURE); 892 goto err; 893 } 894 *pval = (ASN1_VALUE *)stmp; 895 } else { 896 stmp = (ASN1_STRING *)*pval; 897 stmp->type = utype; 898 } 899 if (!ASN1_STRING_set(stmp, content, len)) { 900 ASN1_STRING_free(stmp); 901 *pval = NULL; 902 goto err; 903 } 904 break; 905 } 906 /* If ASN1_ANY and NULL type fix up value */ 907 if (typ && (utype == V_ASN1_NULL)) 908 typ->value.ptr = NULL; 909 910 ret = 1; 911 912 err: 913 if (!ret) { 914 ASN1_TYPE_free(typ); 915 if (opval) 916 *opval = NULL; 917 } 918 return ret; 919 } 920 921 /* This function finds the end of an ASN1 structure when passed its maximum 922 * length, whether it is indefinite length and a pointer to the content. 923 * This is more efficient than calling asn1_collect because it does not 924 * recurse on each indefinite length header. 925 */ 926 927 static int 928 asn1_find_end(const unsigned char **in, long len, char inf) 929 { 930 int expected_eoc; 931 long plen; 932 const unsigned char *p = *in, *q; 933 934 /* If not indefinite length constructed just add length */ 935 if (inf == 0) { 936 *in += len; 937 return 1; 938 } 939 expected_eoc = 1; 940 /* Indefinite length constructed form. Find the end when enough EOCs 941 * are found. If more indefinite length constructed headers 942 * are encountered increment the expected eoc count otherwise just 943 * skip to the end of the data. 944 */ 945 while (len > 0) { 946 if (asn1_check_eoc(&p, len)) { 947 expected_eoc--; 948 if (expected_eoc == 0) 949 break; 950 len -= 2; 951 continue; 952 } 953 q = p; 954 /* Just read in a header: only care about the length */ 955 if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len, 956 -1, 0, 0, NULL)) { 957 ASN1error(ERR_R_NESTED_ASN1_ERROR); 958 return 0; 959 } 960 if (inf) 961 expected_eoc++; 962 else 963 p += plen; 964 len -= p - q; 965 } 966 if (expected_eoc) { 967 ASN1error(ASN1_R_MISSING_EOC); 968 return 0; 969 } 970 *in = p; 971 return 1; 972 } 973 /* This function collects the asn1 data from a constructred string 974 * type into a buffer. The values of 'in' and 'len' should refer 975 * to the contents of the constructed type and 'inf' should be set 976 * if it is indefinite length. 977 */ 978 979 #ifndef ASN1_MAX_STRING_NEST 980 /* This determines how many levels of recursion are permitted in ASN1 981 * string types. If it is not limited stack overflows can occur. If set 982 * to zero no recursion is allowed at all. Although zero should be adequate 983 * examples exist that require a value of 1. So 5 should be more than enough. 984 */ 985 #define ASN1_MAX_STRING_NEST 5 986 #endif 987 988 static int 989 asn1_collect(CBB *cbb, const unsigned char **in, long len, char inf, 990 int tag, int aclass, int depth) 991 { 992 const unsigned char *p, *q; 993 long plen; 994 char cst, ininf; 995 996 if (depth > ASN1_MAX_STRING_NEST) { 997 ASN1error(ASN1_R_NESTED_ASN1_STRING); 998 return 0; 999 } 1000 1001 p = *in; 1002 inf &= 1; 1003 1004 while (len > 0) { 1005 q = p; 1006 /* Check for EOC */ 1007 if (asn1_check_eoc(&p, len)) { 1008 /* EOC is illegal outside indefinite length 1009 * constructed form */ 1010 if (!inf) { 1011 ASN1error(ASN1_R_UNEXPECTED_EOC); 1012 return 0; 1013 } 1014 inf = 0; 1015 break; 1016 } 1017 1018 if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, 1019 len, tag, aclass, 0, NULL)) { 1020 ASN1error(ERR_R_NESTED_ASN1_ERROR); 1021 return 0; 1022 } 1023 1024 /* If indefinite length constructed update max length */ 1025 if (cst) { 1026 if (!asn1_collect(cbb, &p, plen, ininf, tag, aclass, 1027 depth + 1)) 1028 return 0; 1029 } else if (plen > 0) { 1030 if (!CBB_add_bytes(cbb, p, plen)) 1031 return 0; 1032 p += plen; 1033 } 1034 len -= p - q; 1035 } 1036 if (inf) { 1037 ASN1error(ASN1_R_MISSING_EOC); 1038 return 0; 1039 } 1040 *in = p; 1041 return 1; 1042 } 1043 1044 /* Check for ASN1 EOC and swallow it if found */ 1045 1046 static int 1047 asn1_check_eoc(const unsigned char **in, long len) 1048 { 1049 const unsigned char *p; 1050 1051 if (len < 2) 1052 return 0; 1053 p = *in; 1054 if (!p[0] && !p[1]) { 1055 *in += 2; 1056 return 1; 1057 } 1058 return 0; 1059 } 1060 1061 /* Check an ASN1 tag and length: a bit like ASN1_get_object 1062 * but it sets the length for indefinite length constructed 1063 * form, we don't know the exact length but we can set an 1064 * upper bound to the amount of data available minus the 1065 * header length just read. 1066 */ 1067 1068 static int 1069 asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, 1070 char *cst, const unsigned char **in, long len, int exptag, int expclass, 1071 char opt, ASN1_TLC *ctx) 1072 { 1073 int i; 1074 int ptag, pclass; 1075 long plen; 1076 const unsigned char *p, *q; 1077 1078 p = *in; 1079 q = p; 1080 1081 if (ctx && ctx->valid) { 1082 i = ctx->ret; 1083 plen = ctx->plen; 1084 pclass = ctx->pclass; 1085 ptag = ctx->ptag; 1086 p += ctx->hdrlen; 1087 } else { 1088 i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); 1089 if (ctx) { 1090 ctx->ret = i; 1091 ctx->plen = plen; 1092 ctx->pclass = pclass; 1093 ctx->ptag = ptag; 1094 ctx->hdrlen = p - q; 1095 ctx->valid = 1; 1096 /* If definite length, and no error, length + 1097 * header can't exceed total amount of data available. 1098 */ 1099 if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) { 1100 ASN1error(ASN1_R_TOO_LONG); 1101 asn1_tlc_invalidate(ctx); 1102 return 0; 1103 } 1104 } 1105 } 1106 1107 if (i & 0x80) { 1108 ASN1error(ASN1_R_BAD_OBJECT_HEADER); 1109 asn1_tlc_invalidate(ctx); 1110 return 0; 1111 } 1112 if (exptag >= 0) { 1113 if ((exptag != ptag) || (expclass != pclass)) { 1114 /* If type is OPTIONAL, not an error: 1115 * indicate missing type. 1116 */ 1117 if (opt) 1118 return -1; 1119 asn1_tlc_invalidate(ctx); 1120 ASN1error(ASN1_R_WRONG_TAG); 1121 return 0; 1122 } 1123 /* We have a tag and class match: 1124 * assume we are going to do something with it */ 1125 asn1_tlc_invalidate(ctx); 1126 } 1127 1128 if (i & 1) 1129 plen = len - (p - q); 1130 if (inf) 1131 *inf = i & 1; 1132 if (cst) 1133 *cst = i & V_ASN1_CONSTRUCTED; 1134 if (olen) 1135 *olen = plen; 1136 if (oclass) 1137 *oclass = pclass; 1138 if (otag) 1139 *otag = ptag; 1140 1141 *in = p; 1142 return 1; 1143 } 1144