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