tasn_dec.c revision 291854
1249109Sjkim/* tasn_dec.c */ 2249109Sjkim/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3249109Sjkim * project 2000. 4249109Sjkim */ 5249109Sjkim/* ==================================================================== 6249109Sjkim * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. 7316303Sjkim * 8316303Sjkim * Redistribution and use in source and binary forms, with or without 9316303Sjkim * modification, are permitted provided that the following conditions 10316303Sjkim * are met: 11316303Sjkim * 12249109Sjkim * 1. Redistributions of source code must retain the above copyright 13249109Sjkim * notice, this list of conditions and the following disclaimer. 14316303Sjkim * 15316303Sjkim * 2. Redistributions in binary form must reproduce the above copyright 16316303Sjkim * notice, this list of conditions and the following disclaimer in 17316303Sjkim * the documentation and/or other materials provided with the 18316303Sjkim * distribution. 19316303Sjkim * 20316303Sjkim * 3. All advertising materials mentioning features or use of this 21316303Sjkim * software must display the following acknowledgment: 22316303Sjkim * "This product includes software developed by the OpenSSL Project 23316303Sjkim * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24316303Sjkim * 25316303Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26316303Sjkim * endorse or promote products derived from this software without 27316303Sjkim * prior written permission. For written permission, please contact 28316303Sjkim * licensing@OpenSSL.org. 29316303Sjkim * 30316303Sjkim * 5. Products derived from this software may not be called "OpenSSL" 31316303Sjkim * nor may "OpenSSL" appear in their names without prior written 32316303Sjkim * permission of the OpenSSL Project. 33316303Sjkim * 34316303Sjkim * 6. Redistributions of any form whatsoever must retain the following 35316303Sjkim * acknowledgment: 36316303Sjkim * "This product includes software developed by the OpenSSL Project 37316303Sjkim * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38316303Sjkim * 39316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40316303Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42316303Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43316303Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45316303Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46316303Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47316303Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48316303Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49316303Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50316303Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 51316303Sjkim * ==================================================================== 52316303Sjkim * 53316303Sjkim * This product includes cryptographic software written by Eric Young 54316303Sjkim * (eay@cryptsoft.com). This product includes software written by Tim 55316303Sjkim * Hudson (tjh@cryptsoft.com). 56316303Sjkim * 57316303Sjkim */ 58316303Sjkim 59316303Sjkim 60316303Sjkim#include <stddef.h> 61316303Sjkim#include <string.h> 62316303Sjkim#include <openssl/asn1.h> 63316303Sjkim#include <openssl/asn1t.h> 64316303Sjkim#include <openssl/objects.h> 65316303Sjkim#include <openssl/buffer.h> 66316303Sjkim#include <openssl/err.h> 67316303Sjkim 68316303Sjkimstatic int asn1_check_eoc(const unsigned char **in, long len); 69316303Sjkimstatic int asn1_find_end(const unsigned char **in, long len, char inf); 70316303Sjkim 71316303Sjkimstatic int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, 72316303Sjkim char inf, int tag, int aclass, int depth); 73316303Sjkim 74316303Sjkimstatic int collect_data(BUF_MEM *buf, const unsigned char **p, long plen); 75316303Sjkim 76316303Sjkimstatic int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, 77316303Sjkim char *inf, char *cst, 78316303Sjkim const unsigned char **in, long len, 79316303Sjkim int exptag, int expclass, char opt, 80316303Sjkim ASN1_TLC *ctx); 81316303Sjkim 82316303Sjkimstatic int asn1_template_ex_d2i(ASN1_VALUE **pval, 83316303Sjkim const unsigned char **in, long len, 84316303Sjkim const ASN1_TEMPLATE *tt, char opt, 85316303Sjkim ASN1_TLC *ctx); 86316303Sjkimstatic int asn1_template_noexp_d2i(ASN1_VALUE **val, 87316303Sjkim const unsigned char **in, long len, 88316303Sjkim const ASN1_TEMPLATE *tt, char opt, 89316303Sjkim ASN1_TLC *ctx); 90316303Sjkimstatic int asn1_d2i_ex_primitive(ASN1_VALUE **pval, 91316303Sjkim const unsigned char **in, long len, 92316303Sjkim const ASN1_ITEM *it, 93316303Sjkim int tag, int aclass, char opt, ASN1_TLC *ctx); 94316303Sjkim 95316303Sjkim/* Table to convert tags to bit values, used for MSTRING type */ 96316303Sjkimstatic const unsigned long tag2bit[32] = { 97316303Sjkim0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */ 98316303SjkimB_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,/* tags 4- 7 */ 99316303SjkimB_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags 8-11 */ 100316303SjkimB_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */ 101316303SjkimB_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */ 102316303SjkimB_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING, /* tags 20-22 */ 103316303SjkimB_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */ 104316303SjkimB_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING, /* tags 25-27 */ 105316303SjkimB_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */ 106316303Sjkim }; 107316303Sjkim 108316303Sjkimunsigned long ASN1_tag2bit(int tag) 109316303Sjkim { 110316303Sjkim if ((tag < 0) || (tag > 30)) return 0; 111316303Sjkim return tag2bit[tag]; 112316303Sjkim } 113316303Sjkim 114316303Sjkim/* Macro to initialize and invalidate the cache */ 115316303Sjkim 116316303Sjkim#define asn1_tlc_clear(c) if (c) (c)->valid = 0 117316303Sjkim 118316303Sjkim/* Decode an ASN1 item, this currently behaves just 119249109Sjkim * like a standard 'd2i' function. 'in' points to 120249109Sjkim * a buffer to read the data from, in future we will 121249109Sjkim * have more advanced versions that can input data 122249109Sjkim * a piece at a time and this will simply be a special 123249109Sjkim * case. 124249109Sjkim */ 125249109Sjkim 126249109SjkimASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, 127249109Sjkim const unsigned char **in, long len, const ASN1_ITEM *it) 128249109Sjkim { 129249109Sjkim ASN1_TLC c; 130249109Sjkim ASN1_VALUE *ptmpval = NULL; 131249109Sjkim if (!pval) 132249109Sjkim pval = &ptmpval; 133249109Sjkim c.valid = 0; 134316303Sjkim if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 135316303Sjkim return *pval; 136316303Sjkim return NULL; 137316303Sjkim } 138316303Sjkim 139316303Sjkimint ASN1_template_d2i(ASN1_VALUE **pval, 140316303Sjkim const unsigned char **in, long len, const ASN1_TEMPLATE *tt) 141316303Sjkim { 142316303Sjkim ASN1_TLC c; 143316303Sjkim c.valid = 0; 144316303Sjkim return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); 145316303Sjkim } 146316303Sjkim 147249109Sjkim 148249109Sjkim/* Decode an item, taking care of IMPLICIT tagging, if any. 149249109Sjkim * If 'opt' set and tag mismatch return -1 to handle OPTIONAL 150316303Sjkim */ 151249109Sjkim 152249112Sjkimint ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, 153249109Sjkim const ASN1_ITEM *it, 154249109Sjkim int tag, int aclass, char opt, ASN1_TLC *ctx) 155249109Sjkim { 156249109Sjkim const ASN1_TEMPLATE *tt, *errtt = NULL; 157249109Sjkim const ASN1_COMPAT_FUNCS *cf; 158249109Sjkim const ASN1_EXTERN_FUNCS *ef; 159249109Sjkim const ASN1_AUX *aux = it->funcs; 160249109Sjkim ASN1_aux_cb *asn1_cb; 161249109Sjkim const unsigned char *p = NULL, *q; 162249109Sjkim unsigned char *wp=NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */ 163249109Sjkim unsigned char imphack = 0, oclass; 164249109Sjkim char seq_eoc, seq_nolen, cst, isopt; 165249109Sjkim long tmplen; 166249109Sjkim int i; 167249109Sjkim int otag; 168249109Sjkim int ret = 0; 169249109Sjkim ASN1_VALUE **pchptr, *ptmpval; 170249109Sjkim int combine = aclass & ASN1_TFLG_COMBINE; 171249109Sjkim aclass &= ~ASN1_TFLG_COMBINE; 172249109Sjkim if (!pval) 173249109Sjkim return 0; 174249109Sjkim if (aux && aux->asn1_cb) 175249109Sjkim asn1_cb = aux->asn1_cb; 176249109Sjkim else asn1_cb = 0; 177249109Sjkim 178249109Sjkim switch(it->itype) 179249109Sjkim { 180249109Sjkim case ASN1_ITYPE_PRIMITIVE: 181249109Sjkim if (it->templates) 182249109Sjkim { 183249109Sjkim /* tagging or OPTIONAL is currently illegal on an item 184249109Sjkim * template because the flags can't get passed down. 185249109Sjkim * In practice this isn't a problem: we include the 186249109Sjkim * relevant flags from the item template in the 187249109Sjkim * template itself. 188249109Sjkim */ 189249109Sjkim if ((tag != -1) || opt) 190249109Sjkim { 191249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 192249109Sjkim ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); 193249109Sjkim goto err; 194249109Sjkim } 195249109Sjkim return asn1_template_ex_d2i(pval, in, len, 196249109Sjkim it->templates, opt, ctx); 197249109Sjkim } 198249109Sjkim return asn1_d2i_ex_primitive(pval, in, len, it, 199298714Sjkim tag, aclass, opt, ctx); 200249109Sjkim break; 201249109Sjkim 202249109Sjkim case ASN1_ITYPE_MSTRING: 203249109Sjkim p = *in; 204249109Sjkim /* Just read in tag and class */ 205249109Sjkim ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, 206249109Sjkim &p, len, -1, 0, 1, ctx); 207249109Sjkim if (!ret) 208249109Sjkim { 209249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 210249109Sjkim ERR_R_NESTED_ASN1_ERROR); 211249109Sjkim goto err; 212249109Sjkim } 213249109Sjkim 214249109Sjkim /* Must be UNIVERSAL class */ 215249109Sjkim if (oclass != V_ASN1_UNIVERSAL) 216249109Sjkim { 217249109Sjkim /* If OPTIONAL, assume this is OK */ 218249109Sjkim if (opt) return -1; 219249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 220249109Sjkim ASN1_R_MSTRING_NOT_UNIVERSAL); 221249109Sjkim goto err; 222249109Sjkim } 223249109Sjkim /* Check tag matches bit map */ 224249109Sjkim if (!(ASN1_tag2bit(otag) & it->utype)) 225249109Sjkim { 226249109Sjkim /* If OPTIONAL, assume this is OK */ 227249109Sjkim if (opt) 228249109Sjkim return -1; 229249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 230249109Sjkim ASN1_R_MSTRING_WRONG_TAG); 231249109Sjkim goto err; 232249109Sjkim } 233249109Sjkim return asn1_d2i_ex_primitive(pval, in, len, 234249109Sjkim it, otag, 0, 0, ctx); 235249109Sjkim 236249109Sjkim case ASN1_ITYPE_EXTERN: 237249109Sjkim /* Use new style d2i */ 238249109Sjkim ef = it->funcs; 239249109Sjkim return ef->asn1_ex_d2i(pval, in, len, 240249109Sjkim it, tag, aclass, opt, ctx); 241249109Sjkim 242249109Sjkim case ASN1_ITYPE_COMPAT: 243249109Sjkim /* we must resort to old style evil hackery */ 244249109Sjkim cf = it->funcs; 245249109Sjkim 246249109Sjkim /* If OPTIONAL see if it is there */ 247249109Sjkim if (opt) 248249109Sjkim { 249249109Sjkim int exptag; 250249109Sjkim p = *in; 251249109Sjkim if (tag == -1) 252249109Sjkim exptag = it->utype; 253249109Sjkim else exptag = tag; 254249109Sjkim /* Don't care about anything other than presence 255249109Sjkim * of expected tag */ 256249109Sjkim 257249109Sjkim ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, 258249109Sjkim &p, len, exptag, aclass, 1, ctx); 259249109Sjkim if (!ret) 260249109Sjkim { 261249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 262249109Sjkim ERR_R_NESTED_ASN1_ERROR); 263249109Sjkim goto err; 264249109Sjkim } 265249109Sjkim if (ret == -1) 266249109Sjkim return -1; 267249109Sjkim } 268249109Sjkim 269249109Sjkim /* This is the old style evil hack IMPLICIT handling: 270249109Sjkim * since the underlying code is expecting a tag and 271249109Sjkim * class other than the one present we change the 272249109Sjkim * buffer temporarily then change it back afterwards. 273249109Sjkim * This doesn't and never did work for tags > 30. 274249109Sjkim * 275249109Sjkim * Yes this is *horrible* but it is only needed for 276249109Sjkim * old style d2i which will hopefully not be around 277249109Sjkim * for much longer. 278249109Sjkim * FIXME: should copy the buffer then modify it so 279249109Sjkim * the input buffer can be const: we should *always* 280249109Sjkim * copy because the old style d2i might modify the 281249109Sjkim * buffer. 282249109Sjkim */ 283249109Sjkim 284249109Sjkim if (tag != -1) 285249109Sjkim { 286249109Sjkim wp = *(unsigned char **)in; 287249109Sjkim imphack = *wp; 288249109Sjkim if (p == NULL) 289249109Sjkim { 290249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 291249109Sjkim ERR_R_NESTED_ASN1_ERROR); 292249109Sjkim goto err; 293249109Sjkim } 294249109Sjkim *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED) 295249109Sjkim | it->utype); 296249109Sjkim } 297249109Sjkim 298249109Sjkim ptmpval = cf->asn1_d2i(pval, in, len); 299249109Sjkim 300249109Sjkim if (tag != -1) 301249109Sjkim *wp = imphack; 302249109Sjkim 303249109Sjkim if (ptmpval) 304249109Sjkim return 1; 305249109Sjkim 306249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 307249109Sjkim goto err; 308249109Sjkim 309249109Sjkim 310249109Sjkim case ASN1_ITYPE_CHOICE: 311249109Sjkim if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) 312249109Sjkim goto auxerr; 313249109Sjkim 314249109Sjkim if (*pval) { 315249109Sjkim /* Free up and zero CHOICE value if initialised */ 316249109Sjkim i = asn1_get_choice_selector(pval, it); 317249109Sjkim if ((i >= 0) && (i < it->tcount)) { 318249109Sjkim tt = it->templates + i; 319249109Sjkim pchptr = asn1_get_field_ptr(pval, tt); 320249109Sjkim ASN1_template_free(pchptr, tt); 321249109Sjkim asn1_set_choice_selector(pval, -1, it); 322249109Sjkim } 323249109Sjkim } else if (!ASN1_item_ex_new(pval, it)) { 324249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 325249109Sjkim ERR_R_NESTED_ASN1_ERROR); 326249109Sjkim goto err; 327249109Sjkim } 328249109Sjkim /* CHOICE type, try each possibility in turn */ 329249109Sjkim p = *in; 330249109Sjkim for (i = 0, tt=it->templates; i < it->tcount; i++, tt++) 331249109Sjkim { 332249109Sjkim pchptr = asn1_get_field_ptr(pval, tt); 333249109Sjkim /* We mark field as OPTIONAL so its absence 334249109Sjkim * can be recognised. 335249109Sjkim */ 336249109Sjkim ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); 337249109Sjkim /* If field not present, try the next one */ 338249109Sjkim if (ret == -1) 339249109Sjkim continue; 340249109Sjkim /* If positive return, read OK, break loop */ 341249109Sjkim if (ret > 0) 342249109Sjkim break; 343249109Sjkim /* Otherwise must be an ASN1 parsing error */ 344249109Sjkim errtt = tt; 345249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 346249109Sjkim ERR_R_NESTED_ASN1_ERROR); 347249109Sjkim goto err; 348249109Sjkim } 349249109Sjkim 350249109Sjkim /* Did we fall off the end without reading anything? */ 351249109Sjkim if (i == it->tcount) 352249109Sjkim { 353249109Sjkim /* If OPTIONAL, this is OK */ 354249109Sjkim if (opt) 355249109Sjkim { 356249109Sjkim /* Free and zero it */ 357249109Sjkim ASN1_item_ex_free(pval, it); 358249109Sjkim return -1; 359249109Sjkim } 360249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 361249109Sjkim ASN1_R_NO_MATCHING_CHOICE_TYPE); 362250838Sjkim goto err; 363249109Sjkim } 364250838Sjkim 365249109Sjkim asn1_set_choice_selector(pval, i, it); 366249109Sjkim *in = p; 367249109Sjkim if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) 368249109Sjkim goto auxerr; 369249109Sjkim return 1; 370249109Sjkim 371249109Sjkim case ASN1_ITYPE_NDEF_SEQUENCE: 372249109Sjkim case ASN1_ITYPE_SEQUENCE: 373249109Sjkim p = *in; 374249109Sjkim tmplen = len; 375249109Sjkim 376249109Sjkim /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ 377249109Sjkim if (tag == -1) 378249109Sjkim { 379249109Sjkim tag = V_ASN1_SEQUENCE; 380249109Sjkim aclass = V_ASN1_UNIVERSAL; 381249109Sjkim } 382249109Sjkim /* Get SEQUENCE length and update len, p */ 383249109Sjkim ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, 384249109Sjkim &p, len, tag, aclass, opt, ctx); 385249109Sjkim if (!ret) 386249109Sjkim { 387249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 388249109Sjkim ERR_R_NESTED_ASN1_ERROR); 389249109Sjkim goto err; 390249109Sjkim } 391249109Sjkim else if (ret == -1) 392249109Sjkim return -1; 393249109Sjkim if (aux && (aux->flags & ASN1_AFLG_BROKEN)) 394249109Sjkim { 395249109Sjkim len = tmplen - (p - *in); 396249109Sjkim seq_nolen = 1; 397249109Sjkim } 398249109Sjkim /* If indefinite we don't do a length check */ 399249109Sjkim else seq_nolen = seq_eoc; 400249109Sjkim if (!cst) 401249109Sjkim { 402249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 403249109Sjkim ASN1_R_SEQUENCE_NOT_CONSTRUCTED); 404249109Sjkim goto err; 405249109Sjkim } 406249109Sjkim 407249109Sjkim if (!*pval && !ASN1_item_ex_new(pval, it)) 408249109Sjkim { 409249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 410249109Sjkim ERR_R_NESTED_ASN1_ERROR); 411249109Sjkim goto err; 412249109Sjkim } 413249109Sjkim 414249109Sjkim if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) 415249109Sjkim goto auxerr; 416249109Sjkim 417249109Sjkim /* Free up and zero any ADB found */ 418249109Sjkim for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { 419249109Sjkim if (tt->flags & ASN1_TFLG_ADB_MASK) { 420249109Sjkim const ASN1_TEMPLATE *seqtt; 421249109Sjkim ASN1_VALUE **pseqval; 422249109Sjkim seqtt = asn1_do_adb(pval, tt, 1); 423249109Sjkim pseqval = asn1_get_field_ptr(pval, seqtt); 424249109Sjkim ASN1_template_free(pseqval, seqtt); 425249109Sjkim } 426249109Sjkim } 427249109Sjkim 428249109Sjkim /* Get each field entry */ 429249109Sjkim for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) 430249109Sjkim { 431249109Sjkim const ASN1_TEMPLATE *seqtt; 432249109Sjkim ASN1_VALUE **pseqval; 433249109Sjkim seqtt = asn1_do_adb(pval, tt, 1); 434249109Sjkim if (!seqtt) 435249109Sjkim goto err; 436249109Sjkim pseqval = asn1_get_field_ptr(pval, seqtt); 437249109Sjkim /* Have we ran out of data? */ 438249109Sjkim if (!len) 439249109Sjkim break; 440249109Sjkim q = p; 441249109Sjkim if (asn1_check_eoc(&p, len)) 442249109Sjkim { 443249109Sjkim if (!seq_eoc) 444249109Sjkim { 445249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 446249109Sjkim ASN1_R_UNEXPECTED_EOC); 447249109Sjkim goto err; 448249109Sjkim } 449249109Sjkim len -= p - q; 450249109Sjkim seq_eoc = 0; 451249109Sjkim q = p; 452249109Sjkim break; 453249109Sjkim } 454249109Sjkim /* This determines the OPTIONAL flag value. The field 455249109Sjkim * cannot be omitted if it is the last of a SEQUENCE 456249109Sjkim * and there is still data to be read. This isn't 457249109Sjkim * strictly necessary but it increases efficiency in 458249109Sjkim * some cases. 459249109Sjkim */ 460249109Sjkim if (i == (it->tcount - 1)) 461249109Sjkim isopt = 0; 462249109Sjkim else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); 463249109Sjkim /* attempt to read in field, allowing each to be 464249109Sjkim * OPTIONAL */ 465249109Sjkim 466249109Sjkim ret = asn1_template_ex_d2i(pseqval, &p, len, 467249109Sjkim seqtt, isopt, ctx); 468249109Sjkim if (!ret) 469249109Sjkim { 470249109Sjkim errtt = seqtt; 471249109Sjkim goto err; 472249109Sjkim } 473249109Sjkim else if (ret == -1) 474249109Sjkim { 475249109Sjkim /* OPTIONAL component absent. 476249109Sjkim * Free and zero the field. 477249109Sjkim */ 478249109Sjkim ASN1_template_free(pseqval, seqtt); 479249109Sjkim continue; 480249109Sjkim } 481249109Sjkim /* Update length */ 482249109Sjkim len -= p - q; 483249109Sjkim } 484249109Sjkim 485249109Sjkim /* Check for EOC if expecting one */ 486249109Sjkim if (seq_eoc && !asn1_check_eoc(&p, len)) 487249109Sjkim { 488249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC); 489249109Sjkim goto err; 490249109Sjkim } 491249109Sjkim /* Check all data read */ 492249109Sjkim if (!seq_nolen && len) 493249109Sjkim { 494249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 495249109Sjkim ASN1_R_SEQUENCE_LENGTH_MISMATCH); 496249109Sjkim goto err; 497249109Sjkim } 498249109Sjkim 499249109Sjkim /* If we get here we've got no more data in the SEQUENCE, 500249109Sjkim * however we may not have read all fields so check all 501249109Sjkim * remaining are OPTIONAL and clear any that are. 502249109Sjkim */ 503249109Sjkim for (; i < it->tcount; tt++, i++) 504249109Sjkim { 505249109Sjkim const ASN1_TEMPLATE *seqtt; 506249109Sjkim seqtt = asn1_do_adb(pval, tt, 1); 507249109Sjkim if (!seqtt) 508249109Sjkim goto err; 509249109Sjkim if (seqtt->flags & ASN1_TFLG_OPTIONAL) 510249109Sjkim { 511249109Sjkim ASN1_VALUE **pseqval; 512249109Sjkim pseqval = asn1_get_field_ptr(pval, seqtt); 513249109Sjkim ASN1_template_free(pseqval, seqtt); 514249109Sjkim } 515249109Sjkim else 516249109Sjkim { 517249109Sjkim errtt = seqtt; 518249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 519249109Sjkim ASN1_R_FIELD_MISSING); 520249109Sjkim goto err; 521249109Sjkim } 522249109Sjkim } 523249109Sjkim /* Save encoding */ 524249109Sjkim if (!asn1_enc_save(pval, *in, p - *in, it)) 525249109Sjkim goto auxerr; 526249109Sjkim *in = p; 527249109Sjkim if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) 528249109Sjkim goto auxerr; 529249109Sjkim return 1; 530249109Sjkim 531249109Sjkim default: 532249109Sjkim return 0; 533249109Sjkim } 534249109Sjkim auxerr: 535249109Sjkim ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR); 536249109Sjkim err: 537249109Sjkim if (combine == 0) 538249109Sjkim ASN1_item_ex_free(pval, it); 539249109Sjkim if (errtt) 540249109Sjkim ERR_add_error_data(4, "Field=", errtt->field_name, 541249109Sjkim ", Type=", it->sname); 542249109Sjkim else 543249109Sjkim ERR_add_error_data(2, "Type=", it->sname); 544249109Sjkim return 0; 545249109Sjkim } 546249109Sjkim 547249109Sjkim/* Templates are handled with two separate functions. 548249109Sjkim * One handles any EXPLICIT tag and the other handles the rest. 549249109Sjkim */ 550249109Sjkim 551249109Sjkimstatic int asn1_template_ex_d2i(ASN1_VALUE **val, 552249109Sjkim const unsigned char **in, long inlen, 553249109Sjkim const ASN1_TEMPLATE *tt, char opt, 554249109Sjkim ASN1_TLC *ctx) 555249109Sjkim { 556249109Sjkim int flags, aclass; 557249109Sjkim int ret; 558249109Sjkim long len; 559249109Sjkim const unsigned char *p, *q; 560249109Sjkim char exp_eoc; 561249109Sjkim if (!val) 562249109Sjkim return 0; 563249109Sjkim flags = tt->flags; 564249109Sjkim aclass = flags & ASN1_TFLG_TAG_CLASS; 565249109Sjkim 566249109Sjkim p = *in; 567249109Sjkim 568249109Sjkim /* Check if EXPLICIT tag expected */ 569249109Sjkim if (flags & ASN1_TFLG_EXPTAG) 570249109Sjkim { 571249109Sjkim char cst; 572249109Sjkim /* Need to work out amount of data available to the inner 573249109Sjkim * content and where it starts: so read in EXPLICIT header to 574249109Sjkim * get the info. 575249109Sjkim */ 576249109Sjkim ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, 577249109Sjkim &p, inlen, tt->tag, aclass, opt, ctx); 578249109Sjkim q = p; 579249109Sjkim if (!ret) 580249109Sjkim { 581249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, 582249109Sjkim ERR_R_NESTED_ASN1_ERROR); 583249109Sjkim return 0; 584249109Sjkim } 585249109Sjkim else if (ret == -1) 586249109Sjkim return -1; 587249109Sjkim if (!cst) 588249109Sjkim { 589249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, 590249109Sjkim ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); 591249109Sjkim return 0; 592249109Sjkim } 593249109Sjkim /* We've found the field so it can't be OPTIONAL now */ 594249109Sjkim ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx); 595249109Sjkim if (!ret) 596249109Sjkim { 597249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, 598249109Sjkim ERR_R_NESTED_ASN1_ERROR); 599249109Sjkim return 0; 600249109Sjkim } 601249109Sjkim /* We read the field in OK so update length */ 602249109Sjkim len -= p - q; 603249109Sjkim if (exp_eoc) 604249109Sjkim { 605249109Sjkim /* If NDEF we must have an EOC here */ 606249109Sjkim if (!asn1_check_eoc(&p, len)) 607249109Sjkim { 608249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, 609249109Sjkim ASN1_R_MISSING_EOC); 610249109Sjkim goto err; 611249109Sjkim } 612249109Sjkim } 613249109Sjkim else 614249109Sjkim { 615249109Sjkim /* Otherwise we must hit the EXPLICIT tag end or its 616249109Sjkim * an error */ 617249109Sjkim if (len) 618249109Sjkim { 619249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, 620249109Sjkim ASN1_R_EXPLICIT_LENGTH_MISMATCH); 621249109Sjkim goto err; 622249109Sjkim } 623249109Sjkim } 624249109Sjkim } 625249109Sjkim else 626249109Sjkim return asn1_template_noexp_d2i(val, in, inlen, 627249109Sjkim tt, opt, ctx); 628249109Sjkim 629249109Sjkim *in = p; 630249109Sjkim return 1; 631249109Sjkim 632249109Sjkim err: 633249109Sjkim ASN1_template_free(val, tt); 634249109Sjkim return 0; 635249109Sjkim } 636249109Sjkim 637249109Sjkimstatic int asn1_template_noexp_d2i(ASN1_VALUE **val, 638249109Sjkim const unsigned char **in, long len, 639249109Sjkim const ASN1_TEMPLATE *tt, char opt, 640249109Sjkim ASN1_TLC *ctx) 641249109Sjkim { 642249109Sjkim int flags, aclass; 643249109Sjkim int ret; 644249109Sjkim const unsigned char *p, *q; 645249109Sjkim if (!val) 646249109Sjkim return 0; 647249109Sjkim flags = tt->flags; 648249109Sjkim aclass = flags & ASN1_TFLG_TAG_CLASS; 649249109Sjkim 650249109Sjkim p = *in; 651249109Sjkim q = p; 652249109Sjkim 653249109Sjkim if (flags & ASN1_TFLG_SK_MASK) 654249109Sjkim { 655249109Sjkim /* SET OF, SEQUENCE OF */ 656249109Sjkim int sktag, skaclass; 657249109Sjkim char sk_eoc; 658249109Sjkim /* First work out expected inner tag value */ 659249109Sjkim if (flags & ASN1_TFLG_IMPTAG) 660249109Sjkim { 661249109Sjkim sktag = tt->tag; 662249109Sjkim skaclass = aclass; 663249109Sjkim } 664249109Sjkim else 665249109Sjkim { 666249109Sjkim skaclass = V_ASN1_UNIVERSAL; 667249109Sjkim if (flags & ASN1_TFLG_SET_OF) 668249109Sjkim sktag = V_ASN1_SET; 669249109Sjkim else 670249109Sjkim sktag = V_ASN1_SEQUENCE; 671249109Sjkim } 672249109Sjkim /* Get the tag */ 673249109Sjkim ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, 674249109Sjkim &p, len, sktag, skaclass, opt, ctx); 675249109Sjkim if (!ret) 676249109Sjkim { 677249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 678249109Sjkim ERR_R_NESTED_ASN1_ERROR); 679249109Sjkim return 0; 680249109Sjkim } 681249109Sjkim else if (ret == -1) 682249109Sjkim return -1; 683249109Sjkim if (!*val) 684249109Sjkim *val = (ASN1_VALUE *)sk_new_null(); 685249109Sjkim else 686249109Sjkim { 687298714Sjkim /* We've got a valid STACK: free up any items present */ 688249109Sjkim STACK *sktmp = (STACK *)*val; 689249109Sjkim ASN1_VALUE *vtmp; 690249109Sjkim while(sk_num(sktmp) > 0) 691249109Sjkim { 692249109Sjkim vtmp = (ASN1_VALUE *)sk_pop(sktmp); 693249109Sjkim ASN1_item_ex_free(&vtmp, 694249109Sjkim ASN1_ITEM_ptr(tt->item)); 695249109Sjkim } 696249109Sjkim } 697249109Sjkim 698249109Sjkim if (!*val) 699249109Sjkim { 700249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 701249109Sjkim ERR_R_MALLOC_FAILURE); 702249109Sjkim goto err; 703249109Sjkim } 704249109Sjkim 705249109Sjkim /* Read as many items as we can */ 706249109Sjkim while(len > 0) 707249109Sjkim { 708249109Sjkim ASN1_VALUE *skfield; 709249109Sjkim q = p; 710249109Sjkim /* See if EOC found */ 711249109Sjkim if (asn1_check_eoc(&p, len)) 712249109Sjkim { 713249109Sjkim if (!sk_eoc) 714249109Sjkim { 715249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 716249109Sjkim ASN1_R_UNEXPECTED_EOC); 717249109Sjkim goto err; 718249109Sjkim } 719249109Sjkim len -= p - q; 720249109Sjkim sk_eoc = 0; 721249109Sjkim break; 722249109Sjkim } 723249109Sjkim skfield = NULL; 724249109Sjkim if (!ASN1_item_ex_d2i(&skfield, &p, len, 725249109Sjkim ASN1_ITEM_ptr(tt->item), 726249109Sjkim -1, 0, 0, ctx)) 727249109Sjkim { 728249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 729249109Sjkim ERR_R_NESTED_ASN1_ERROR); 730249109Sjkim goto err; 731250838Sjkim } 732249109Sjkim len -= p - q; 733250838Sjkim if (!sk_push((STACK *)*val, (char *)skfield)) 734249109Sjkim { 735249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 736249109Sjkim ERR_R_MALLOC_FAILURE); 737249109Sjkim goto err; 738249109Sjkim } 739249109Sjkim } 740249109Sjkim if (sk_eoc) 741249109Sjkim { 742249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC); 743249109Sjkim goto err; 744249109Sjkim } 745249109Sjkim } 746249109Sjkim else if (flags & ASN1_TFLG_IMPTAG) 747249109Sjkim { 748249109Sjkim /* IMPLICIT tagging */ 749249109Sjkim ret = ASN1_item_ex_d2i(val, &p, len, 750249109Sjkim ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx); 751249109Sjkim if (!ret) 752249109Sjkim { 753249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 754249109Sjkim ERR_R_NESTED_ASN1_ERROR); 755249109Sjkim goto err; 756249109Sjkim } 757249109Sjkim else if (ret == -1) 758249109Sjkim return -1; 759249109Sjkim } 760249109Sjkim else 761249109Sjkim { 762249109Sjkim /* Nothing special */ 763249109Sjkim ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), 764249109Sjkim -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx); 765249109Sjkim if (!ret) 766249109Sjkim { 767249109Sjkim ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 768249109Sjkim ERR_R_NESTED_ASN1_ERROR); 769249109Sjkim goto err; 770249109Sjkim } 771249109Sjkim else if (ret == -1) 772249109Sjkim return -1; 773249109Sjkim } 774249109Sjkim 775249109Sjkim *in = p; 776249109Sjkim return 1; 777249109Sjkim 778249109Sjkim err: 779249109Sjkim ASN1_template_free(val, tt); 780249109Sjkim return 0; 781249109Sjkim } 782249109Sjkim 783249109Sjkimstatic int asn1_d2i_ex_primitive(ASN1_VALUE **pval, 784249109Sjkim const unsigned char **in, long inlen, 785249109Sjkim const ASN1_ITEM *it, 786249109Sjkim int tag, int aclass, char opt, ASN1_TLC *ctx) 787249109Sjkim { 788249109Sjkim int ret = 0, utype; 789249109Sjkim long plen; 790249109Sjkim char cst, inf, free_cont = 0; 791249109Sjkim const unsigned char *p; 792249109Sjkim BUF_MEM buf; 793249109Sjkim const unsigned char *cont = NULL; 794249109Sjkim long len; 795249109Sjkim if (!pval) 796249109Sjkim { 797249109Sjkim ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL); 798249109Sjkim return 0; /* Should never happen */ 799249109Sjkim } 800249109Sjkim 801249109Sjkim if (it->itype == ASN1_ITYPE_MSTRING) 802249109Sjkim { 803249109Sjkim utype = tag; 804249109Sjkim tag = -1; 805249109Sjkim } 806249109Sjkim else 807249109Sjkim utype = it->utype; 808249109Sjkim 809249109Sjkim if (utype == V_ASN1_ANY) 810249109Sjkim { 811249109Sjkim /* If type is ANY need to figure out type from tag */ 812249109Sjkim unsigned char oclass; 813249109Sjkim if (tag >= 0) 814249109Sjkim { 815249109Sjkim ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, 816249109Sjkim ASN1_R_ILLEGAL_TAGGED_ANY); 817249109Sjkim return 0; 818249109Sjkim } 819249109Sjkim 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