1 /* tasn_dec.c */ 2 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 3 * project 2000. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2000 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 68 static int asn1_check_eoc(unsigned char **in, long len); 69 static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass); 70 static int collect_data(BUF_MEM *buf, unsigned char **p, long plen); 71 static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, 72 unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx); 73 static int asn1_template_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx); 74 static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx); 75 static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long len, 76 const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx); 77 78 /* Table to convert tags to bit values, used for MSTRING type */ 79 static unsigned long tag2bit[32]={ 80 0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */ 81 B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,/* tags 4- 7 */ 82 B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags 8-11 */ 83 B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */ 84 0, 0, B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */ 85 B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING, /* tags 20-22 */ 86 B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */ 87 B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING, /* tags 25-27 */ 88 B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */ 89 }; 90 91 unsigned long ASN1_tag2bit(int tag) 92 { 93 if((tag < 0) || (tag > 30)) return 0; 94 return tag2bit[tag]; 95 } 96 97 /* Macro to initialize and invalidate the cache */ 98 99 #define asn1_tlc_clear(c) if(c) (c)->valid = 0 100 101 /* Decode an ASN1 item, this currently behaves just 102 * like a standard 'd2i' function. 'in' points to 103 * a buffer to read the data from, in future we will 104 * have more advanced versions that can input data 105 * a piece at a time and this will simply be a special 106 * case. 107 */ 108 109 ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it) 110 { 111 ASN1_TLC c; 112 ASN1_VALUE *ptmpval = NULL; 113 if(!pval) pval = &ptmpval; 114 asn1_tlc_clear(&c); 115 if(ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 116 return *pval; 117 return NULL; 118 } 119 120 int ASN1_template_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt) 121 { 122 ASN1_TLC c; 123 asn1_tlc_clear(&c); 124 return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); 125 } 126 127 128 /* Decode an item, taking care of IMPLICIT tagging, if any. 129 * If 'opt' set and tag mismatch return -1 to handle OPTIONAL 130 */ 131 132 int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it, 133 int tag, int aclass, char opt, ASN1_TLC *ctx) 134 { 135 const ASN1_TEMPLATE *tt, *errtt = NULL; 136 const ASN1_COMPAT_FUNCS *cf; 137 const ASN1_EXTERN_FUNCS *ef; 138 const ASN1_AUX *aux = it->funcs; 139 ASN1_aux_cb *asn1_cb; 140 unsigned char *p, *q, imphack = 0, oclass; 141 char seq_eoc, seq_nolen, cst, isopt; 142 long tmplen; 143 int i; 144 int otag; 145 int ret = 0; 146 ASN1_VALUE *pchval, **pchptr, *ptmpval; 147 if(!pval) return 0; 148 if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; 149 else asn1_cb = 0; 150 151 switch(it->itype) { 152 153 case ASN1_ITYPE_PRIMITIVE: 154 if(it->templates) { 155 /* tagging or OPTIONAL is currently illegal on an item template 156 * because the flags can't get passed down. In practice this isn't 157 * a problem: we include the relevant flags from the item template 158 * in the template itself. 159 */ 160 if ((tag != -1) || opt) { 161 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); 162 goto err; 163 } 164 return asn1_template_ex_d2i(pval, in, len, it->templates, opt, ctx); 165 } 166 return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt, ctx); 167 break; 168 169 case ASN1_ITYPE_MSTRING: 170 p = *in; 171 /* Just read in tag and class */ 172 ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, &p, len, -1, 0, 1, ctx); 173 if(!ret) { 174 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 175 goto err; 176 } 177 /* Must be UNIVERSAL class */ 178 if(oclass != V_ASN1_UNIVERSAL) { 179 /* If OPTIONAL, assume this is OK */ 180 if(opt) return -1; 181 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL); 182 goto err; 183 } 184 /* Check tag matches bit map */ 185 if(!(ASN1_tag2bit(otag) & it->utype)) { 186 /* If OPTIONAL, assume this is OK */ 187 if(opt) return -1; 188 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG); 189 goto err; 190 } 191 return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx); 192 193 case ASN1_ITYPE_EXTERN: 194 /* Use new style d2i */ 195 ef = it->funcs; 196 return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); 197 198 case ASN1_ITYPE_COMPAT: 199 /* we must resort to old style evil hackery */ 200 cf = it->funcs; 201 202 /* If OPTIONAL see if it is there */ 203 if(opt) { 204 int exptag; 205 p = *in; 206 if(tag == -1) exptag = it->utype; 207 else exptag = tag; 208 /* Don't care about anything other than presence of expected tag */ 209 ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, &p, len, exptag, aclass, 1, ctx); 210 if(!ret) { 211 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 212 goto err; 213 } 214 if(ret == -1) return -1; 215 } 216 /* This is the old style evil hack IMPLICIT handling: 217 * since the underlying code is expecting a tag and 218 * class other than the one present we change the 219 * buffer temporarily then change it back afterwards. 220 * This doesn't and never did work for tags > 30. 221 * 222 * Yes this is *horrible* but it is only needed for 223 * old style d2i which will hopefully not be around 224 * for much longer. 225 * FIXME: should copy the buffer then modify it so 226 * the input buffer can be const: we should *always* 227 * copy because the old style d2i might modify the 228 * buffer. 229 */ 230 231 if(tag != -1) { 232 p = *in; 233 imphack = *p; 234 *p = (unsigned char)((*p & V_ASN1_CONSTRUCTED) | it->utype); 235 } 236 237 ptmpval = cf->asn1_d2i(pval, in, len); 238 239 if(tag != -1) *p = imphack; 240 241 if(ptmpval) return 1; 242 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 243 goto err; 244 245 246 case ASN1_ITYPE_CHOICE: 247 if(asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) 248 goto auxerr; 249 250 /* Allocate structure */ 251 if(!*pval) { 252 if(!ASN1_item_ex_new(pval, it)) { 253 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 254 goto err; 255 } 256 } 257 /* CHOICE type, try each possibility in turn */ 258 pchval = NULL; 259 p = *in; 260 for(i = 0, tt=it->templates; i < it->tcount; i++, tt++) { 261 pchptr = asn1_get_field_ptr(pval, tt); 262 /* We mark field as OPTIONAL so its absence 263 * can be recognised. 264 */ 265 ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); 266 /* If field not present, try the next one */ 267 if(ret == -1) continue; 268 /* If positive return, read OK, break loop */ 269 if(ret > 0) break; 270 /* Otherwise must be an ASN1 parsing error */ 271 errtt = tt; 272 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 273 goto err; 274 } 275 /* Did we fall off the end without reading anything? */ 276 if(i == it->tcount) { 277 /* If OPTIONAL, this is OK */ 278 if(opt) { 279 /* Free and zero it */ 280 ASN1_item_ex_free(pval, it); 281 return -1; 282 } 283 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE); 284 goto err; 285 } 286 asn1_set_choice_selector(pval, i, it); 287 *in = p; 288 if(asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) 289 goto auxerr; 290 return 1; 291 292 case ASN1_ITYPE_SEQUENCE: 293 p = *in; 294 tmplen = len; 295 296 /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ 297 if(tag == -1) { 298 tag = V_ASN1_SEQUENCE; 299 aclass = V_ASN1_UNIVERSAL; 300 } 301 /* Get SEQUENCE length and update len, p */ 302 ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, &p, len, tag, aclass, opt, ctx); 303 if(!ret) { 304 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 305 goto err; 306 } else if(ret == -1) return -1; 307 if(aux && (aux->flags & ASN1_AFLG_BROKEN)) { 308 len = tmplen - (p - *in); 309 seq_nolen = 1; 310 } else seq_nolen = seq_eoc; /* If indefinite we don't do a length check */ 311 if(!cst) { 312 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); 313 goto err; 314 } 315 316 if(!*pval) { 317 if(!ASN1_item_ex_new(pval, it)) { 318 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 319 goto err; 320 } 321 } 322 if(asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) 323 goto auxerr; 324 325 /* Get each field entry */ 326 for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) { 327 const ASN1_TEMPLATE *seqtt; 328 ASN1_VALUE **pseqval; 329 seqtt = asn1_do_adb(pval, tt, 1); 330 if(!seqtt) goto err; 331 pseqval = asn1_get_field_ptr(pval, seqtt); 332 /* Have we ran out of data? */ 333 if(!len) break; 334 q = p; 335 if(asn1_check_eoc(&p, len)) { 336 if(!seq_eoc) { 337 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC); 338 goto err; 339 } 340 len -= p - q; 341 seq_eoc = 0; 342 q = p; 343 break; 344 } 345 /* This determines the OPTIONAL flag value. The field cannot 346 * be omitted if it is the last of a SEQUENCE and there is 347 * still data to be read. This isn't strictly necessary but 348 * it increases efficiency in some cases. 349 */ 350 if(i == (it->tcount - 1)) isopt = 0; 351 else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); 352 /* attempt to read in field, allowing each to be OPTIONAL */ 353 ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx); 354 if(!ret) { 355 errtt = seqtt; 356 goto err; 357 } else if(ret == -1) { 358 /* OPTIONAL component absent. Free and zero the field 359 */ 360 ASN1_template_free(pseqval, seqtt); 361 continue; 362 } 363 /* Update length */ 364 len -= p - q; 365 } 366 /* Check for EOC if expecting one */ 367 if(seq_eoc && !asn1_check_eoc(&p, len)) { 368 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC); 369 goto err; 370 } 371 /* Check all data read */ 372 if(!seq_nolen && len) { 373 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH); 374 goto err; 375 } 376 377 /* If we get here we've got no more data in the SEQUENCE, 378 * however we may not have read all fields so check all 379 * remaining are OPTIONAL and clear any that are. 380 */ 381 for(; i < it->tcount; tt++, i++) { 382 const ASN1_TEMPLATE *seqtt; 383 seqtt = asn1_do_adb(pval, tt, 1); 384 if(!seqtt) goto err; 385 if(seqtt->flags & ASN1_TFLG_OPTIONAL) { 386 ASN1_VALUE **pseqval; 387 pseqval = asn1_get_field_ptr(pval, seqtt); 388 ASN1_template_free(pseqval, seqtt); 389 } else { 390 errtt = seqtt; 391 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING); 392 goto err; 393 } 394 } 395 /* Save encoding */ 396 if(!asn1_enc_save(pval, *in, p - *in, it)) goto auxerr; 397 *in = p; 398 if(asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) 399 goto auxerr; 400 return 1; 401 402 default: 403 return 0; 404 } 405 auxerr: 406 ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR); 407 err: 408 ASN1_item_ex_free(pval, it); 409 if(errtt) ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname); 410 else ERR_add_error_data(2, "Type=", it->sname); 411 return 0; 412 } 413 414 /* Templates are handled with two separate functions. One handles any EXPLICIT tag and the other handles the 415 * rest. 416 */ 417 418 static int asn1_template_ex_d2i(ASN1_VALUE **val, unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx) 419 { 420 int flags, aclass; 421 int ret; 422 long len; 423 unsigned char *p, *q; 424 char exp_eoc; 425 if(!val) return 0; 426 flags = tt->flags; 427 aclass = flags & ASN1_TFLG_TAG_CLASS; 428 429 p = *in; 430 431 /* Check if EXPLICIT tag expected */ 432 if(flags & ASN1_TFLG_EXPTAG) { 433 char cst; 434 /* Need to work out amount of data available to the inner content and where it 435 * starts: so read in EXPLICIT header to get the info. 436 */ 437 ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, &p, inlen, tt->tag, aclass, opt, ctx); 438 q = p; 439 if(!ret) { 440 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 441 return 0; 442 } else if(ret == -1) return -1; 443 if(!cst) { 444 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); 445 return 0; 446 } 447 /* We've found the field so it can't be OPTIONAL now */ 448 ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx); 449 if(!ret) { 450 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 451 return 0; 452 } 453 /* We read the field in OK so update length */ 454 len -= p - q; 455 if(exp_eoc) { 456 /* If NDEF we must have an EOC here */ 457 if(!asn1_check_eoc(&p, len)) { 458 ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC); 459 goto err; 460 } 461 } else { 462 /* Otherwise we must hit the EXPLICIT tag end or its an error */ 463 if(len) { 464 ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_EXPLICIT_LENGTH_MISMATCH); 465 goto err; 466 } 467 } 468 } else 469 return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx); 470 471 *in = p; 472 return 1; 473 474 err: 475 ASN1_template_free(val, tt); 476 *val = NULL; 477 return 0; 478 } 479 480 static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx) 481 { 482 int flags, aclass; 483 int ret; 484 unsigned char *p, *q; 485 if(!val) return 0; 486 flags = tt->flags; 487 aclass = flags & ASN1_TFLG_TAG_CLASS; 488 489 p = *in; 490 q = p; 491 492 if(flags & ASN1_TFLG_SK_MASK) { 493 /* SET OF, SEQUENCE OF */ 494 int sktag, skaclass; 495 char sk_eoc; 496 /* First work out expected inner tag value */ 497 if(flags & ASN1_TFLG_IMPTAG) { 498 sktag = tt->tag; 499 skaclass = aclass; 500 } else { 501 skaclass = V_ASN1_UNIVERSAL; 502 if(flags & ASN1_TFLG_SET_OF) sktag = V_ASN1_SET; 503 else sktag = V_ASN1_SEQUENCE; 504 } 505 /* Get the tag */ 506 ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, &p, len, sktag, skaclass, opt, ctx); 507 if(!ret) { 508 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 509 return 0; 510 } else if(ret == -1) return -1; 511 if(!*val) *val = (ASN1_VALUE *)sk_new_null(); 512 else { 513 /* We've got a valid STACK: free up any items present */ 514 STACK *sktmp = (STACK *)*val; 515 ASN1_VALUE *vtmp; 516 while(sk_num(sktmp) > 0) { 517 vtmp = (ASN1_VALUE *)sk_pop(sktmp); 518 ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); 519 } 520 } 521 522 if(!*val) { 523 ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_MALLOC_FAILURE); 524 goto err; 525 } 526 /* Read as many items as we can */ 527 while(len > 0) { 528 ASN1_VALUE *skfield; 529 q = p; 530 /* See if EOC found */ 531 if(asn1_check_eoc(&p, len)) { 532 if(!sk_eoc) { 533 ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_UNEXPECTED_EOC); 534 goto err; 535 } 536 len -= p - q; 537 sk_eoc = 0; 538 break; 539 } 540 skfield = NULL; 541 if(!ASN1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) { 542 ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR); 543 goto err; 544 } 545 len -= p - q; 546 if(!sk_push((STACK *)*val, (char *)skfield)) { 547 ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_MALLOC_FAILURE); 548 goto err; 549 } 550 } 551 if(sk_eoc) { 552 ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC); 553 goto err; 554 } 555 } else if(flags & ASN1_TFLG_IMPTAG) { 556 /* IMPLICIT tagging */ 557 ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx); 558 if(!ret) { 559 ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR); 560 goto err; 561 } else if(ret == -1) return -1; 562 } else { 563 /* Nothing special */ 564 ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, opt, ctx); 565 if(!ret) { 566 ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR); 567 goto err; 568 } else if(ret == -1) return -1; 569 } 570 571 *in = p; 572 return 1; 573 574 err: 575 ASN1_template_free(val, tt); 576 *val = NULL; 577 return 0; 578 } 579 580 static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inlen, 581 const ASN1_ITEM *it, 582 int tag, int aclass, char opt, ASN1_TLC *ctx) 583 { 584 int ret = 0, utype; 585 long plen; 586 char cst, inf, free_cont = 0; 587 unsigned char *p; 588 BUF_MEM buf; 589 unsigned char *cont = NULL; 590 long len; 591 if(!pval) { 592 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL); 593 return 0; /* Should never happen */ 594 } 595 596 if(it->itype == ASN1_ITYPE_MSTRING) { 597 utype = tag; 598 tag = -1; 599 } else utype = it->utype; 600 601 if(utype == V_ASN1_ANY) { 602 /* If type is ANY need to figure out type from tag */ 603 unsigned char oclass; 604 if(tag >= 0) { 605 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY); 606 return 0; 607 } 608 if(opt) { 609 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_OPTIONAL_ANY); 610 return 0; 611 } 612 p = *in; 613 ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, &p, inlen, -1, 0, 0, ctx); 614 if(!ret) { 615 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); 616 return 0; 617 } 618 if(oclass != V_ASN1_UNIVERSAL) utype = V_ASN1_OTHER; 619 } 620 if(tag == -1) { 621 tag = utype; 622 aclass = V_ASN1_UNIVERSAL; 623 } 624 p = *in; 625 /* Check header */ 626 ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, &p, inlen, tag, aclass, opt, ctx); 627 if(!ret) { 628 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); 629 return 0; 630 } else if(ret == -1) return -1; 631 /* SEQUENCE, SET and "OTHER" are left in encoded form */ 632 if((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) { 633 /* Clear context cache for type OTHER because the auto clear when 634 * we have a exact match wont work 635 */ 636 if(utype == V_ASN1_OTHER) { 637 asn1_tlc_clear(ctx); 638 /* SEQUENCE and SET must be constructed */ 639 } else if(!cst) { 640 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_CONSTRUCTED); 641 return 0; 642 } 643 644 cont = *in; 645 /* If indefinite length constructed find the real end */ 646 if(inf) { 647 if(!asn1_collect(NULL, &p, plen, inf, -1, -1)) goto err; 648 len = p - cont; 649 } else { 650 len = p - cont + plen; 651 p += plen; 652 buf.data = NULL; 653 } 654 } else if(cst) { 655 buf.length = 0; 656 buf.max = 0; 657 buf.data = NULL; 658 /* Should really check the internal tags are correct but 659 * some things may get this wrong. The relevant specs 660 * say that constructed string types should be OCTET STRINGs 661 * internally irrespective of the type. So instead just check 662 * for UNIVERSAL class and ignore the tag. 663 */ 664 if(!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL)) goto err; 665 len = buf.length; 666 /* Append a final null to string */ 667 if(!BUF_MEM_grow_clean(&buf, len + 1)) { 668 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); 669 return 0; 670 } 671 buf.data[len] = 0; 672 cont = (unsigned char *)buf.data; 673 free_cont = 1; 674 } else { 675 cont = p; 676 len = plen; 677 p += plen; 678 } 679 680 /* We now have content length and type: translate into a structure */ 681 if(!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) goto err; 682 683 *in = p; 684 ret = 1; 685 err: 686 if(free_cont && buf.data) OPENSSL_free(buf.data); 687 return ret; 688 } 689 690 /* Translate ASN1 content octets into a structure */ 691 692 int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it) 693 { 694 ASN1_VALUE **opval = NULL; 695 ASN1_STRING *stmp; 696 ASN1_TYPE *typ = NULL; 697 int ret = 0; 698 const ASN1_PRIMITIVE_FUNCS *pf; 699 ASN1_INTEGER **tint; 700 pf = it->funcs; 701 if(pf && pf->prim_c2i) return pf->prim_c2i(pval, cont, len, utype, free_cont, it); 702 /* If ANY type clear type and set pointer to internal value */ 703 if(it->utype == V_ASN1_ANY) { 704 if(!*pval) { 705 typ = ASN1_TYPE_new(); 706 *pval = (ASN1_VALUE *)typ; 707 } else typ = (ASN1_TYPE *)*pval; 708 if(utype != typ->type) ASN1_TYPE_set(typ, utype, NULL); 709 opval = pval; 710 pval = (ASN1_VALUE **)&typ->value.ptr; 711 } 712 switch(utype) { 713 case V_ASN1_OBJECT: 714 if(!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) goto err; 715 break; 716 717 case V_ASN1_NULL: 718 if(len) { 719 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_NULL_IS_WRONG_LENGTH); 720 goto err; 721 } 722 *pval = (ASN1_VALUE *)1; 723 break; 724 725 case V_ASN1_BOOLEAN: 726 if(len != 1) { 727 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); 728 goto err; 729 } else { 730 ASN1_BOOLEAN *tbool; 731 tbool = (ASN1_BOOLEAN *)pval; 732 *tbool = *cont; 733 } 734 break; 735 736 case V_ASN1_BIT_STRING: 737 if(!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) goto err; 738 break; 739 740 case V_ASN1_INTEGER: 741 case V_ASN1_NEG_INTEGER: 742 case V_ASN1_ENUMERATED: 743 case V_ASN1_NEG_ENUMERATED: 744 tint = (ASN1_INTEGER **)pval; 745 if(!c2i_ASN1_INTEGER(tint, &cont, len)) goto err; 746 /* Fixup type to match the expected form */ 747 (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); 748 break; 749 750 case V_ASN1_OCTET_STRING: 751 case V_ASN1_NUMERICSTRING: 752 case V_ASN1_PRINTABLESTRING: 753 case V_ASN1_T61STRING: 754 case V_ASN1_VIDEOTEXSTRING: 755 case V_ASN1_IA5STRING: 756 case V_ASN1_UTCTIME: 757 case V_ASN1_GENERALIZEDTIME: 758 case V_ASN1_GRAPHICSTRING: 759 case V_ASN1_VISIBLESTRING: 760 case V_ASN1_GENERALSTRING: 761 case V_ASN1_UNIVERSALSTRING: 762 case V_ASN1_BMPSTRING: 763 case V_ASN1_UTF8STRING: 764 case V_ASN1_OTHER: 765 case V_ASN1_SET: 766 case V_ASN1_SEQUENCE: 767 default: 768 /* All based on ASN1_STRING and handled the same */ 769 if(!*pval) { 770 stmp = ASN1_STRING_type_new(utype); 771 if(!stmp) { 772 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); 773 goto err; 774 } 775 *pval = (ASN1_VALUE *)stmp; 776 } else { 777 stmp = (ASN1_STRING *)*pval; 778 stmp->type = utype; 779 } 780 /* If we've already allocated a buffer use it */ 781 if(*free_cont) { 782 if(stmp->data) OPENSSL_free(stmp->data); 783 stmp->data = cont; 784 stmp->length = len; 785 *free_cont = 0; 786 } else { 787 if(!ASN1_STRING_set(stmp, cont, len)) { 788 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); 789 ASN1_STRING_free(stmp); 790 *pval = NULL; 791 goto err; 792 } 793 } 794 break; 795 } 796 /* If ASN1_ANY and NULL type fix up value */ 797 if(typ && utype==V_ASN1_NULL) typ->value.ptr = NULL; 798 799 ret = 1; 800 err: 801 if(!ret) 802 { 803 ASN1_TYPE_free(typ); 804 if (opval) 805 *opval = NULL; 806 } 807 return ret; 808 } 809 810 /* This function collects the asn1 data from a constructred string 811 * type into a buffer. The values of 'in' and 'len' should refer 812 * to the contents of the constructed type and 'inf' should be set 813 * if it is indefinite length. If 'buf' is NULL then we just want 814 * to find the end of the current structure: useful for indefinite 815 * length constructed stuff. 816 */ 817 818 static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass) 819 { 820 unsigned char *p, *q; 821 long plen; 822 char cst, ininf; 823 p = *in; 824 inf &= 1; 825 /* If no buffer and not indefinite length constructed just pass over the encoded data */ 826 if(!buf && !inf) { 827 *in += len; 828 return 1; 829 } 830 while(len > 0) { 831 q = p; 832 /* Check for EOC */ 833 if(asn1_check_eoc(&p, len)) { 834 /* EOC is illegal outside indefinite length constructed form */ 835 if(!inf) { 836 ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC); 837 return 0; 838 } 839 inf = 0; 840 break; 841 } 842 if(!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, len, tag, aclass, 0, NULL)) { 843 ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR); 844 return 0; 845 } 846 /* If indefinite length constructed update max length */ 847 if(cst) { 848 if(!asn1_collect(buf, &p, plen, ininf, tag, aclass)) return 0; 849 } else { 850 if(!collect_data(buf, &p, plen)) return 0; 851 } 852 len -= p - q; 853 } 854 if(inf) { 855 ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC); 856 return 0; 857 } 858 *in = p; 859 return 1; 860 } 861 862 static int collect_data(BUF_MEM *buf, unsigned char **p, long plen) 863 { 864 int len; 865 if(buf) { 866 len = buf->length; 867 if(!BUF_MEM_grow_clean(buf, len + plen)) { 868 ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); 869 return 0; 870 } 871 memcpy(buf->data + len, *p, plen); 872 } 873 *p += plen; 874 return 1; 875 } 876 877 /* Check for ASN1 EOC and swallow it if found */ 878 879 static int asn1_check_eoc(unsigned char **in, long len) 880 { 881 unsigned char *p; 882 if(len < 2) return 0; 883 p = *in; 884 if(!p[0] && !p[1]) { 885 *in += 2; 886 return 1; 887 } 888 return 0; 889 } 890 891 /* Check an ASN1 tag and length: a bit like ASN1_get_object 892 * but it sets the length for indefinite length constructed 893 * form, we don't know the exact length but we can set an 894 * upper bound to the amount of data available minus the 895 * header length just read. 896 */ 897 898 static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, 899 unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx) 900 { 901 int i; 902 int ptag, pclass; 903 long plen; 904 unsigned char *p, *q; 905 p = *in; 906 q = p; 907 908 if(ctx && ctx->valid) { 909 i = ctx->ret; 910 plen = ctx->plen; 911 pclass = ctx->pclass; 912 ptag = ctx->ptag; 913 p += ctx->hdrlen; 914 } else { 915 i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); 916 if(ctx) { 917 ctx->ret = i; 918 ctx->plen = plen; 919 ctx->pclass = pclass; 920 ctx->ptag = ptag; 921 ctx->hdrlen = p - q; 922 ctx->valid = 1; 923 /* If definite length, and no error, length + 924 * header can't exceed total amount of data available. 925 */ 926 if(!(i & 0x81) && ((plen + ctx->hdrlen) > len)) { 927 ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); 928 asn1_tlc_clear(ctx); 929 return 0; 930 } 931 } 932 } 933 934 if(i & 0x80) { 935 ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER); 936 asn1_tlc_clear(ctx); 937 return 0; 938 } 939 if(exptag >= 0) { 940 if((exptag != ptag) || (expclass != pclass)) { 941 /* If type is OPTIONAL, not an error, but indicate missing 942 * type. 943 */ 944 if(opt) return -1; 945 asn1_tlc_clear(ctx); 946 ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG); 947 return 0; 948 } 949 /* We have a tag and class match, so assume we are going to do something with it */ 950 asn1_tlc_clear(ctx); 951 } 952 953 if(i & 1) plen = len - (p - q); 954 955 if(inf) *inf = i & 1; 956 957 if(cst) *cst = i & V_ASN1_CONSTRUCTED; 958 959 if(olen) *olen = plen; 960 if(oclass) *oclass = pclass; 961 if(otag) *otag = ptag; 962 963 *in = p; 964 return 1; 965 } 966