tasn_dec.c revision 296465
142680Smsmith/* tasn_dec.c */ 242680Smsmith/* 342680Smsmith * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 442680Smsmith * 2000. 542680Smsmith */ 642680Smsmith/* ==================================================================== 742680Smsmith * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. 842680Smsmith * 942680Smsmith * Redistribution and use in source and binary forms, with or without 1042680Smsmith * modification, are permitted provided that the following conditions 1142680Smsmith * are met: 1242680Smsmith * 1342680Smsmith * 1. Redistributions of source code must retain the above copyright 1442680Smsmith * notice, this list of conditions and the following disclaimer. 1542680Smsmith * 1642680Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1742680Smsmith * notice, this list of conditions and the following disclaimer in 1842680Smsmith * the documentation and/or other materials provided with the 1942680Smsmith * distribution. 2042680Smsmith * 2142680Smsmith * 3. All advertising materials mentioning features or use of this 2242680Smsmith * software must display the following acknowledgment: 2342680Smsmith * "This product includes software developed by the OpenSSL Project 2442680Smsmith * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2542680Smsmith * 2642680Smsmith * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2742680Smsmith * endorse or promote products derived from this software without 2842680Smsmith * prior written permission. For written permission, please contact 2942680Smsmith * licensing@OpenSSL.org. 3042680Smsmith * 3142680Smsmith * 5. Products derived from this software may not be called "OpenSSL" 3242680Smsmith * nor may "OpenSSL" appear in their names without prior written 3352757Sphk * permission of the OpenSSL Project. 3452757Sphk * 3542680Smsmith * 6. Redistributions of any form whatsoever must retain the following 3642680Smsmith * acknowledgment: 37116182Sobrien * "This product includes software developed by the OpenSSL Project 38116182Sobrien * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39116182Sobrien * 4042680Smsmith * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4142680Smsmith * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4252843Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43114216Skan * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44351760Smav * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4542680Smsmith * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4642680Smsmith * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4742680Smsmith * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4842680Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4942680Smsmith * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5042680Smsmith * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5142680Smsmith * OF THE POSSIBILITY OF SUCH DAMAGE. 5242680Smsmith * ==================================================================== 5342680Smsmith * 5442680Smsmith * This product includes cryptographic software written by Eric Young 5542680Smsmith * (eay@cryptsoft.com). This product includes software written by Tim 5642680Smsmith * Hudson (tjh@cryptsoft.com). 5742680Smsmith * 5842680Smsmith */ 5942680Smsmith 6042680Smsmith#include <stddef.h> 6142680Smsmith#include <string.h> 6242680Smsmith#include <openssl/asn1.h> 63351760Smav#include <openssl/asn1t.h> 64351760Smav#include <openssl/objects.h> 65351760Smav#include <openssl/buffer.h> 66230587Sken#include <openssl/err.h> 6742680Smsmith 6842680Smsmithstatic int asn1_check_eoc(const unsigned char **in, long len); 6942680Smsmithstatic int asn1_find_end(const unsigned char **in, long len, char inf); 7042680Smsmith 7142680Smsmithstatic int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, 7242680Smsmith char inf, int tag, int aclass, int depth); 7342680Smsmith 7442680Smsmithstatic int collect_data(BUF_MEM *buf, const unsigned char **p, long plen); 7542680Smsmith 7642680Smsmithstatic int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, 7742680Smsmith char *inf, char *cst, 7842680Smsmith const unsigned char **in, long len, 7942680Smsmith int exptag, int expclass, char opt, ASN1_TLC *ctx); 8042680Smsmith 8142680Smsmithstatic int asn1_template_ex_d2i(ASN1_VALUE **pval, 8242680Smsmith const unsigned char **in, long len, 8342680Smsmith const ASN1_TEMPLATE *tt, char opt, 8442680Smsmith ASN1_TLC *ctx); 8542680Smsmithstatic int asn1_template_noexp_d2i(ASN1_VALUE **val, 8642680Smsmith const unsigned char **in, long len, 8742680Smsmith const ASN1_TEMPLATE *tt, char opt, 8842680Smsmith ASN1_TLC *ctx); 8953648Sarchiestatic int asn1_d2i_ex_primitive(ASN1_VALUE **pval, 9042680Smsmith const unsigned char **in, long len, 9143300Sdillon const ASN1_ITEM *it, 9242680Smsmith int tag, int aclass, char opt, 9342680Smsmith ASN1_TLC *ctx); 9442680Smsmith 9542680Smsmith/* Table to convert tags to bit values, used for MSTRING type */ 9642680Smsmithstatic const unsigned long tag2bit[32] = { 9742680Smsmith /* tags 0 - 3 */ 9842680Smsmith 0, 0, 0, B_ASN1_BIT_STRING, 9942680Smsmith /* tags 4- 7 */ 10042680Smsmith B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN, 10142680Smsmith /* tags 8-11 */ 10242680Smsmith B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, 10342680Smsmith /* tags 12-15 */ 10442680Smsmith B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, 10542680Smsmith /* tags 16-19 */ 10642680Smsmith B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING, 10742680Smsmith /* tags 20-22 */ 10842680Smsmith B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING, 10943300Sdillon /* tags 23-24 */ 11042680Smsmith B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, 11142680Smsmith /* tags 25-27 */ 11242680Smsmith B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING, 11342680Smsmith /* tags 28-31 */ 11442680Smsmith B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN, 11542680Smsmith}; 11642680Smsmith 11742680Smsmithunsigned long ASN1_tag2bit(int tag) 11842680Smsmith{ 11942680Smsmith if ((tag < 0) || (tag > 30)) 12042680Smsmith return 0; 12142680Smsmith return tag2bit[tag]; 12242680Smsmith} 12342680Smsmith 12442680Smsmith/* Macro to initialize and invalidate the cache */ 12542680Smsmith 12642680Smsmith#define asn1_tlc_clear(c) if (c) (c)->valid = 0 12742680Smsmith 12842680Smsmith/* 12942680Smsmith * Decode an ASN1 item, this currently behaves just like a standard 'd2i' 13042680Smsmith * function. 'in' points to a buffer to read the data from, in future we 13142680Smsmith * will have more advanced versions that can input data a piece at a time and 13242680Smsmith * this will simply be a special case. 13342680Smsmith */ 13442680Smsmith 13542680SmsmithASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, 13642680Smsmith const unsigned char **in, long len, 13742680Smsmith const ASN1_ITEM *it) 13842680Smsmith{ 13942680Smsmith ASN1_TLC c; 14042680Smsmith ASN1_VALUE *ptmpval = NULL; 14142680Smsmith if (!pval) 14242680Smsmith pval = &ptmpval; 14342680Smsmith c.valid = 0; 14442680Smsmith if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 14542680Smsmith return *pval; 14642680Smsmith return NULL; 14742680Smsmith} 14842680Smsmith 14942680Smsmithint ASN1_template_d2i(ASN1_VALUE **pval, 15042680Smsmith const unsigned char **in, long len, 15142680Smsmith const ASN1_TEMPLATE *tt) 15242680Smsmith{ 15342680Smsmith ASN1_TLC c; 15442680Smsmith c.valid = 0; 15542680Smsmith return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); 15642680Smsmith} 15742680Smsmith 15842680Smsmith/* 15942680Smsmith * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and 16042680Smsmith * tag mismatch return -1 to handle OPTIONAL 16142680Smsmith */ 16242680Smsmith 16342680Smsmithint ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, 16442680Smsmith const ASN1_ITEM *it, 16542680Smsmith int tag, int aclass, char opt, ASN1_TLC *ctx) 16642680Smsmith{ 167351760Smav const ASN1_TEMPLATE *tt, *errtt = NULL; 168351760Smav const ASN1_COMPAT_FUNCS *cf; 169351760Smav const ASN1_EXTERN_FUNCS *ef; 17042680Smsmith const ASN1_AUX *aux = it->funcs; 171230587Sken ASN1_aux_cb *asn1_cb; 172230587Sken const unsigned char *p = NULL, *q; 173230587Sken unsigned char *wp = NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */ 174230587Sken unsigned char imphack = 0, oclass; 175230587Sken char seq_eoc, seq_nolen, cst, isopt; 176230587Sken long tmplen; 17742680Smsmith int i; 17842680Smsmith int otag; 17942680Smsmith int ret = 0; 18042680Smsmith ASN1_VALUE **pchptr, *ptmpval; 181351760Smav int combine = aclass & ASN1_TFLG_COMBINE; 182351760Smav aclass &= ~ASN1_TFLG_COMBINE; 183351760Smav if (!pval) 184351760Smav return 0; 185351760Smav if (aux && aux->asn1_cb) 186351760Smav asn1_cb = aux->asn1_cb; 18742680Smsmith else 188230587Sken asn1_cb = 0; 189230587Sken 190230587Sken switch (it->itype) { 191230587Sken case ASN1_ITYPE_PRIMITIVE: 192230587Sken if (it->templates) { 193230587Sken /* 19442680Smsmith * tagging or OPTIONAL is currently illegal on an item template 19542680Smsmith * because the flags can't get passed down. In practice this 19642680Smsmith * isn't a problem: we include the relevant flags from the item 19742680Smsmith * template in the template itself. 19842680Smsmith */ 19942680Smsmith if ((tag != -1) || opt) { 20042680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, 20142680Smsmith ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); 20242680Smsmith goto err; 20342680Smsmith } 20442680Smsmith return asn1_template_ex_d2i(pval, in, len, 20542680Smsmith it->templates, opt, ctx); 20642680Smsmith } 20742680Smsmith return asn1_d2i_ex_primitive(pval, in, len, it, 20842680Smsmith tag, aclass, opt, ctx); 20942680Smsmith break; 21042680Smsmith 21142680Smsmith case ASN1_ITYPE_MSTRING: 21242680Smsmith p = *in; 21342680Smsmith /* Just read in tag and class */ 21442680Smsmith ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, 21542680Smsmith &p, len, -1, 0, 1, ctx); 21642680Smsmith if (!ret) { 21742680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 21842680Smsmith goto err; 21942680Smsmith } 22042680Smsmith 22142680Smsmith /* Must be UNIVERSAL class */ 22242680Smsmith if (oclass != V_ASN1_UNIVERSAL) { 22342680Smsmith /* If OPTIONAL, assume this is OK */ 22442680Smsmith if (opt) 22542680Smsmith return -1; 22642680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL); 22742680Smsmith goto err; 22842680Smsmith } 22942680Smsmith /* Check tag matches bit map */ 23042680Smsmith if (!(ASN1_tag2bit(otag) & it->utype)) { 23142680Smsmith /* If OPTIONAL, assume this is OK */ 23242680Smsmith if (opt) 23342680Smsmith return -1; 23442680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG); 23542680Smsmith goto err; 23642680Smsmith } 23742680Smsmith return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx); 23842680Smsmith 23942680Smsmith case ASN1_ITYPE_EXTERN: 24042680Smsmith /* Use new style d2i */ 24142680Smsmith ef = it->funcs; 24242680Smsmith return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); 24342680Smsmith 24442680Smsmith case ASN1_ITYPE_COMPAT: 24542680Smsmith /* we must resort to old style evil hackery */ 24642680Smsmith cf = it->funcs; 24742680Smsmith 24842680Smsmith /* If OPTIONAL see if it is there */ 24942680Smsmith if (opt) { 25042680Smsmith int exptag; 25142680Smsmith p = *in; 25242680Smsmith if (tag == -1) 25342680Smsmith exptag = it->utype; 25442680Smsmith else 25542680Smsmith exptag = tag; 25642680Smsmith /* 25742680Smsmith * Don't care about anything other than presence of expected tag 25842680Smsmith */ 25942680Smsmith 26042680Smsmith ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, 26142680Smsmith &p, len, exptag, aclass, 1, ctx); 262230587Sken if (!ret) { 263230587Sken ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 264230587Sken goto err; 26542680Smsmith } 26642680Smsmith if (ret == -1) 26742680Smsmith return -1; 26842680Smsmith } 26942680Smsmith 270351760Smav /* 271351760Smav * This is the old style evil hack IMPLICIT handling: since the 272351760Smav * underlying code is expecting a tag and class other than the one 273351760Smav * present we change the buffer temporarily then change it back 274351760Smav * afterwards. This doesn't and never did work for tags > 30. Yes 275351760Smav * this is *horrible* but it is only needed for old style d2i which 27642680Smsmith * will hopefully not be around for much longer. FIXME: should copy 27742680Smsmith * the buffer then modify it so the input buffer can be const: we 27842680Smsmith * should *always* copy because the old style d2i might modify the 27942680Smsmith * buffer. 28042680Smsmith */ 28142680Smsmith 28242680Smsmith if (tag != -1) { 28342680Smsmith wp = *(unsigned char **)in; 28442680Smsmith imphack = *wp; 28542680Smsmith if (p == NULL) { 28642680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 28742680Smsmith goto err; 28842680Smsmith } 28942680Smsmith *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED) 29042680Smsmith | it->utype); 29142680Smsmith } 29242680Smsmith 29342680Smsmith ptmpval = cf->asn1_d2i(pval, in, len); 29442680Smsmith 29542680Smsmith if (tag != -1) 29642680Smsmith *wp = imphack; 29742680Smsmith 29842680Smsmith if (ptmpval) 29942680Smsmith return 1; 30042680Smsmith 30142680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 30242680Smsmith goto err; 30342680Smsmith 30442680Smsmith case ASN1_ITYPE_CHOICE: 30542680Smsmith if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) 30642680Smsmith goto auxerr; 30742680Smsmith if (*pval) { 30842680Smsmith /* Free up and zero CHOICE value if initialised */ 30942680Smsmith i = asn1_get_choice_selector(pval, it); 31042680Smsmith if ((i >= 0) && (i < it->tcount)) { 31142680Smsmith tt = it->templates + i; 31242680Smsmith pchptr = asn1_get_field_ptr(pval, tt); 31342680Smsmith ASN1_template_free(pchptr, tt); 31442680Smsmith asn1_set_choice_selector(pval, -1, it); 31542680Smsmith } 31642680Smsmith } else if (!ASN1_item_ex_new(pval, it)) { 31742680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 31842680Smsmith goto err; 31942680Smsmith } 32042680Smsmith /* CHOICE type, try each possibility in turn */ 32142680Smsmith p = *in; 32242680Smsmith for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { 32342680Smsmith pchptr = asn1_get_field_ptr(pval, tt); 324104363Sphk /* 32542680Smsmith * We mark field as OPTIONAL so its absence can be recognised. 32642680Smsmith */ 32742680Smsmith ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); 32842680Smsmith /* If field not present, try the next one */ 32942680Smsmith if (ret == -1) 33042680Smsmith continue; 33142680Smsmith /* If positive return, read OK, break loop */ 33242680Smsmith if (ret > 0) 33342680Smsmith break; 33442680Smsmith /* Otherwise must be an ASN1 parsing error */ 33542680Smsmith errtt = tt; 33642680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 33742680Smsmith goto err; 33842680Smsmith } 33942680Smsmith 34042680Smsmith /* Did we fall off the end without reading anything? */ 34142680Smsmith if (i == it->tcount) { 34242680Smsmith /* If OPTIONAL, this is OK */ 34342680Smsmith if (opt) { 34442680Smsmith /* Free and zero it */ 34542680Smsmith ASN1_item_ex_free(pval, it); 34642680Smsmith return -1; 34742680Smsmith } 34842680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE); 34942680Smsmith goto err; 35044016Sdillon } 35142680Smsmith 35242680Smsmith asn1_set_choice_selector(pval, i, it); 35342680Smsmith *in = p; 35442680Smsmith if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) 35542680Smsmith goto auxerr; 35642680Smsmith return 1; 35742680Smsmith 35842680Smsmith case ASN1_ITYPE_NDEF_SEQUENCE: 35942680Smsmith case ASN1_ITYPE_SEQUENCE: 36042680Smsmith p = *in; 36142680Smsmith tmplen = len; 36242680Smsmith 36342680Smsmith /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ 36444016Sdillon if (tag == -1) { 36542680Smsmith tag = V_ASN1_SEQUENCE; 36642680Smsmith aclass = V_ASN1_UNIVERSAL; 36742680Smsmith } 36842680Smsmith /* Get SEQUENCE length and update len, p */ 36942680Smsmith ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, 37042680Smsmith &p, len, tag, aclass, opt, ctx); 37142680Smsmith if (!ret) { 37242680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 37342680Smsmith goto err; 37442680Smsmith } else if (ret == -1) 37542680Smsmith return -1; 37642680Smsmith if (aux && (aux->flags & ASN1_AFLG_BROKEN)) { 37742680Smsmith len = tmplen - (p - *in); 37842680Smsmith seq_nolen = 1; 37942680Smsmith } 38042680Smsmith /* If indefinite we don't do a length check */ 38142680Smsmith else 38242680Smsmith seq_nolen = seq_eoc; 38342680Smsmith if (!cst) { 38442680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); 38542680Smsmith goto err; 38642680Smsmith } 38742680Smsmith 38842680Smsmith if (!*pval && !ASN1_item_ex_new(pval, it)) { 38942680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 39042680Smsmith goto err; 39142680Smsmith } 39242680Smsmith 39342680Smsmith if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) 39442680Smsmith goto auxerr; 39542680Smsmith 39642680Smsmith /* Free up and zero any ADB found */ 39742680Smsmith for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { 39842680Smsmith if (tt->flags & ASN1_TFLG_ADB_MASK) { 39942680Smsmith const ASN1_TEMPLATE *seqtt; 40042680Smsmith ASN1_VALUE **pseqval; 40142680Smsmith seqtt = asn1_do_adb(pval, tt, 1); 40242680Smsmith pseqval = asn1_get_field_ptr(pval, seqtt); 40342680Smsmith ASN1_template_free(pseqval, seqtt); 40442680Smsmith } 40542680Smsmith } 40642680Smsmith 40742680Smsmith /* Get each field entry */ 40842680Smsmith for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { 40942680Smsmith const ASN1_TEMPLATE *seqtt; 41042680Smsmith ASN1_VALUE **pseqval; 41142680Smsmith seqtt = asn1_do_adb(pval, tt, 1); 41242680Smsmith if (!seqtt) 41342680Smsmith goto err; 41442680Smsmith pseqval = asn1_get_field_ptr(pval, seqtt); 41542680Smsmith /* Have we ran out of data? */ 41642680Smsmith if (!len) 41742680Smsmith break; 41842680Smsmith q = p; 41942680Smsmith if (asn1_check_eoc(&p, len)) { 42042680Smsmith if (!seq_eoc) { 42142680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC); 42242680Smsmith goto err; 42342680Smsmith } 42442680Smsmith len -= p - q; 42542680Smsmith seq_eoc = 0; 42642680Smsmith q = p; 42742680Smsmith break; 42842680Smsmith } 42942680Smsmith /* 43042680Smsmith * This determines the OPTIONAL flag value. The field cannot be 43142680Smsmith * omitted if it is the last of a SEQUENCE and there is still 43242680Smsmith * data to be read. This isn't strictly necessary but it 43342680Smsmith * increases efficiency in some cases. 43442680Smsmith */ 43542680Smsmith if (i == (it->tcount - 1)) 43642680Smsmith isopt = 0; 43742680Smsmith else 43842680Smsmith isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); 43942680Smsmith /* 44042680Smsmith * attempt to read in field, allowing each to be OPTIONAL 44142680Smsmith */ 44242680Smsmith 44342680Smsmith ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx); 44442680Smsmith if (!ret) { 44542680Smsmith errtt = seqtt; 44642680Smsmith goto err; 44742680Smsmith } else if (ret == -1) { 44842680Smsmith /* 44942680Smsmith * OPTIONAL component absent. Free and zero the field. 45042680Smsmith */ 45142680Smsmith ASN1_template_free(pseqval, seqtt); 45242680Smsmith continue; 45342680Smsmith } 45442680Smsmith /* Update length */ 45542680Smsmith len -= p - q; 45642680Smsmith } 45742680Smsmith 45842680Smsmith /* Check for EOC if expecting one */ 45942680Smsmith if (seq_eoc && !asn1_check_eoc(&p, len)) { 46042680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC); 46142680Smsmith goto err; 46242680Smsmith } 46342680Smsmith /* Check all data read */ 46442680Smsmith if (!seq_nolen && len) { 46542680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH); 46642680Smsmith goto err; 46742680Smsmith } 46842680Smsmith 46942680Smsmith /* 47042680Smsmith * If we get here we've got no more data in the SEQUENCE, however we 47142680Smsmith * may not have read all fields so check all remaining are OPTIONAL 47242680Smsmith * and clear any that are. 47342680Smsmith */ 47442680Smsmith for (; i < it->tcount; tt++, i++) { 47542680Smsmith const ASN1_TEMPLATE *seqtt; 47642680Smsmith seqtt = asn1_do_adb(pval, tt, 1); 47742680Smsmith if (!seqtt) 47842680Smsmith goto err; 47942680Smsmith if (seqtt->flags & ASN1_TFLG_OPTIONAL) { 48042680Smsmith ASN1_VALUE **pseqval; 48142680Smsmith pseqval = asn1_get_field_ptr(pval, seqtt); 48242680Smsmith ASN1_template_free(pseqval, seqtt); 48342680Smsmith } else { 48442680Smsmith errtt = seqtt; 48542680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING); 48642680Smsmith goto err; 48742680Smsmith } 48842680Smsmith } 48942680Smsmith /* Save encoding */ 49042680Smsmith if (!asn1_enc_save(pval, *in, p - *in, it)) 49142680Smsmith goto auxerr; 49242680Smsmith *in = p; 49342680Smsmith if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) 49442680Smsmith goto auxerr; 49542680Smsmith return 1; 49642680Smsmith 49742680Smsmith default: 49842680Smsmith return 0; 49942680Smsmith } 50042680Smsmith auxerr: 50142680Smsmith ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR); 50242680Smsmith err: 50342680Smsmith if (combine == 0) 50442680Smsmith ASN1_item_ex_free(pval, it); 50542680Smsmith if (errtt) 50642680Smsmith ERR_add_error_data(4, "Field=", errtt->field_name, 50742680Smsmith ", Type=", it->sname); 50842680Smsmith else 50942680Smsmith ERR_add_error_data(2, "Type=", it->sname); 51042680Smsmith return 0; 51142680Smsmith} 51242680Smsmith 51342680Smsmith/* 51442680Smsmith * Templates are handled with two separate functions. One handles any 51542680Smsmith * EXPLICIT tag and the other handles the rest. 51642680Smsmith */ 51742680Smsmith 51842680Smsmithstatic int asn1_template_ex_d2i(ASN1_VALUE **val, 51942680Smsmith const unsigned char **in, long inlen, 52042680Smsmith const ASN1_TEMPLATE *tt, char opt, 52142680Smsmith ASN1_TLC *ctx) 52242680Smsmith{ 52342680Smsmith int flags, aclass; 52442680Smsmith int ret; 52542680Smsmith long len; 52642680Smsmith const unsigned char *p, *q; 52742680Smsmith char exp_eoc; 52842680Smsmith if (!val) 52942680Smsmith return 0; 53042680Smsmith flags = tt->flags; 53142680Smsmith aclass = flags & ASN1_TFLG_TAG_CLASS; 53242680Smsmith 53342680Smsmith p = *in; 53442680Smsmith 53542680Smsmith /* Check if EXPLICIT tag expected */ 53642680Smsmith if (flags & ASN1_TFLG_EXPTAG) { 53742680Smsmith char cst; 53842680Smsmith /* 53942680Smsmith * Need to work out amount of data available to the inner content and 54042680Smsmith * where it starts: so read in EXPLICIT header to get the info. 54153648Sarchie */ 54242680Smsmith ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, 54342680Smsmith &p, inlen, tt->tag, aclass, opt, ctx); 54450275Sbde q = p; 545230587Sken if (!ret) { 546230587Sken ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 54742680Smsmith return 0; 54842680Smsmith } else if (ret == -1) 54942680Smsmith return -1; 55042680Smsmith if (!cst) { 55142680Smsmith ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, 55242680Smsmith ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); 553351760Smav return 0; 554351760Smav } 555351760Smav /* We've found the field so it can't be OPTIONAL now */ 556351760Smav ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx); 557351760Smav if (!ret) { 558351760Smav ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 55942680Smsmith return 0; 56042680Smsmith } 56142680Smsmith /* We read the field in OK so update length */ 56242680Smsmith len -= p - q; 56342680Smsmith if (exp_eoc) { 56442680Smsmith /* If NDEF we must have an EOC here */ 56542680Smsmith if (!asn1_check_eoc(&p, len)) { 56642680Smsmith ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_MISSING_EOC); 56742680Smsmith goto err; 56842680Smsmith } 56942680Smsmith } else { 57042680Smsmith /* 57142680Smsmith * Otherwise we must hit the EXPLICIT tag end or its an error 57242680Smsmith */ 57342680Smsmith if (len) { 57442680Smsmith ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, 57542680Smsmith ASN1_R_EXPLICIT_LENGTH_MISMATCH); 57642680Smsmith goto err; 57742680Smsmith } 57842680Smsmith } 57942680Smsmith } else 58042680Smsmith return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx); 58143300Sdillon 58243300Sdillon *in = p; 58342680Smsmith return 1; 58442680Smsmith 58542680Smsmith err: 58642680Smsmith ASN1_template_free(val, tt); 58742680Smsmith return 0; 58842680Smsmith} 58942680Smsmith 59042680Smsmithstatic int asn1_template_noexp_d2i(ASN1_VALUE **val, 59142680Smsmith const unsigned char **in, long len, 59242680Smsmith const ASN1_TEMPLATE *tt, char opt, 59342680Smsmith ASN1_TLC *ctx) 59442680Smsmith{ 59542680Smsmith int flags, aclass; 59642680Smsmith int ret; 59742680Smsmith const unsigned char *p, *q; 59842680Smsmith if (!val) 59942680Smsmith return 0; 60042680Smsmith flags = tt->flags; 60142680Smsmith aclass = flags & ASN1_TFLG_TAG_CLASS; 60242680Smsmith 60342680Smsmith p = *in; 60442680Smsmith q = p; 60542680Smsmith 60642680Smsmith if (flags & ASN1_TFLG_SK_MASK) { 60742680Smsmith /* SET OF, SEQUENCE OF */ 60842680Smsmith int sktag, skaclass; 60942680Smsmith char sk_eoc; 61042680Smsmith /* First work out expected inner tag value */ 61142680Smsmith if (flags & ASN1_TFLG_IMPTAG) { 61242680Smsmith sktag = tt->tag; 61342680Smsmith skaclass = aclass; 61442680Smsmith } else { 61542680Smsmith skaclass = V_ASN1_UNIVERSAL; 61642680Smsmith if (flags & ASN1_TFLG_SET_OF) 61742680Smsmith sktag = V_ASN1_SET; 61842680Smsmith else 61942680Smsmith sktag = V_ASN1_SEQUENCE; 62042680Smsmith } 62142680Smsmith /* Get the tag */ 62242680Smsmith ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, 62342680Smsmith &p, len, sktag, skaclass, opt, ctx); 62442680Smsmith if (!ret) { 62542680Smsmith ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); 62642680Smsmith return 0; 62742680Smsmith } else if (ret == -1) 62842680Smsmith return -1; 62942680Smsmith if (!*val) 63042680Smsmith *val = (ASN1_VALUE *)sk_new_null(); 631298819Spfg else { 63242680Smsmith /* 63342680Smsmith * We've got a valid STACK: free up any items present 63442680Smsmith */ 63542680Smsmith STACK *sktmp = (STACK *) * val; 63642680Smsmith ASN1_VALUE *vtmp; 63742680Smsmith while (sk_num(sktmp) > 0) { 63842680Smsmith vtmp = (ASN1_VALUE *)sk_pop(sktmp); 63942680Smsmith ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); 64042680Smsmith } 64142680Smsmith } 64242680Smsmith 64342680Smsmith if (!*val) { 64442680Smsmith ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); 64542680Smsmith goto err; 64642680Smsmith } 64742680Smsmith 64842680Smsmith /* Read as many items as we can */ 64942680Smsmith while (len > 0) { 65042680Smsmith ASN1_VALUE *skfield; 65142680Smsmith q = p; 65242680Smsmith /* See if EOC found */ 65342680Smsmith if (asn1_check_eoc(&p, len)) { 65442680Smsmith if (!sk_eoc) { 65542680Smsmith ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 65642680Smsmith ASN1_R_UNEXPECTED_EOC); 65742680Smsmith goto err; 65842680Smsmith } 65942680Smsmith len -= p - q; 66042680Smsmith sk_eoc = 0; 66142680Smsmith break; 66242680Smsmith } 66342680Smsmith skfield = NULL; 66442680Smsmith if (!ASN1_item_ex_d2i(&skfield, &p, len, 66542680Smsmith ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) { 66642680Smsmith ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 667 ERR_R_NESTED_ASN1_ERROR); 668 goto err; 669 } 670 len -= p - q; 671 if (!sk_push((STACK *) * val, (char *)skfield)) { 672 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); 673 goto err; 674 } 675 } 676 if (sk_eoc) { 677 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC); 678 goto err; 679 } 680 } else if (flags & ASN1_TFLG_IMPTAG) { 681 /* IMPLICIT tagging */ 682 ret = ASN1_item_ex_d2i(val, &p, len, 683 ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, 684 ctx); 685 if (!ret) { 686 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); 687 goto err; 688 } else if (ret == -1) 689 return -1; 690 } else { 691 /* Nothing special */ 692 ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), 693 -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx); 694 if (!ret) { 695 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); 696 goto err; 697 } else if (ret == -1) 698 return -1; 699 } 700 701 *in = p; 702 return 1; 703 704 err: 705 ASN1_template_free(val, tt); 706 return 0; 707} 708 709static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, 710 const unsigned char **in, long inlen, 711 const ASN1_ITEM *it, 712 int tag, int aclass, char opt, ASN1_TLC *ctx) 713{ 714 int ret = 0, utype; 715 long plen; 716 char cst, inf, free_cont = 0; 717 const unsigned char *p; 718 BUF_MEM buf; 719 const unsigned char *cont = NULL; 720 long len; 721 if (!pval) { 722 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL); 723 return 0; /* Should never happen */ 724 } 725 726 if (it->itype == ASN1_ITYPE_MSTRING) { 727 utype = tag; 728 tag = -1; 729 } else 730 utype = it->utype; 731 732 if (utype == V_ASN1_ANY) { 733 /* If type is ANY need to figure out type from tag */ 734 unsigned char oclass; 735 if (tag >= 0) { 736 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY); 737 return 0; 738 } 739 if (opt) { 740 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, 741 ASN1_R_ILLEGAL_OPTIONAL_ANY); 742 return 0; 743 } 744 p = *in; 745 ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, 746 &p, inlen, -1, 0, 0, ctx); 747 if (!ret) { 748 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); 749 return 0; 750 } 751 if (oclass != V_ASN1_UNIVERSAL) 752 utype = V_ASN1_OTHER; 753 } 754 if (tag == -1) { 755 tag = utype; 756 aclass = V_ASN1_UNIVERSAL; 757 } 758 p = *in; 759 /* Check header */ 760 ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, 761 &p, inlen, tag, aclass, opt, ctx); 762 if (!ret) { 763 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); 764 return 0; 765 } else if (ret == -1) 766 return -1; 767 ret = 0; 768 /* SEQUENCE, SET and "OTHER" are left in encoded form */ 769 if ((utype == V_ASN1_SEQUENCE) 770 || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) { 771 /* 772 * Clear context cache for type OTHER because the auto clear when we 773 * have a exact match wont work 774 */ 775 if (utype == V_ASN1_OTHER) { 776 asn1_tlc_clear(ctx); 777 } 778 /* SEQUENCE and SET must be constructed */ 779 else if (!cst) { 780 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, 781 ASN1_R_TYPE_NOT_CONSTRUCTED); 782 return 0; 783 } 784 785 cont = *in; 786 /* If indefinite length constructed find the real end */ 787 if (inf) { 788 if (!asn1_find_end(&p, plen, inf)) 789 goto err; 790 len = p - cont; 791 } else { 792 len = p - cont + plen; 793 p += plen; 794 buf.data = NULL; 795 } 796 } else if (cst) { 797 if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN 798 || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER 799 || utype == V_ASN1_ENUMERATED) { 800 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_PRIMITIVE); 801 return 0; 802 } 803 buf.length = 0; 804 buf.max = 0; 805 buf.data = NULL; 806 /* 807 * Should really check the internal tags are correct but some things 808 * may get this wrong. The relevant specs say that constructed string 809 * types should be OCTET STRINGs internally irrespective of the type. 810 * So instead just check for UNIVERSAL class and ignore the tag. 811 */ 812 if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) { 813 free_cont = 1; 814 goto err; 815 } 816 len = buf.length; 817 /* Append a final null to string */ 818 if (!BUF_MEM_grow_clean(&buf, len + 1)) { 819 ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); 820 return 0; 821 } 822 buf.data[len] = 0; 823 cont = (const unsigned char *)buf.data; 824 free_cont = 1; 825 } else { 826 cont = p; 827 len = plen; 828 p += plen; 829 } 830 831 /* We now have content length and type: translate into a structure */ 832 if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) 833 goto err; 834 835 *in = p; 836 ret = 1; 837 err: 838 if (free_cont && buf.data) 839 OPENSSL_free(buf.data); 840 return ret; 841} 842 843/* Translate ASN1 content octets into a structure */ 844 845int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, 846 int utype, char *free_cont, const ASN1_ITEM *it) 847{ 848 ASN1_VALUE **opval = NULL; 849 ASN1_STRING *stmp; 850 ASN1_TYPE *typ = NULL; 851 int ret = 0; 852 const ASN1_PRIMITIVE_FUNCS *pf; 853 ASN1_INTEGER **tint; 854 pf = it->funcs; 855 856 if (pf && pf->prim_c2i) 857 return pf->prim_c2i(pval, cont, len, utype, free_cont, it); 858 /* If ANY type clear type and set pointer to internal value */ 859 if (it->utype == V_ASN1_ANY) { 860 if (!*pval) { 861 typ = ASN1_TYPE_new(); 862 if (typ == NULL) 863 goto err; 864 *pval = (ASN1_VALUE *)typ; 865 } else 866 typ = (ASN1_TYPE *)*pval; 867 868 if (utype != typ->type) 869 ASN1_TYPE_set(typ, utype, NULL); 870 opval = pval; 871 pval = &typ->value.asn1_value; 872 } 873 switch (utype) { 874 case V_ASN1_OBJECT: 875 if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) 876 goto err; 877 break; 878 879 case V_ASN1_NULL: 880 if (len) { 881 ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH); 882 goto err; 883 } 884 *pval = (ASN1_VALUE *)1; 885 break; 886 887 case V_ASN1_BOOLEAN: 888 if (len != 1) { 889 ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); 890 goto err; 891 } else { 892 ASN1_BOOLEAN *tbool; 893 tbool = (ASN1_BOOLEAN *)pval; 894 *tbool = *cont; 895 } 896 break; 897 898 case V_ASN1_BIT_STRING: 899 if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) 900 goto err; 901 break; 902 903 case V_ASN1_INTEGER: 904 case V_ASN1_NEG_INTEGER: 905 case V_ASN1_ENUMERATED: 906 case V_ASN1_NEG_ENUMERATED: 907 tint = (ASN1_INTEGER **)pval; 908 if (!c2i_ASN1_INTEGER(tint, &cont, len)) 909 goto err; 910 /* Fixup type to match the expected form */ 911 (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); 912 break; 913 914 case V_ASN1_OCTET_STRING: 915 case V_ASN1_NUMERICSTRING: 916 case V_ASN1_PRINTABLESTRING: 917 case V_ASN1_T61STRING: 918 case V_ASN1_VIDEOTEXSTRING: 919 case V_ASN1_IA5STRING: 920 case V_ASN1_UTCTIME: 921 case V_ASN1_GENERALIZEDTIME: 922 case V_ASN1_GRAPHICSTRING: 923 case V_ASN1_VISIBLESTRING: 924 case V_ASN1_GENERALSTRING: 925 case V_ASN1_UNIVERSALSTRING: 926 case V_ASN1_BMPSTRING: 927 case V_ASN1_UTF8STRING: 928 case V_ASN1_OTHER: 929 case V_ASN1_SET: 930 case V_ASN1_SEQUENCE: 931 default: 932 if (utype == V_ASN1_BMPSTRING && (len & 1)) { 933 ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); 934 goto err; 935 } 936 if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) { 937 ASN1err(ASN1_F_ASN1_EX_C2I, 938 ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); 939 goto err; 940 } 941 /* All based on ASN1_STRING and handled the same */ 942 if (!*pval) { 943 stmp = ASN1_STRING_type_new(utype); 944 if (!stmp) { 945 ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); 946 goto err; 947 } 948 *pval = (ASN1_VALUE *)stmp; 949 } else { 950 stmp = (ASN1_STRING *)*pval; 951 stmp->type = utype; 952 } 953 /* If we've already allocated a buffer use it */ 954 if (*free_cont) { 955 if (stmp->data) 956 OPENSSL_free(stmp->data); 957 stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ 958 stmp->length = len; 959 *free_cont = 0; 960 } else { 961 if (!ASN1_STRING_set(stmp, cont, len)) { 962 ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); 963 ASN1_STRING_free(stmp); 964 *pval = NULL; 965 goto err; 966 } 967 } 968 break; 969 } 970 /* If ASN1_ANY and NULL type fix up value */ 971 if (typ && (utype == V_ASN1_NULL)) 972 typ->value.ptr = NULL; 973 974 ret = 1; 975 err: 976 if (!ret) { 977 ASN1_TYPE_free(typ); 978 if (opval) 979 *opval = NULL; 980 } 981 return ret; 982} 983 984/* 985 * This function finds the end of an ASN1 structure when passed its maximum 986 * length, whether it is indefinite length and a pointer to the content. This 987 * is more efficient than calling asn1_collect because it does not recurse on 988 * each indefinite length header. 989 */ 990 991static int asn1_find_end(const unsigned char **in, long len, char inf) 992{ 993 int expected_eoc; 994 long plen; 995 const unsigned char *p = *in, *q; 996 /* If not indefinite length constructed just add length */ 997 if (inf == 0) { 998 *in += len; 999 return 1; 1000 } 1001 expected_eoc = 1; 1002 /* 1003 * Indefinite length constructed form. Find the end when enough EOCs are 1004 * found. If more indefinite length constructed headers are encountered 1005 * increment the expected eoc count otherwise just skip to the end of the 1006 * data. 1007 */ 1008 while (len > 0) { 1009 if (asn1_check_eoc(&p, len)) { 1010 expected_eoc--; 1011 if (expected_eoc == 0) 1012 break; 1013 len -= 2; 1014 continue; 1015 } 1016 q = p; 1017 /* Just read in a header: only care about the length */ 1018 if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len, 1019 -1, 0, 0, NULL)) { 1020 ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR); 1021 return 0; 1022 } 1023 if (inf) 1024 expected_eoc++; 1025 else 1026 p += plen; 1027 len -= p - q; 1028 } 1029 if (expected_eoc) { 1030 ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC); 1031 return 0; 1032 } 1033 *in = p; 1034 return 1; 1035} 1036 1037/* 1038 * This function collects the asn1 data from a constructred string type into 1039 * a buffer. The values of 'in' and 'len' should refer to the contents of the 1040 * constructed type and 'inf' should be set if it is indefinite length. 1041 */ 1042 1043#ifndef ASN1_MAX_STRING_NEST 1044/* 1045 * This determines how many levels of recursion are permitted in ASN1 string 1046 * types. If it is not limited stack overflows can occur. If set to zero no 1047 * recursion is allowed at all. Although zero should be adequate examples 1048 * exist that require a value of 1. So 5 should be more than enough. 1049 */ 1050# define ASN1_MAX_STRING_NEST 5 1051#endif 1052 1053static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, 1054 char inf, int tag, int aclass, int depth) 1055{ 1056 const unsigned char *p, *q; 1057 long plen; 1058 char cst, ininf; 1059 p = *in; 1060 inf &= 1; 1061 /* 1062 * If no buffer and not indefinite length constructed just pass over the 1063 * encoded data 1064 */ 1065 if (!buf && !inf) { 1066 *in += len; 1067 return 1; 1068 } 1069 while (len > 0) { 1070 q = p; 1071 /* Check for EOC */ 1072 if (asn1_check_eoc(&p, len)) { 1073 /* 1074 * EOC is illegal outside indefinite length constructed form 1075 */ 1076 if (!inf) { 1077 ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC); 1078 return 0; 1079 } 1080 inf = 0; 1081 break; 1082 } 1083 1084 if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, 1085 len, tag, aclass, 0, NULL)) { 1086 ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR); 1087 return 0; 1088 } 1089 1090 /* If indefinite length constructed update max length */ 1091 if (cst) { 1092 if (depth >= ASN1_MAX_STRING_NEST) { 1093 ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING); 1094 return 0; 1095 } 1096 if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1)) 1097 return 0; 1098 } else if (plen && !collect_data(buf, &p, plen)) 1099 return 0; 1100 len -= p - q; 1101 } 1102 if (inf) { 1103 ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC); 1104 return 0; 1105 } 1106 *in = p; 1107 return 1; 1108} 1109 1110static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen) 1111{ 1112 int len; 1113 if (buf) { 1114 len = buf->length; 1115 if (!BUF_MEM_grow_clean(buf, len + plen)) { 1116 ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); 1117 return 0; 1118 } 1119 memcpy(buf->data + len, *p, plen); 1120 } 1121 *p += plen; 1122 return 1; 1123} 1124 1125/* Check for ASN1 EOC and swallow it if found */ 1126 1127static int asn1_check_eoc(const unsigned char **in, long len) 1128{ 1129 const unsigned char *p; 1130 if (len < 2) 1131 return 0; 1132 p = *in; 1133 if (!p[0] && !p[1]) { 1134 *in += 2; 1135 return 1; 1136 } 1137 return 0; 1138} 1139 1140/* 1141 * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the 1142 * length for indefinite length constructed form, we don't know the exact 1143 * length but we can set an upper bound to the amount of data available minus 1144 * the header length just read. 1145 */ 1146 1147static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, 1148 char *inf, char *cst, 1149 const unsigned char **in, long len, 1150 int exptag, int expclass, char opt, ASN1_TLC *ctx) 1151{ 1152 int i; 1153 int ptag, pclass; 1154 long plen; 1155 const unsigned char *p, *q; 1156 p = *in; 1157 q = p; 1158 1159 if (ctx && ctx->valid) { 1160 i = ctx->ret; 1161 plen = ctx->plen; 1162 pclass = ctx->pclass; 1163 ptag = ctx->ptag; 1164 p += ctx->hdrlen; 1165 } else { 1166 i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); 1167 if (ctx) { 1168 ctx->ret = i; 1169 ctx->plen = plen; 1170 ctx->pclass = pclass; 1171 ctx->ptag = ptag; 1172 ctx->hdrlen = p - q; 1173 ctx->valid = 1; 1174 /* 1175 * If definite length, and no error, length + header can't exceed 1176 * total amount of data available. 1177 */ 1178 if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) { 1179 ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); 1180 asn1_tlc_clear(ctx); 1181 return 0; 1182 } 1183 } 1184 } 1185 1186 if (i & 0x80) { 1187 ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER); 1188 asn1_tlc_clear(ctx); 1189 return 0; 1190 } 1191 if (exptag >= 0) { 1192 if ((exptag != ptag) || (expclass != pclass)) { 1193 /* 1194 * If type is OPTIONAL, not an error: indicate missing type. 1195 */ 1196 if (opt) 1197 return -1; 1198 asn1_tlc_clear(ctx); 1199 ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG); 1200 return 0; 1201 } 1202 /* 1203 * We have a tag and class match: assume we are going to do something 1204 * with it 1205 */ 1206 asn1_tlc_clear(ctx); 1207 } 1208 1209 if (i & 1) 1210 plen = len - (p - q); 1211 1212 if (inf) 1213 *inf = i & 1; 1214 1215 if (cst) 1216 *cst = i & V_ASN1_CONSTRUCTED; 1217 1218 if (olen) 1219 *olen = plen; 1220 1221 if (oclass) 1222 *oclass = pclass; 1223 1224 if (otag) 1225 *otag = ptag; 1226 1227 *in = p; 1228 return 1; 1229} 1230