tasn_dec.c revision 291854
1/* tasn_dec.c */ 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 60#include <stddef.h> 61#include <string.h> 62#include <openssl/asn1.h> 63#include <openssl/asn1t.h> 64#include <openssl/objects.h> 65#include <openssl/buffer.h> 66#include <openssl/err.h> 67 68static int asn1_check_eoc(const unsigned char **in, long len); 69static int asn1_find_end(const unsigned char **in, long len, char inf); 70 71static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, 72 char inf, int tag, int aclass, int depth); 73 74static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen); 75 76static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, 77 char *inf, char *cst, 78 const unsigned char **in, long len, 79 int exptag, int expclass, char opt, 80 ASN1_TLC *ctx); 81 82static int asn1_template_ex_d2i(ASN1_VALUE **pval, 83 const unsigned char **in, long len, 84 const ASN1_TEMPLATE *tt, char opt, 85 ASN1_TLC *ctx); 86static int asn1_template_noexp_d2i(ASN1_VALUE **val, 87 const unsigned char **in, long len, 88 const ASN1_TEMPLATE *tt, char opt, 89 ASN1_TLC *ctx); 90static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, 91 const unsigned char **in, long len, 92 const ASN1_ITEM *it, 93 int tag, int aclass, char opt, ASN1_TLC *ctx); 94 95/* Table to convert tags to bit values, used for MSTRING type */ 96static const unsigned long tag2bit[32] = { 970, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */ 98B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,/* tags 4- 7 */ 99B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags 8-11 */ 100B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */ 101B_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */ 102B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING, /* tags 20-22 */ 103B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */ 104B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING, /* tags 25-27 */ 105B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */ 106 }; 107 108unsigned long ASN1_tag2bit(int tag) 109 { 110 if ((tag < 0) || (tag > 30)) return 0; 111 return tag2bit[tag]; 112 } 113 114/* Macro to initialize and invalidate the cache */ 115 116#define asn1_tlc_clear(c) if (c) (c)->valid = 0 117 118/* Decode an ASN1 item, this currently behaves just 119 * like a standard 'd2i' function. 'in' points to 120 * a buffer to read the data from, in future we will 121 * have more advanced versions that can input data 122 * a piece at a time and this will simply be a special 123 * case. 124 */ 125 126ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, 127 const unsigned char **in, long len, const ASN1_ITEM *it) 128 { 129 ASN1_TLC c; 130 ASN1_VALUE *ptmpval = NULL; 131 if (!pval) 132 pval = &ptmpval; 133 c.valid = 0; 134 if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 135 return *pval; 136 return NULL; 137 } 138 139int ASN1_template_d2i(ASN1_VALUE **pval, 140 const unsigned char **in, long len, const ASN1_TEMPLATE *tt) 141 { 142 ASN1_TLC c; 143 c.valid = 0; 144 return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); 145 } 146 147 148/* Decode an item, taking care of IMPLICIT tagging, if any. 149 * If 'opt' set and tag mismatch return -1 to handle OPTIONAL 150 */ 151 152int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, 153 const ASN1_ITEM *it, 154 int tag, int aclass, char opt, ASN1_TLC *ctx) 155 { 156 const ASN1_TEMPLATE *tt, *errtt = NULL; 157 const ASN1_COMPAT_FUNCS *cf; 158 const ASN1_EXTERN_FUNCS *ef; 159 const ASN1_AUX *aux = it->funcs; 160 ASN1_aux_cb *asn1_cb; 161 const unsigned char *p = NULL, *q; 162 unsigned char *wp=NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */ 163 unsigned char imphack = 0, oclass; 164 char seq_eoc, seq_nolen, cst, isopt; 165 long tmplen; 166 int i; 167 int otag; 168 int ret = 0; 169 ASN1_VALUE **pchptr, *ptmpval; 170 int combine = aclass & ASN1_TFLG_COMBINE; 171 aclass &= ~ASN1_TFLG_COMBINE; 172 if (!pval) 173 return 0; 174 if (aux && aux->asn1_cb) 175 asn1_cb = aux->asn1_cb; 176 else asn1_cb = 0; 177 178 switch(it->itype) 179 { 180 case ASN1_ITYPE_PRIMITIVE: 181 if (it->templates) 182 { 183 /* tagging or OPTIONAL is currently illegal on an item 184 * template because the flags can't get passed down. 185 * In practice this isn't a problem: we include the 186 * relevant flags from the item template in the 187 * template itself. 188 */ 189 if ((tag != -1) || opt) 190 { 191 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 192 ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); 193 goto err; 194 } 195 return asn1_template_ex_d2i(pval, in, len, 196 it->templates, opt, ctx); 197 } 198 return asn1_d2i_ex_primitive(pval, in, len, it, 199 tag, aclass, opt, ctx); 200 break; 201 202 case ASN1_ITYPE_MSTRING: 203 p = *in; 204 /* Just read in tag and class */ 205 ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, 206 &p, len, -1, 0, 1, ctx); 207 if (!ret) 208 { 209 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 210 ERR_R_NESTED_ASN1_ERROR); 211 goto err; 212 } 213 214 /* Must be UNIVERSAL class */ 215 if (oclass != V_ASN1_UNIVERSAL) 216 { 217 /* If OPTIONAL, assume this is OK */ 218 if (opt) return -1; 219 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 220 ASN1_R_MSTRING_NOT_UNIVERSAL); 221 goto err; 222 } 223 /* Check tag matches bit map */ 224 if (!(ASN1_tag2bit(otag) & it->utype)) 225 { 226 /* If OPTIONAL, assume this is OK */ 227 if (opt) 228 return -1; 229 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 230 ASN1_R_MSTRING_WRONG_TAG); 231 goto err; 232 } 233 return asn1_d2i_ex_primitive(pval, in, len, 234 it, otag, 0, 0, ctx); 235 236 case ASN1_ITYPE_EXTERN: 237 /* Use new style d2i */ 238 ef = it->funcs; 239 return ef->asn1_ex_d2i(pval, in, len, 240 it, tag, aclass, opt, ctx); 241 242 case ASN1_ITYPE_COMPAT: 243 /* we must resort to old style evil hackery */ 244 cf = it->funcs; 245 246 /* If OPTIONAL see if it is there */ 247 if (opt) 248 { 249 int exptag; 250 p = *in; 251 if (tag == -1) 252 exptag = it->utype; 253 else exptag = tag; 254 /* Don't care about anything other than presence 255 * of expected tag */ 256 257 ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, 258 &p, len, exptag, aclass, 1, ctx); 259 if (!ret) 260 { 261 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 262 ERR_R_NESTED_ASN1_ERROR); 263 goto err; 264 } 265 if (ret == -1) 266 return -1; 267 } 268 269 /* This is the old style evil hack IMPLICIT handling: 270 * since the underlying code is expecting a tag and 271 * class other than the one present we change the 272 * buffer temporarily then change it back afterwards. 273 * This doesn't and never did work for tags > 30. 274 * 275 * Yes this is *horrible* but it is only needed for 276 * old style d2i which will hopefully not be around 277 * for much longer. 278 * FIXME: should copy the buffer then modify it so 279 * the input buffer can be const: we should *always* 280 * copy because the old style d2i might modify the 281 * buffer. 282 */ 283 284 if (tag != -1) 285 { 286 wp = *(unsigned char **)in; 287 imphack = *wp; 288 if (p == NULL) 289 { 290 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 291 ERR_R_NESTED_ASN1_ERROR); 292 goto err; 293 } 294 *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED) 295 | it->utype); 296 } 297 298 ptmpval = cf->asn1_d2i(pval, in, len); 299 300 if (tag != -1) 301 *wp = imphack; 302 303 if (ptmpval) 304 return 1; 305 306 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 307 goto err; 308 309 310 case ASN1_ITYPE_CHOICE: 311 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) 312 goto auxerr; 313 314 if (*pval) { 315 /* Free up and zero CHOICE value if initialised */ 316 i = asn1_get_choice_selector(pval, it); 317 if ((i >= 0) && (i < it->tcount)) { 318 tt = it->templates + i; 319 pchptr = asn1_get_field_ptr(pval, tt); 320 ASN1_template_free(pchptr, tt); 321 asn1_set_choice_selector(pval, -1, it); 322 } 323 } else if (!ASN1_item_ex_new(pval, it)) { 324 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 325 ERR_R_NESTED_ASN1_ERROR); 326 goto err; 327 } 328 /* CHOICE type, try each possibility in turn */ 329 p = *in; 330 for (i = 0, tt=it->templates; i < it->tcount; i++, tt++) 331 { 332 pchptr = asn1_get_field_ptr(pval, tt); 333 /* We mark field as OPTIONAL so its absence 334 * can be recognised. 335 */ 336 ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); 337 /* If field not present, try the next one */ 338 if (ret == -1) 339 continue; 340 /* If positive return, read OK, break loop */ 341 if (ret > 0) 342 break; 343 /* Otherwise must be an ASN1 parsing error */ 344 errtt = tt; 345 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 346 ERR_R_NESTED_ASN1_ERROR); 347 goto err; 348 } 349 350 /* Did we fall off the end without reading anything? */ 351 if (i == it->tcount) 352 { 353 /* If OPTIONAL, this is OK */ 354 if (opt) 355 { 356 /* Free and zero it */ 357 ASN1_item_ex_free(pval, it); 358 return -1; 359 } 360 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 361 ASN1_R_NO_MATCHING_CHOICE_TYPE); 362 goto err; 363 } 364 365 asn1_set_choice_selector(pval, i, it); 366 *in = p; 367 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) 368 goto auxerr; 369 return 1; 370 371 case ASN1_ITYPE_NDEF_SEQUENCE: 372 case ASN1_ITYPE_SEQUENCE: 373 p = *in; 374 tmplen = len; 375 376 /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ 377 if (tag == -1) 378 { 379 tag = V_ASN1_SEQUENCE; 380 aclass = V_ASN1_UNIVERSAL; 381 } 382 /* Get SEQUENCE length and update len, p */ 383 ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, 384 &p, len, tag, aclass, opt, ctx); 385 if (!ret) 386 { 387 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 388 ERR_R_NESTED_ASN1_ERROR); 389 goto err; 390 } 391 else if (ret == -1) 392 return -1; 393 if (aux && (aux->flags & ASN1_AFLG_BROKEN)) 394 { 395 len = tmplen - (p - *in); 396 seq_nolen = 1; 397 } 398 /* If indefinite we don't do a length check */ 399 else seq_nolen = seq_eoc; 400 if (!cst) 401 { 402 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 403 ASN1_R_SEQUENCE_NOT_CONSTRUCTED); 404 goto err; 405 } 406 407 if (!*pval && !ASN1_item_ex_new(pval, it)) 408 { 409 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 410 ERR_R_NESTED_ASN1_ERROR); 411 goto err; 412 } 413 414 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) 415 goto auxerr; 416 417 /* Free up and zero any ADB found */ 418 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { 419 if (tt->flags & ASN1_TFLG_ADB_MASK) { 420 const ASN1_TEMPLATE *seqtt; 421 ASN1_VALUE **pseqval; 422 seqtt = asn1_do_adb(pval, tt, 1); 423 pseqval = asn1_get_field_ptr(pval, seqtt); 424 ASN1_template_free(pseqval, seqtt); 425 } 426 } 427 428 /* Get each field entry */ 429 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) 430 { 431 const ASN1_TEMPLATE *seqtt; 432 ASN1_VALUE **pseqval; 433 seqtt = asn1_do_adb(pval, tt, 1); 434 if (!seqtt) 435 goto err; 436 pseqval = asn1_get_field_ptr(pval, seqtt); 437 /* Have we ran out of data? */ 438 if (!len) 439 break; 440 q = p; 441 if (asn1_check_eoc(&p, len)) 442 { 443 if (!seq_eoc) 444 { 445 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 446 ASN1_R_UNEXPECTED_EOC); 447 goto err; 448 } 449 len -= p - q; 450 seq_eoc = 0; 451 q = p; 452 break; 453 } 454 /* This determines the OPTIONAL flag value. The field 455 * cannot be omitted if it is the last of a SEQUENCE 456 * and there is still data to be read. This isn't 457 * strictly necessary but it increases efficiency in 458 * some cases. 459 */ 460 if (i == (it->tcount - 1)) 461 isopt = 0; 462 else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); 463 /* attempt to read in field, allowing each to be 464 * OPTIONAL */ 465 466 ret = asn1_template_ex_d2i(pseqval, &p, len, 467 seqtt, isopt, ctx); 468 if (!ret) 469 { 470 errtt = seqtt; 471 goto err; 472 } 473 else if (ret == -1) 474 { 475 /* OPTIONAL component absent. 476 * Free and zero the field. 477 */ 478 ASN1_template_free(pseqval, seqtt); 479 continue; 480 } 481 /* Update length */ 482 len -= p - q; 483 } 484 485 /* Check for EOC if expecting one */ 486 if (seq_eoc && !asn1_check_eoc(&p, len)) 487 { 488 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC); 489 goto err; 490 } 491 /* Check all data read */ 492 if (!seq_nolen && len) 493 { 494 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 495 ASN1_R_SEQUENCE_LENGTH_MISMATCH); 496 goto err; 497 } 498 499 /* If we get here we've got no more data in the SEQUENCE, 500 * however we may not have read all fields so check all 501 * remaining are OPTIONAL and clear any that are. 502 */ 503 for (; i < it->tcount; tt++, i++) 504 { 505 const ASN1_TEMPLATE *seqtt; 506 seqtt = asn1_do_adb(pval, tt, 1); 507 if (!seqtt) 508 goto err; 509 if (seqtt->flags & ASN1_TFLG_OPTIONAL) 510 { 511 ASN1_VALUE **pseqval; 512 pseqval = asn1_get_field_ptr(pval, seqtt); 513 ASN1_template_free(pseqval, seqtt); 514 } 515 else 516 { 517 errtt = seqtt; 518 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 519 ASN1_R_FIELD_MISSING); 520 goto err; 521 } 522 } 523 /* Save encoding */ 524 if (!asn1_enc_save(pval, *in, p - *in, it)) 525 goto auxerr; 526 *in = p; 527 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) 528 goto auxerr; 529 return 1; 530 531 default: 532 return 0; 533 } 534 auxerr: 535 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR); 536 err: 537 if (combine == 0) 538 ASN1_item_ex_free(pval, it); 539 if (errtt) 540 ERR_add_error_data(4, "Field=", errtt->field_name, 541 ", Type=", it->sname); 542 else 543 ERR_add_error_data(2, "Type=", it->sname); 544 return 0; 545 } 546 547/* Templates are handled with two separate functions. 548 * One handles any EXPLICIT tag and the other handles the rest. 549 */ 550 551static int asn1_template_ex_d2i(ASN1_VALUE **val, 552 const unsigned char **in, long inlen, 553 const ASN1_TEMPLATE *tt, char opt, 554 ASN1_TLC *ctx) 555 { 556 int flags, aclass; 557 int ret; 558 long len; 559 const unsigned char *p, *q; 560 char exp_eoc; 561 if (!val) 562 return 0; 563 flags = tt->flags; 564 aclass = flags & ASN1_TFLG_TAG_CLASS; 565 566 p = *in; 567 568 /* Check if EXPLICIT tag expected */ 569 if (flags & ASN1_TFLG_EXPTAG) 570 { 571 char cst; 572 /* Need to work out amount of data available to the inner 573 * content and where it starts: so read in EXPLICIT header to 574 * get the info. 575 */ 576 ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, 577 &p, inlen, tt->tag, aclass, opt, ctx); 578 q = p; 579 if (!ret) 580 { 581 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, 582 ERR_R_NESTED_ASN1_ERROR); 583 return 0; 584 } 585 else if (ret == -1) 586 return -1; 587 if (!cst) 588 { 589 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, 590 ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); 591 return 0; 592 } 593 /* We've found the field so it can't be OPTIONAL now */ 594 ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx); 595 if (!ret) 596 { 597 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, 598 ERR_R_NESTED_ASN1_ERROR); 599 return 0; 600 } 601 /* We read the field in OK so update length */ 602 len -= p - q; 603 if (exp_eoc) 604 { 605 /* If NDEF we must have an EOC here */ 606 if (!asn1_check_eoc(&p, len)) 607 { 608 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, 609 ASN1_R_MISSING_EOC); 610 goto err; 611 } 612 } 613 else 614 { 615 /* Otherwise we must hit the EXPLICIT tag end or its 616 * an error */ 617 if (len) 618 { 619 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, 620 ASN1_R_EXPLICIT_LENGTH_MISMATCH); 621 goto err; 622 } 623 } 624 } 625 else 626 return asn1_template_noexp_d2i(val, in, inlen, 627 tt, opt, ctx); 628 629 *in = p; 630 return 1; 631 632 err: 633 ASN1_template_free(val, tt); 634 return 0; 635 } 636 637static int asn1_template_noexp_d2i(ASN1_VALUE **val, 638 const unsigned char **in, long len, 639 const ASN1_TEMPLATE *tt, char opt, 640 ASN1_TLC *ctx) 641 { 642 int flags, aclass; 643 int ret; 644 const unsigned char *p, *q; 645 if (!val) 646 return 0; 647 flags = tt->flags; 648 aclass = flags & ASN1_TFLG_TAG_CLASS; 649 650 p = *in; 651 q = p; 652 653 if (flags & ASN1_TFLG_SK_MASK) 654 { 655 /* SET OF, SEQUENCE OF */ 656 int sktag, skaclass; 657 char sk_eoc; 658 /* First work out expected inner tag value */ 659 if (flags & ASN1_TFLG_IMPTAG) 660 { 661 sktag = tt->tag; 662 skaclass = aclass; 663 } 664 else 665 { 666 skaclass = V_ASN1_UNIVERSAL; 667 if (flags & ASN1_TFLG_SET_OF) 668 sktag = V_ASN1_SET; 669 else 670 sktag = V_ASN1_SEQUENCE; 671 } 672 /* Get the tag */ 673 ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, 674 &p, len, sktag, skaclass, opt, ctx); 675 if (!ret) 676 { 677 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 678 ERR_R_NESTED_ASN1_ERROR); 679 return 0; 680 } 681 else if (ret == -1) 682 return -1; 683 if (!*val) 684 *val = (ASN1_VALUE *)sk_new_null(); 685 else 686 { 687 /* We've got a valid STACK: free up any items present */ 688 STACK *sktmp = (STACK *)*val; 689 ASN1_VALUE *vtmp; 690 while(sk_num(sktmp) > 0) 691 { 692 vtmp = (ASN1_VALUE *)sk_pop(sktmp); 693 ASN1_item_ex_free(&vtmp, 694 ASN1_ITEM_ptr(tt->item)); 695 } 696 } 697 698 if (!*val) 699 { 700 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 701 ERR_R_MALLOC_FAILURE); 702 goto err; 703 } 704 705 /* Read as many items as we can */ 706 while(len > 0) 707 { 708 ASN1_VALUE *skfield; 709 q = p; 710 /* See if EOC found */ 711 if (asn1_check_eoc(&p, len)) 712 { 713 if (!sk_eoc) 714 { 715 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 716 ASN1_R_UNEXPECTED_EOC); 717 goto err; 718 } 719 len -= p - q; 720 sk_eoc = 0; 721 break; 722 } 723 skfield = NULL; 724 if (!ASN1_item_ex_d2i(&skfield, &p, len, 725 ASN1_ITEM_ptr(tt->item), 726 -1, 0, 0, ctx)) 727 { 728 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 729 ERR_R_NESTED_ASN1_ERROR); 730 goto err; 731 } 732 len -= p - q; 733 if (!sk_push((STACK *)*val, (char *)skfield)) 734 { 735 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 736 ERR_R_MALLOC_FAILURE); 737 goto err; 738 } 739 } 740 if (sk_eoc) 741 { 742 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC); 743 goto err; 744 } 745 } 746 else if (flags & ASN1_TFLG_IMPTAG) 747 { 748 /* IMPLICIT tagging */ 749 ret = ASN1_item_ex_d2i(val, &p, len, 750 ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx); 751 if (!ret) 752 { 753 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 754 ERR_R_NESTED_ASN1_ERROR); 755 goto err; 756 } 757 else if (ret == -1) 758 return -1; 759 } 760 else 761 { 762 /* Nothing special */ 763 ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), 764 -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx); 765 if (!ret) 766 { 767 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 768 ERR_R_NESTED_ASN1_ERROR); 769 goto err; 770 } 771 else if (ret == -1) 772 return -1; 773 } 774 775 *in = p; 776 return 1; 777 778 err: 779 ASN1_template_free(val, tt); 780 return 0; 781 } 782 783static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, 784 const unsigned char **in, long inlen, 785 const ASN1_ITEM *it, 786 int tag, int aclass, char opt, ASN1_TLC *ctx) 787 { 788 int ret = 0, utype; 789 long plen; 790 char cst, inf, free_cont = 0; 791 const unsigned char *p; 792 BUF_MEM buf; 793 const unsigned char *cont = NULL; 794 long len; 795 if (!pval) 796 { 797 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL); 798 return 0; /* Should never happen */ 799 } 800 801 if (it->itype == ASN1_ITYPE_MSTRING) 802 { 803 utype = tag; 804 tag = -1; 805 } 806 else 807 utype = it->utype; 808 809 if (utype == V_ASN1_ANY) 810 { 811 /* If type is ANY need to figure out type from tag */ 812 unsigned char oclass; 813 if (tag >= 0) 814 { 815 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, 816 ASN1_R_ILLEGAL_TAGGED_ANY); 817 return 0; 818 } 819 if (opt) 820 { 821 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, 822 ASN1_R_ILLEGAL_OPTIONAL_ANY); 823 return 0; 824 } 825 p = *in; 826 ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, 827 &p, inlen, -1, 0, 0, ctx); 828 if (!ret) 829 { 830 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, 831 ERR_R_NESTED_ASN1_ERROR); 832 return 0; 833 } 834 if (oclass != V_ASN1_UNIVERSAL) 835 utype = V_ASN1_OTHER; 836 } 837 if (tag == -1) 838 { 839 tag = utype; 840 aclass = V_ASN1_UNIVERSAL; 841 } 842 p = *in; 843 /* Check header */ 844 ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, 845 &p, inlen, tag, aclass, opt, ctx); 846 if (!ret) 847 { 848 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); 849 return 0; 850 } 851 else if (ret == -1) 852 return -1; 853 ret = 0; 854 /* SEQUENCE, SET and "OTHER" are left in encoded form */ 855 if ((utype == V_ASN1_SEQUENCE) 856 || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) 857 { 858 /* Clear context cache for type OTHER because the auto clear 859 * when we have a exact match wont work 860 */ 861 if (utype == V_ASN1_OTHER) 862 { 863 asn1_tlc_clear(ctx); 864 } 865 /* SEQUENCE and SET must be constructed */ 866 else if (!cst) 867 { 868 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, 869 ASN1_R_TYPE_NOT_CONSTRUCTED); 870 return 0; 871 } 872 873 cont = *in; 874 /* If indefinite length constructed find the real end */ 875 if (inf) 876 { 877 if (!asn1_find_end(&p, plen, inf)) 878 goto err; 879 len = p - cont; 880 } 881 else 882 { 883 len = p - cont + plen; 884 p += plen; 885 buf.data = NULL; 886 } 887 } 888 else if (cst) 889 { 890 if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN 891 || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER 892 || utype == V_ASN1_ENUMERATED) 893 { 894 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, 895 ASN1_R_TYPE_NOT_PRIMITIVE); 896 return 0; 897 } 898 buf.length = 0; 899 buf.max = 0; 900 buf.data = NULL; 901 /* Should really check the internal tags are correct but 902 * some things may get this wrong. The relevant specs 903 * say that constructed string types should be OCTET STRINGs 904 * internally irrespective of the type. So instead just check 905 * for UNIVERSAL class and ignore the tag. 906 */ 907 if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) 908 { 909 free_cont = 1; 910 goto err; 911 } 912 len = buf.length; 913 /* Append a final null to string */ 914 if (!BUF_MEM_grow_clean(&buf, len + 1)) 915 { 916 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, 917 ERR_R_MALLOC_FAILURE); 918 return 0; 919 } 920 buf.data[len] = 0; 921 cont = (const unsigned char *)buf.data; 922 free_cont = 1; 923 } 924 else 925 { 926 cont = p; 927 len = plen; 928 p += plen; 929 } 930 931 /* We now have content length and type: translate into a structure */ 932 if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) 933 goto err; 934 935 *in = p; 936 ret = 1; 937 err: 938 if (free_cont && buf.data) OPENSSL_free(buf.data); 939 return ret; 940 } 941 942/* Translate ASN1 content octets into a structure */ 943 944int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, 945 int utype, char *free_cont, const ASN1_ITEM *it) 946 { 947 ASN1_VALUE **opval = NULL; 948 ASN1_STRING *stmp; 949 ASN1_TYPE *typ = NULL; 950 int ret = 0; 951 const ASN1_PRIMITIVE_FUNCS *pf; 952 ASN1_INTEGER **tint; 953 pf = it->funcs; 954 955 if (pf && pf->prim_c2i) 956 return pf->prim_c2i(pval, cont, len, utype, free_cont, it); 957 /* If ANY type clear type and set pointer to internal value */ 958 if (it->utype == V_ASN1_ANY) 959 { 960 if (!*pval) 961 { 962 typ = ASN1_TYPE_new(); 963 if (typ == NULL) 964 goto err; 965 *pval = (ASN1_VALUE *)typ; 966 } 967 else 968 typ = (ASN1_TYPE *)*pval; 969 970 if (utype != typ->type) 971 ASN1_TYPE_set(typ, utype, NULL); 972 opval = pval; 973 pval = &typ->value.asn1_value; 974 } 975 switch(utype) 976 { 977 case V_ASN1_OBJECT: 978 if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) 979 goto err; 980 break; 981 982 case V_ASN1_NULL: 983 if (len) 984 { 985 ASN1err(ASN1_F_ASN1_EX_C2I, 986 ASN1_R_NULL_IS_WRONG_LENGTH); 987 goto err; 988 } 989 *pval = (ASN1_VALUE *)1; 990 break; 991 992 case V_ASN1_BOOLEAN: 993 if (len != 1) 994 { 995 ASN1err(ASN1_F_ASN1_EX_C2I, 996 ASN1_R_BOOLEAN_IS_WRONG_LENGTH); 997 goto err; 998 } 999 else 1000 { 1001 ASN1_BOOLEAN *tbool; 1002 tbool = (ASN1_BOOLEAN *)pval; 1003 *tbool = *cont; 1004 } 1005 break; 1006 1007 case V_ASN1_BIT_STRING: 1008 if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) 1009 goto err; 1010 break; 1011 1012 case V_ASN1_INTEGER: 1013 case V_ASN1_NEG_INTEGER: 1014 case V_ASN1_ENUMERATED: 1015 case V_ASN1_NEG_ENUMERATED: 1016 tint = (ASN1_INTEGER **)pval; 1017 if (!c2i_ASN1_INTEGER(tint, &cont, len)) 1018 goto err; 1019 /* Fixup type to match the expected form */ 1020 (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); 1021 break; 1022 1023 case V_ASN1_OCTET_STRING: 1024 case V_ASN1_NUMERICSTRING: 1025 case V_ASN1_PRINTABLESTRING: 1026 case V_ASN1_T61STRING: 1027 case V_ASN1_VIDEOTEXSTRING: 1028 case V_ASN1_IA5STRING: 1029 case V_ASN1_UTCTIME: 1030 case V_ASN1_GENERALIZEDTIME: 1031 case V_ASN1_GRAPHICSTRING: 1032 case V_ASN1_VISIBLESTRING: 1033 case V_ASN1_GENERALSTRING: 1034 case V_ASN1_UNIVERSALSTRING: 1035 case V_ASN1_BMPSTRING: 1036 case V_ASN1_UTF8STRING: 1037 case V_ASN1_OTHER: 1038 case V_ASN1_SET: 1039 case V_ASN1_SEQUENCE: 1040 default: 1041 if (utype == V_ASN1_BMPSTRING && (len & 1)) 1042 { 1043 ASN1err(ASN1_F_ASN1_EX_C2I, 1044 ASN1_R_BMPSTRING_IS_WRONG_LENGTH); 1045 goto err; 1046 } 1047 if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) 1048 { 1049 ASN1err(ASN1_F_ASN1_EX_C2I, 1050 ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); 1051 goto err; 1052 } 1053 /* All based on ASN1_STRING and handled the same */ 1054 if (!*pval) 1055 { 1056 stmp = ASN1_STRING_type_new(utype); 1057 if (!stmp) 1058 { 1059 ASN1err(ASN1_F_ASN1_EX_C2I, 1060 ERR_R_MALLOC_FAILURE); 1061 goto err; 1062 } 1063 *pval = (ASN1_VALUE *)stmp; 1064 } 1065 else 1066 { 1067 stmp = (ASN1_STRING *)*pval; 1068 stmp->type = utype; 1069 } 1070 /* If we've already allocated a buffer use it */ 1071 if (*free_cont) 1072 { 1073 if (stmp->data) 1074 OPENSSL_free(stmp->data); 1075 stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ 1076 stmp->length = len; 1077 *free_cont = 0; 1078 } 1079 else 1080 { 1081 if (!ASN1_STRING_set(stmp, cont, len)) 1082 { 1083 ASN1err(ASN1_F_ASN1_EX_C2I, 1084 ERR_R_MALLOC_FAILURE); 1085 ASN1_STRING_free(stmp); 1086 *pval = NULL; 1087 goto err; 1088 } 1089 } 1090 break; 1091 } 1092 /* If ASN1_ANY and NULL type fix up value */ 1093 if (typ && (utype == V_ASN1_NULL)) 1094 typ->value.ptr = NULL; 1095 1096 ret = 1; 1097 err: 1098 if (!ret) 1099 { 1100 ASN1_TYPE_free(typ); 1101 if (opval) 1102 *opval = NULL; 1103 } 1104 return ret; 1105 } 1106 1107 1108/* This function finds the end of an ASN1 structure when passed its maximum 1109 * length, whether it is indefinite length and a pointer to the content. 1110 * This is more efficient than calling asn1_collect because it does not 1111 * recurse on each indefinite length header. 1112 */ 1113 1114static int asn1_find_end(const unsigned char **in, long len, char inf) 1115 { 1116 int expected_eoc; 1117 long plen; 1118 const unsigned char *p = *in, *q; 1119 /* If not indefinite length constructed just add length */ 1120 if (inf == 0) 1121 { 1122 *in += len; 1123 return 1; 1124 } 1125 expected_eoc = 1; 1126 /* Indefinite length constructed form. Find the end when enough EOCs 1127 * are found. If more indefinite length constructed headers 1128 * are encountered increment the expected eoc count otherwise just 1129 * skip to the end of the data. 1130 */ 1131 while (len > 0) 1132 { 1133 if(asn1_check_eoc(&p, len)) 1134 { 1135 expected_eoc--; 1136 if (expected_eoc == 0) 1137 break; 1138 len -= 2; 1139 continue; 1140 } 1141 q = p; 1142 /* Just read in a header: only care about the length */ 1143 if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len, 1144 -1, 0, 0, NULL)) 1145 { 1146 ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR); 1147 return 0; 1148 } 1149 if (inf) 1150 expected_eoc++; 1151 else 1152 p += plen; 1153 len -= p - q; 1154 } 1155 if (expected_eoc) 1156 { 1157 ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC); 1158 return 0; 1159 } 1160 *in = p; 1161 return 1; 1162 } 1163/* This function collects the asn1 data from a constructred string 1164 * type into a buffer. The values of 'in' and 'len' should refer 1165 * to the contents of the constructed type and 'inf' should be set 1166 * if it is indefinite length. 1167 */ 1168 1169#ifndef ASN1_MAX_STRING_NEST 1170/* This determines how many levels of recursion are permitted in ASN1 1171 * string types. If it is not limited stack overflows can occur. If set 1172 * to zero no recursion is allowed at all. Although zero should be adequate 1173 * examples exist that require a value of 1. So 5 should be more than enough. 1174 */ 1175#define ASN1_MAX_STRING_NEST 5 1176#endif 1177 1178 1179static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, 1180 char inf, int tag, int aclass, int depth) 1181 { 1182 const unsigned char *p, *q; 1183 long plen; 1184 char cst, ininf; 1185 p = *in; 1186 inf &= 1; 1187 /* If no buffer and not indefinite length constructed just pass over 1188 * the encoded data */ 1189 if (!buf && !inf) 1190 { 1191 *in += len; 1192 return 1; 1193 } 1194 while(len > 0) 1195 { 1196 q = p; 1197 /* Check for EOC */ 1198 if (asn1_check_eoc(&p, len)) 1199 { 1200 /* EOC is illegal outside indefinite length 1201 * constructed form */ 1202 if (!inf) 1203 { 1204 ASN1err(ASN1_F_ASN1_COLLECT, 1205 ASN1_R_UNEXPECTED_EOC); 1206 return 0; 1207 } 1208 inf = 0; 1209 break; 1210 } 1211 1212 if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, 1213 len, tag, aclass, 0, NULL)) 1214 { 1215 ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR); 1216 return 0; 1217 } 1218 1219 /* If indefinite length constructed update max length */ 1220 if (cst) 1221 { 1222 if (depth >= ASN1_MAX_STRING_NEST) 1223 { 1224 ASN1err(ASN1_F_ASN1_COLLECT, 1225 ASN1_R_NESTED_ASN1_STRING); 1226 return 0; 1227 } 1228 if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, 1229 depth + 1)) 1230 return 0; 1231 } 1232 else if (plen && !collect_data(buf, &p, plen)) 1233 return 0; 1234 len -= p - q; 1235 } 1236 if (inf) 1237 { 1238 ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC); 1239 return 0; 1240 } 1241 *in = p; 1242 return 1; 1243 } 1244 1245static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen) 1246 { 1247 int len; 1248 if (buf) 1249 { 1250 len = buf->length; 1251 if (!BUF_MEM_grow_clean(buf, len + plen)) 1252 { 1253 ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); 1254 return 0; 1255 } 1256 memcpy(buf->data + len, *p, plen); 1257 } 1258 *p += plen; 1259 return 1; 1260 } 1261 1262/* Check for ASN1 EOC and swallow it if found */ 1263 1264static int asn1_check_eoc(const unsigned char **in, long len) 1265 { 1266 const unsigned char *p; 1267 if (len < 2) return 0; 1268 p = *in; 1269 if (!p[0] && !p[1]) 1270 { 1271 *in += 2; 1272 return 1; 1273 } 1274 return 0; 1275 } 1276 1277/* Check an ASN1 tag and length: a bit like ASN1_get_object 1278 * but it sets the length for indefinite length constructed 1279 * form, we don't know the exact length but we can set an 1280 * upper bound to the amount of data available minus the 1281 * header length just read. 1282 */ 1283 1284static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, 1285 char *inf, char *cst, 1286 const unsigned char **in, long len, 1287 int exptag, int expclass, char opt, 1288 ASN1_TLC *ctx) 1289 { 1290 int i; 1291 int ptag, pclass; 1292 long plen; 1293 const unsigned char *p, *q; 1294 p = *in; 1295 q = p; 1296 1297 if (ctx && ctx->valid) 1298 { 1299 i = ctx->ret; 1300 plen = ctx->plen; 1301 pclass = ctx->pclass; 1302 ptag = ctx->ptag; 1303 p += ctx->hdrlen; 1304 } 1305 else 1306 { 1307 i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); 1308 if (ctx) 1309 { 1310 ctx->ret = i; 1311 ctx->plen = plen; 1312 ctx->pclass = pclass; 1313 ctx->ptag = ptag; 1314 ctx->hdrlen = p - q; 1315 ctx->valid = 1; 1316 /* If definite length, and no error, length + 1317 * header can't exceed total amount of data available. 1318 */ 1319 if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) 1320 { 1321 ASN1err(ASN1_F_ASN1_CHECK_TLEN, 1322 ASN1_R_TOO_LONG); 1323 asn1_tlc_clear(ctx); 1324 return 0; 1325 } 1326 } 1327 } 1328 1329 if (i & 0x80) 1330 { 1331 ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER); 1332 asn1_tlc_clear(ctx); 1333 return 0; 1334 } 1335 if (exptag >= 0) 1336 { 1337 if ((exptag != ptag) || (expclass != pclass)) 1338 { 1339 /* If type is OPTIONAL, not an error: 1340 * indicate missing type. 1341 */ 1342 if (opt) return -1; 1343 asn1_tlc_clear(ctx); 1344 ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG); 1345 return 0; 1346 } 1347 /* We have a tag and class match: 1348 * assume we are going to do something with it */ 1349 asn1_tlc_clear(ctx); 1350 } 1351 1352 if (i & 1) 1353 plen = len - (p - q); 1354 1355 if (inf) 1356 *inf = i & 1; 1357 1358 if (cst) 1359 *cst = i & V_ASN1_CONSTRUCTED; 1360 1361 if (olen) 1362 *olen = plen; 1363 1364 if (oclass) 1365 *oclass = pclass; 1366 1367 if (otag) 1368 *otag = ptag; 1369 1370 *in = p; 1371 return 1; 1372 } 1373