195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * All rights reserved. 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This package is an SSL implementation written 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * by Eric Young (eay@cryptsoft.com). 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The implementation was written so as to conform with Netscapes SSL. 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This library is free for commercial and non-commercial use as long as 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the following conditions are aheared to. The following conditions 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * apply to all code found in this distribution, be it the RC4, RSA, 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * included with this distribution is covered by the same copyright terms 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright remains Eric Young's, and as such any Copyright notices in 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the code are not to be removed. 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If this package is used in a product, Eric Young should be given attribution 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * as the author of the parts of the library used. 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This can be in the form of a textual message at program startup or 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * in documentation (online or textual) provided with the package. 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met: 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the copyright 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer. 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer in the 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * documentation and/or other materials provided with the distribution. 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this software 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * must display the following acknowledgement: 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes cryptographic software written by 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Eric Young (eay@cryptsoft.com)" 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The word 'cryptographic' can be left out if the rouines from the library 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * being used are not cryptographic related :-). 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. If you include any Windows specific code (or a derivative thereof) from 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the apps directory (application code) you must include an acknowledgement: 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SUCH DAMAGE. 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The licence and distribution terms for any publically available version or 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * derivative of this code cannot be changed. i.e. this code cannot simply be 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copied and put under another distribution licence 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * [including the GNU Public Licence.] */ 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/asn1.h> 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/asn1t.h> 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/buf.h> 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/err.h> 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h> 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_check_eoc(const unsigned char **in, long len); 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_find_end(const unsigned char **in, long len, char inf); 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char inf, int tag, int aclass, int depth); 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int collect_data(BUF_MEM *buf, const unsigned char **p, long plen); 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char *inf, char *cst, 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char **in, long len, 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int exptag, int expclass, char opt, 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_TLC *ctx); 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_template_ex_d2i(ASN1_VALUE **pval, 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char **in, long len, 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *tt, char opt, 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_TLC *ctx); 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_template_noexp_d2i(ASN1_VALUE **val, 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char **in, long len, 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *tt, char opt, 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_TLC *ctx); 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_d2i_ex_primitive(ASN1_VALUE **pval, 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char **in, long len, 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_ITEM *it, 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int tag, int aclass, char opt, ASN1_TLC *ctx); 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Table to convert tags to bit values, used for MSTRING type */ 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic const unsigned long tag2bit[32] = { 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */ 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyB_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,/* tags 4- 7 */ 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyB_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags 8-11 */ 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyB_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */ 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyB_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */ 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyB_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING, /* tags 20-22 */ 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyB_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */ 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyB_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING, /* tags 25-27 */ 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyB_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */ 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley }; 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyunsigned long ASN1_tag2bit(int tag) 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((tag < 0) || (tag > 30)) return 0; 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return tag2bit[tag]; 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Macro to initialize and invalidate the cache */ 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define asn1_tlc_clear(c) if (c) (c)->valid = 0 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Version to avoid compiler warning about 'c' always non-NULL */ 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define asn1_tlc_clear_nc(c) (c)->valid = 0 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Decode an ASN1 item, this currently behaves just 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * like a standard 'd2i' function. 'in' points to 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * a buffer to read the data from, in future we will 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * have more advanced versions that can input data 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * a piece at a time and this will simply be a special 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * case. 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char **in, long len, const ASN1_ITEM *it) 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_TLC c; 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE *ptmpval = NULL; 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!pval) 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pval = &ptmpval; 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_tlc_clear_nc(&c); 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return *pval; 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ASN1_template_d2i(ASN1_VALUE **pval, 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char **in, long len, const ASN1_TEMPLATE *tt) 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_TLC c; 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_tlc_clear_nc(&c); 14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); 14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Decode an item, taking care of IMPLICIT tagging, if any. 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If 'opt' set and tag mismatch return -1 to handle OPTIONAL 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_ITEM *it, 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int tag, int aclass, char opt, ASN1_TLC *ctx) 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *tt, *errtt = NULL; 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_COMPAT_FUNCS *cf; 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_EXTERN_FUNCS *ef; 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_AUX *aux = it->funcs; 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_aux_cb *asn1_cb; 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *p = NULL, *q; 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char *wp=NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */ 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char imphack = 0, oclass; 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char seq_eoc, seq_nolen, cst, isopt; 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley long tmplen; 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i; 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int otag; 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret = 0; 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE **pchptr, *ptmpval; 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!pval) 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (aux && aux->asn1_cb) 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_cb = aux->asn1_cb; 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else asn1_cb = 0; 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley switch(it->itype) 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_PRIMITIVE: 17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (it->templates) 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* tagging or OPTIONAL is currently illegal on an item 18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * template because the flags can't get passed down. 18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * In practice this isn't a problem: we include the 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * relevant flags from the item template in the 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * template itself. 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((tag != -1) || opt) 18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return asn1_template_ex_d2i(pval, in, len, 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley it->templates, opt, ctx); 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return asn1_d2i_ex_primitive(pval, in, len, it, 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tag, aclass, opt, ctx); 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_MSTRING: 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *in; 20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Just read in tag and class */ 20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, 20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley &p, len, -1, 0, 1, ctx); 20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR); 20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Must be UNIVERSAL class */ 21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (oclass != V_ASN1_UNIVERSAL) 21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If OPTIONAL, assume this is OK */ 21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (opt) return -1; 21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_MSTRING_NOT_UNIVERSAL); 21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Check tag matches bit map */ 21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!(ASN1_tag2bit(otag) & it->utype)) 21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If OPTIONAL, assume this is OK */ 22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (opt) 22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_MSTRING_WRONG_TAG); 22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return asn1_d2i_ex_primitive(pval, in, len, 22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley it, otag, 0, 0, ctx); 22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_EXTERN: 23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Use new style d2i */ 23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ef = it->funcs; 23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ef->asn1_ex_d2i(pval, in, len, 23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley it, tag, aclass, opt, ctx); 23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_COMPAT: 23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* we must resort to old style evil hackery */ 23795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cf = it->funcs; 23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If OPTIONAL see if it is there */ 24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (opt) 24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 24295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int exptag; 24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *in; 24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tag == -1) 24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley exptag = it->utype; 24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else exptag = tag; 24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Don't care about anything other than presence 24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * of expected tag */ 24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, 25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley &p, len, exptag, aclass, 1, ctx); 25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 25495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR); 25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret == -1) 25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* This is the old style evil hack IMPLICIT handling: 26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * since the underlying code is expecting a tag and 26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * class other than the one present we change the 26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * buffer temporarily then change it back afterwards. 26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This doesn't and never did work for tags > 30. 26695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 26795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Yes this is *horrible* but it is only needed for 26895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * old style d2i which will hopefully not be around 26995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * for much longer. 27095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * FIXME: should copy the buffer then modify it so 27195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the input buffer can be const: we should *always* 27295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copy because the old style d2i might modify the 27395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * buffer. 27495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 27595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 27695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tag != -1) 27795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 27895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley wp = *(unsigned char **)in; 27995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley imphack = *wp; 28095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (p == NULL) 28195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 28295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR); 28395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 28495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 28595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED) 28695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley | it->utype); 28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 28895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ptmpval = cf->asn1_d2i(pval, in, len); 29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tag != -1) 29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *wp = imphack; 29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ptmpval) 29595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 29695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR); 29895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 29995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 30095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 30195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_CHOICE: 30295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) 30395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto auxerr; 30495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 30595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Allocate structure */ 30695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!*pval && !ASN1_item_ex_new(pval, it)) 30795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 30895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR); 30995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 31095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 31195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* CHOICE type, try each possibility in turn */ 31295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *in; 31395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0, tt=it->templates; i < it->tcount; i++, tt++) 31495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 31595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pchptr = asn1_get_field_ptr(pval, tt); 31695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* We mark field as OPTIONAL so its absence 31795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * can be recognised. 31895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 31995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); 32095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If field not present, try the next one */ 32195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret == -1) 32295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley continue; 32395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If positive return, read OK, break loop */ 32495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret > 0) 32595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 32695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Otherwise must be an ASN1 parsing error */ 32795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley errtt = tt; 32895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR); 32995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 33095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 33295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Did we fall off the end without reading anything? */ 33395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i == it->tcount) 33495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 33595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If OPTIONAL, this is OK */ 33695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (opt) 33795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 33895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Free and zero it */ 33995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_item_ex_free(pval, it); 34095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 34195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 34295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NO_MATCHING_CHOICE_TYPE); 34395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 34495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 34595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 34695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_set_choice_selector(pval, i, it); 34795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *in = p; 34895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) 34995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto auxerr; 35095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 35195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 35295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_NDEF_SEQUENCE: 35395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_SEQUENCE: 35495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *in; 35595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tmplen = len; 35695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 35795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ 35895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tag == -1) 35995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 36095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tag = V_ASN1_SEQUENCE; 36195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley aclass = V_ASN1_UNIVERSAL; 36295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 36395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Get SEQUENCE length and update len, p */ 36495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, 36595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley &p, len, tag, aclass, opt, ctx); 36695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 36795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 36895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR); 36995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 37095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 37195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (ret == -1) 37295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 37395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (aux && (aux->flags & ASN1_AFLG_BROKEN)) 37495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 37595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = tmplen - (p - *in); 37695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley seq_nolen = 1; 37795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 37895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If indefinite we don't do a length check */ 37995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else seq_nolen = seq_eoc; 38095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!cst) 38195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 38295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); 38395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 38495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!*pval && !ASN1_item_ex_new(pval, it)) 38795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 38895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR); 38995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 39095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 39195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 39295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) 39395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto auxerr; 39495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 39595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Get each field entry */ 39695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) 39795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 39895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *seqtt; 39995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE **pseqval; 40095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley seqtt = asn1_do_adb(pval, tt, 1); 40195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!seqtt) 40295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 40395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pseqval = asn1_get_field_ptr(pval, seqtt); 40495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Have we ran out of data? */ 40595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!len) 40695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 40795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley q = p; 40895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (asn1_check_eoc(&p, len)) 40995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 41095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!seq_eoc) 41195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 41295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_UNEXPECTED_EOC); 41395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 41495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 41595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len -= p - q; 41695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley seq_eoc = 0; 41795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley q = p; 41895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 41995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 42095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* This determines the OPTIONAL flag value. The field 42195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * cannot be omitted if it is the last of a SEQUENCE 42295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * and there is still data to be read. This isn't 42395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * strictly necessary but it increases efficiency in 42495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * some cases. 42595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 42695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i == (it->tcount - 1)) 42795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley isopt = 0; 42895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); 42995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* attempt to read in field, allowing each to be 43095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OPTIONAL */ 43195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 43295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = asn1_template_ex_d2i(pseqval, &p, len, 43395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley seqtt, isopt, ctx); 43495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 43595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 43695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley errtt = seqtt; 43795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 43895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 43995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (ret == -1) 44095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 44195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* OPTIONAL component absent. 44295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Free and zero the field. 44395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 44495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_template_free(pseqval, seqtt); 44595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley continue; 44695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 44795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Update length */ 44895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len -= p - q; 44995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 45095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 45195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Check for EOC if expecting one */ 45295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (seq_eoc && !asn1_check_eoc(&p, len)) 45395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 45495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_MISSING_EOC); 45595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 45695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 45795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Check all data read */ 45895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!seq_nolen && len) 45995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 46095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_SEQUENCE_LENGTH_MISMATCH); 46195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 46295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 46395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 46495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If we get here we've got no more data in the SEQUENCE, 46595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * however we may not have read all fields so check all 46695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * remaining are OPTIONAL and clear any that are. 46795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 46895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (; i < it->tcount; tt++, i++) 46995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 47095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *seqtt; 47195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley seqtt = asn1_do_adb(pval, tt, 1); 47295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!seqtt) 47395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 47495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (seqtt->flags & ASN1_TFLG_OPTIONAL) 47595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 47695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE **pseqval; 47795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pseqval = asn1_get_field_ptr(pval, seqtt); 47895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_template_free(pseqval, seqtt); 47995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 48095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 48195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 48295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley errtt = seqtt; 48395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_FIELD_MISSING); 48495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 48595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 48695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 48795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Save encoding */ 48895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!asn1_enc_save(pval, *in, p - *in, it)) 48995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto auxerr; 49095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *in = p; 49195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) 49295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto auxerr; 49395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 49495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 49595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley default: 49695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 49795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 49895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley auxerr: 49995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_AUX_ERROR); 50095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley err: 50195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_item_ex_free(pval, it); 50295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (errtt) 50395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ERR_add_error_data(4, "Field=", errtt->field_name, 50495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ", Type=", it->sname); 50595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 50695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ERR_add_error_data(2, "Type=", it->sname); 50795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 50895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 50995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 51095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Templates are handled with two separate functions. 51195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * One handles any EXPLICIT tag and the other handles the rest. 51295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 51395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 51495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_template_ex_d2i(ASN1_VALUE **val, 51595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char **in, long inlen, 51695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *tt, char opt, 51795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_TLC *ctx) 51895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 51995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int flags, aclass; 52095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret; 52195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley long len; 52295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *p, *q; 52395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char exp_eoc; 52495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!val) 52595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 52695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley flags = tt->flags; 52795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley aclass = flags & ASN1_TFLG_TAG_CLASS; 52895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 52995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *in; 53095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 53195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Check if EXPLICIT tag expected */ 53295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & ASN1_TFLG_EXPTAG) 53395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 53495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char cst; 53595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Need to work out amount of data available to the inner 53695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * content and where it starts: so read in EXPLICIT header to 53795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * get the info. 53895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 53995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, 54095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley &p, inlen, tt->tag, aclass, opt, ctx); 54195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley q = p; 54295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 54395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 54495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_NESTED_ASN1_ERROR); 54595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 54695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 54795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (ret == -1) 54895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 54995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!cst) 55095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 55195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); 55295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 55395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 55495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* We've found the field so it can't be OPTIONAL now */ 55595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx); 55695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 55795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 55895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_NESTED_ASN1_ERROR); 55995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 56095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 56195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* We read the field in OK so update length */ 56295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len -= p - q; 56395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (exp_eoc) 56495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 56595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If NDEF we must have an EOC here */ 56695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!asn1_check_eoc(&p, len)) 56795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 56895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_MISSING_EOC); 56995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 57095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 57195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 57295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 57395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 57495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Otherwise we must hit the EXPLICIT tag end or its 57595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * an error */ 57695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (len) 57795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 57895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_EXPLICIT_LENGTH_MISMATCH); 57995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 58095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 58195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 58295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 58395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 58495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return asn1_template_noexp_d2i(val, in, inlen, 58595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tt, opt, ctx); 58695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 58795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *in = p; 58895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 58995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 59095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley err: 59195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_template_free(val, tt); 59295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 59395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 59495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 59595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_template_noexp_d2i(ASN1_VALUE **val, 59695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char **in, long len, 59795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *tt, char opt, 59895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_TLC *ctx) 59995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 60095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int flags, aclass; 60195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret; 60295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *p, *q; 60395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!val) 60495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 60595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley flags = tt->flags; 60695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley aclass = flags & ASN1_TFLG_TAG_CLASS; 60795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 60895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *in; 60995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley q = p; 61095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 61195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & ASN1_TFLG_SK_MASK) 61295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 61395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* SET OF, SEQUENCE OF */ 61495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int sktag, skaclass; 61595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char sk_eoc; 61695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* First work out expected inner tag value */ 61795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & ASN1_TFLG_IMPTAG) 61895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 61995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sktag = tt->tag; 62095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley skaclass = aclass; 62195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 62295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 62395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 62495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley skaclass = V_ASN1_UNIVERSAL; 62595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & ASN1_TFLG_SET_OF) 62695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sktag = V_ASN1_SET; 62795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 62895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sktag = V_ASN1_SEQUENCE; 62995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 63095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Get the tag */ 63195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, 63295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley &p, len, sktag, skaclass, opt, ctx); 63395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 63495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 63595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR); 63695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 63795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 63895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (ret == -1) 63995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 64095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!*val) 64195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *val = (ASN1_VALUE *)sk_new_null(); 64295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 64395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 64495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* We've got a valid STACK: free up any items present */ 64595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley STACK_OF(ASN1_VALUE) *sktmp 64695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley = (STACK_OF(ASN1_VALUE) *)*val; 64795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE *vtmp; 64895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while(sk_ASN1_VALUE_num(sktmp) > 0) 64995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 65095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley vtmp = sk_ASN1_VALUE_pop(sktmp); 65195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_item_ex_free(&vtmp, 65295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_ITEM_ptr(tt->item)); 65395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 65495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 65595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 65695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!*val) 65795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 65895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ERR_R_MALLOC_FAILURE); 65995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 66095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 66195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 66295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Read as many items as we can */ 66395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while(len > 0) 66495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 66595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE *skfield; 66695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley q = p; 66795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* See if EOC found */ 66895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (asn1_check_eoc(&p, len)) 66995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 67095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!sk_eoc) 67195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 67295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_UNEXPECTED_EOC); 67395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 67495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 67595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len -= p - q; 67695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sk_eoc = 0; 67795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 67895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 67995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley skfield = NULL; 68095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ASN1_item_ex_d2i(&skfield, &p, len, 68195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_ITEM_ptr(tt->item), 68295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley -1, 0, 0, ctx)) 68395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 68495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR); 68595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 68695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 68795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len -= p - q; 68895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, 68995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley skfield)) 69095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 69195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ERR_R_MALLOC_FAILURE); 69295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 69395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 69495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 69595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (sk_eoc) 69695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 69795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_MISSING_EOC); 69895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 69995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 70095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 70195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (flags & ASN1_TFLG_IMPTAG) 70295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 70395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* IMPLICIT tagging */ 70495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = ASN1_item_ex_d2i(val, &p, len, 70595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx); 70695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 70795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 70895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR); 70995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 71095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 71195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (ret == -1) 71295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 71395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 71495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 71595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 71695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Nothing special */ 71795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), 71895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley -1, 0, opt, ctx); 71995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 72095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 72195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR); 72295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 72395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 72495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (ret == -1) 72595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 72695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 72795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 72895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *in = p; 72995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 73095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 73195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley err: 73295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_template_free(val, tt); 73395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 73495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 73595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 73695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_d2i_ex_primitive(ASN1_VALUE **pval, 73795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char **in, long inlen, 73895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_ITEM *it, 73995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int tag, int aclass, char opt, ASN1_TLC *ctx) 74095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 74195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret = 0, utype; 74295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley long plen; 74395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char cst, inf, free_cont = 0; 74495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *p; 74595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley BUF_MEM buf; 74695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *cont = NULL; 74795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley long len; 74895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!pval) 74995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 75095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_ILLEGAL_NULL); 75195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; /* Should never happen */ 75295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 75395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 75495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (it->itype == ASN1_ITYPE_MSTRING) 75595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 75695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley utype = tag; 75795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tag = -1; 75895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 75995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 76095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley utype = it->utype; 76195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 76295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (utype == V_ASN1_ANY) 76395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 76495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If type is ANY need to figure out type from tag */ 76595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char oclass; 76695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tag >= 0) 76795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 76895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_ILLEGAL_TAGGED_ANY); 76995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 77095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 77195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (opt) 77295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 77395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_ILLEGAL_OPTIONAL_ANY); 77495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 77595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 77695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *in; 77795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, 77895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley &p, inlen, -1, 0, 0, ctx); 77995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 78095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 78195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_NESTED_ASN1_ERROR); 78295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 78395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 78495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (oclass != V_ASN1_UNIVERSAL) 78595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley utype = V_ASN1_OTHER; 78695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 78795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tag == -1) 78895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 78995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tag = utype; 79095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley aclass = V_ASN1_UNIVERSAL; 79195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 79295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *in; 79395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Check header */ 79495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, 79595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley &p, inlen, tag, aclass, opt, ctx); 79695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 79795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 79895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_NESTED_ASN1_ERROR); 79995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 80095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 80195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (ret == -1) 80295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 80395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = 0; 80495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* SEQUENCE, SET and "OTHER" are left in encoded form */ 80595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((utype == V_ASN1_SEQUENCE) 80695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) 80795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 80895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Clear context cache for type OTHER because the auto clear 80995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * when we have a exact match wont work 81095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 81195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (utype == V_ASN1_OTHER) 81295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 81395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_tlc_clear(ctx); 81495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 81595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* SEQUENCE and SET must be constructed */ 81695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (!cst) 81795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 81895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_TYPE_NOT_CONSTRUCTED); 81995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 82095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 82195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 82295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cont = *in; 82395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If indefinite length constructed find the real end */ 82495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (inf) 82595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 82695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!asn1_find_end(&p, plen, inf)) 82795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 82895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = p - cont; 82995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 83095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 83195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 83295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = p - cont + plen; 83395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p += plen; 83495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf.data = NULL; 83595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 83695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 83795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (cst) 83895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 83995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf.length = 0; 84095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf.max = 0; 84195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf.data = NULL; 84295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Should really check the internal tags are correct but 84395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * some things may get this wrong. The relevant specs 84495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * say that constructed string types should be OCTET STRINGs 84595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * internally irrespective of the type. So instead just check 84695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * for UNIVERSAL class and ignore the tag. 84795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 84895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) 84995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 85095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley free_cont = 1; 85195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 85295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 85395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = buf.length; 85495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Append a final null to string */ 85595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BUF_MEM_grow_clean(&buf, len + 1)) 85695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 85795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ERR_R_MALLOC_FAILURE); 85895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 85995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 86095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf.data[len] = 0; 86195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cont = (const unsigned char *)buf.data; 86295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley free_cont = 1; 86395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 86495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 86595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 86695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cont = p; 86795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = plen; 86895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p += plen; 86995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 87095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 87195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* We now have content length and type: translate into a structure */ 87295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) 87395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 87495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 87595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *in = p; 87695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = 1; 87795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley err: 87895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (free_cont && buf.data) OPENSSL_free(buf.data); 87995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 88095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 88195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 88295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Translate ASN1 content octets into a structure */ 88395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 88495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, 88595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int utype, char *free_cont, const ASN1_ITEM *it) 88695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 88795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE **opval = NULL; 88895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_STRING *stmp; 88995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_TYPE *typ = NULL; 89095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret = 0; 89195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_PRIMITIVE_FUNCS *pf; 89295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_INTEGER **tint; 89395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pf = it->funcs; 89495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 89595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (pf && pf->prim_c2i) 89695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return pf->prim_c2i(pval, cont, len, utype, free_cont, it); 89795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If ANY type clear type and set pointer to internal value */ 89895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (it->utype == V_ASN1_ANY) 89995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 90095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!*pval) 90195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 90295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley typ = ASN1_TYPE_new(); 90395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (typ == NULL) 90495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 90595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *pval = (ASN1_VALUE *)typ; 90695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 90795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 90895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley typ = (ASN1_TYPE *)*pval; 90995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 91095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (utype != typ->type) 91195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_TYPE_set(typ, utype, NULL); 91295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley opval = pval; 91395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pval = &typ->value.asn1_value; 91495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 91595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley switch(utype) 91695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 91795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_OBJECT: 91895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) 91995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 92095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 92195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 92295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_NULL: 92395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (len) 92495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 92595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_NULL_IS_WRONG_LENGTH); 92695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 92795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 92895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *pval = (ASN1_VALUE *)1; 92995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 93095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 93195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_BOOLEAN: 93295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (len != 1) 93395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 93495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); 93595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 93695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 93795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 93895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 93995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_BOOLEAN *tbool; 94095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tbool = (ASN1_BOOLEAN *)pval; 94195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *tbool = *cont; 94295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 94395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 94495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 94595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_BIT_STRING: 94695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) 94795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 94895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 94995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 95095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_INTEGER: 95195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_NEG_INTEGER: 95295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_ENUMERATED: 95395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_NEG_ENUMERATED: 95495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tint = (ASN1_INTEGER **)pval; 95595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!c2i_ASN1_INTEGER(tint, &cont, len)) 95695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 95795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Fixup type to match the expected form */ 95895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); 95995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 96095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 96195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_OCTET_STRING: 96295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_NUMERICSTRING: 96395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_PRINTABLESTRING: 96495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_T61STRING: 96595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_VIDEOTEXSTRING: 96695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_IA5STRING: 96795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_UTCTIME: 96895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_GENERALIZEDTIME: 96995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_GRAPHICSTRING: 97095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_VISIBLESTRING: 97195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_GENERALSTRING: 97295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_UNIVERSALSTRING: 97395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_BMPSTRING: 97495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_UTF8STRING: 97595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_OTHER: 97695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_SET: 97795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_SEQUENCE: 97895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley default: 97995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (utype == V_ASN1_BMPSTRING && (len & 1)) 98095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 98195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); 98295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 98395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 98495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) 98595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 98695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); 98795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 98895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 98995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* All based on ASN1_STRING and handled the same */ 99095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!*pval) 99195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 99295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley stmp = ASN1_STRING_type_new(utype); 99395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!stmp) 99495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 99595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ERR_R_MALLOC_FAILURE); 99695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 99795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 99895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *pval = (ASN1_VALUE *)stmp; 99995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 100095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 100195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 100295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley stmp = (ASN1_STRING *)*pval; 100395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley stmp->type = utype; 100495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 100595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If we've already allocated a buffer use it */ 100695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (*free_cont) 100795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 100895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (stmp->data) 100995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(stmp->data); 101095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ 101195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley stmp->length = len; 101295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *free_cont = 0; 101395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 101495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 101595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 101695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ASN1_STRING_set(stmp, cont, len)) 101795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 101895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ERR_R_MALLOC_FAILURE); 101995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_STRING_free(stmp); 102095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *pval = NULL; 102195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto err; 102295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 102395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 102495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 102595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 102695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If ASN1_ANY and NULL type fix up value */ 102795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (typ && (utype == V_ASN1_NULL)) 102895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley typ->value.ptr = NULL; 102995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 103095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = 1; 103195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley err: 103295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ret) 103395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 103495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_TYPE_free(typ); 103595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (opval) 103695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *opval = NULL; 103795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 103895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 103995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 104095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 104195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 104295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* This function finds the end of an ASN1 structure when passed its maximum 104395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * length, whether it is indefinite length and a pointer to the content. 104495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This is more efficient than calling asn1_collect because it does not 104595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * recurse on each indefinite length header. 104695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 104795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 104895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_find_end(const unsigned char **in, long len, char inf) 104995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 105095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int expected_eoc; 105195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley long plen; 105295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *p = *in, *q; 105395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If not indefinite length constructed just add length */ 105495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (inf == 0) 105595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 105695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *in += len; 105795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 105895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 105995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley expected_eoc = 1; 106095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Indefinite length constructed form. Find the end when enough EOCs 106195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are found. If more indefinite length constructed headers 106295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are encountered increment the expected eoc count otherwise just 106395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * skip to the end of the data. 106495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 106595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while (len > 0) 106695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 106795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if(asn1_check_eoc(&p, len)) 106895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 106995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley expected_eoc--; 107095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (expected_eoc == 0) 107195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 107295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len -= 2; 107395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley continue; 107495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 107595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley q = p; 107695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Just read in a header: only care about the length */ 107795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len, 107895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley -1, 0, 0, NULL)) 107995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 108095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_find_end, ASN1_R_NESTED_ASN1_ERROR); 108195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 108295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 108395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (inf) 108495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley expected_eoc++; 108595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 108695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p += plen; 108795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len -= p - q; 108895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 108995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (expected_eoc) 109095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 109195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_find_end, ASN1_R_MISSING_EOC); 109295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 109395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 109495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *in = p; 109595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 109695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 109795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* This function collects the asn1 data from a constructred string 109895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * type into a buffer. The values of 'in' and 'len' should refer 109995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * to the contents of the constructed type and 'inf' should be set 110095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * if it is indefinite length. 110195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 110295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 110395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#ifndef ASN1_MAX_STRING_NEST 110495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* This determines how many levels of recursion are permitted in ASN1 110595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * string types. If it is not limited stack overflows can occur. If set 110695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * to zero no recursion is allowed at all. Although zero should be adequate 110795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * examples exist that require a value of 1. So 5 should be more than enough. 110895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 110995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define ASN1_MAX_STRING_NEST 5 111095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif 111195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 111295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 111395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, 111495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char inf, int tag, int aclass, int depth) 111595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 111695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *p, *q; 111795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley long plen; 111895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char cst, ininf; 111995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *in; 112095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley inf &= 1; 112195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If no buffer and not indefinite length constructed just pass over 112295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the encoded data */ 112395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!buf && !inf) 112495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 112595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *in += len; 112695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 112795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 112895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while(len > 0) 112995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 113095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley q = p; 113195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Check for EOC */ 113295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (asn1_check_eoc(&p, len)) 113395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 113495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* EOC is illegal outside indefinite length 113595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * constructed form */ 113695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!inf) 113795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 113895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_UNEXPECTED_EOC); 113995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 114095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 114195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley inf = 0; 114295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 114395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 114495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 114595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, 114695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len, tag, aclass, 0, NULL)) 114795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 114895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_NESTED_ASN1_ERROR); 114995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 115095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 115195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 115295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If indefinite length constructed update max length */ 115395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (cst) 115495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 115595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (depth >= ASN1_MAX_STRING_NEST) 115695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 115795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_NESTED_ASN1_STRING); 115895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 115995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 116095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, 116195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley depth + 1)) 116295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 116395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 116495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (plen && !collect_data(buf, &p, plen)) 116595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 116695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len -= p - q; 116795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 116895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (inf) 116995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 117095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_MISSING_EOC); 117195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 117295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 117395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *in = p; 117495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 117595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 117695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 117795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int collect_data(BUF_MEM *buf, const unsigned char **p, long plen) 117895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 117995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int len; 118095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (buf) 118195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 118295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = buf->length; 118395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!BUF_MEM_grow_clean(buf, len + plen)) 118495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 118595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_collect, ERR_R_MALLOC_FAILURE); 118695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 118795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 118895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(buf->data + len, *p, plen); 118995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 119095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *p += plen; 119195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 119295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 119395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 119495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Check for ASN1 EOC and swallow it if found */ 119595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 119695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_check_eoc(const unsigned char **in, long len) 119795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 119895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *p; 119995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (len < 2) return 0; 120095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *in; 120195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!p[0] && !p[1]) 120295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 120395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *in += 2; 120495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 120595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 120695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 120795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 120895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 120995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Check an ASN1 tag and length: a bit like ASN1_get_object 121095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * but it sets the length for indefinite length constructed 121195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * form, we don't know the exact length but we can set an 121295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * upper bound to the amount of data available minus the 121395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * header length just read. 121495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 121595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 121695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, 121795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley char *inf, char *cst, 121895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char **in, long len, 121995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int exptag, int expclass, char opt, 122095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_TLC *ctx) 122195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 122295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i; 122395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ptag, pclass; 122495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley long plen; 122595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *p, *q; 122695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *in; 122795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley q = p; 122895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 122995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx && ctx->valid) 123095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 123195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = ctx->ret; 123295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley plen = ctx->plen; 123395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pclass = ctx->pclass; 123495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ptag = ctx->ptag; 123595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p += ctx->hdrlen; 123695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 123795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 123895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 123995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); 124095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx) 124195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 124295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->ret = i; 124395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->plen = plen; 124495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->pclass = pclass; 124595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->ptag = ptag; 124695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->hdrlen = p - q; 124795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->valid = 1; 124895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If definite length, and no error, length + 124995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * header can't exceed total amount of data available. 125095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 125195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) 125295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 125395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen, ASN1_R_TOO_LONG); 125495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_tlc_clear(ctx); 125595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 125695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 125795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 125895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 125995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 126095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i & 0x80) 126195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 126295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen, ASN1_R_BAD_OBJECT_HEADER); 126395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_tlc_clear(ctx); 126495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 126595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 126695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (exptag >= 0) 126795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 126895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((exptag != ptag) || (expclass != pclass)) 126995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 127095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If type is OPTIONAL, not an error: 127195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * indicate missing type. 127295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 127395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (opt) return -1; 127495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_tlc_clear(ctx); 127595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen, ASN1_R_WRONG_TAG); 127695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 127795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 127895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* We have a tag and class match: 127995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * assume we are going to do something with it */ 128095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_tlc_clear(ctx); 128195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 128295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 128395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i & 1) 128495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley plen = len - (p - q); 128595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 128695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (inf) 128795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *inf = i & 1; 128895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 128995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (cst) 129095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *cst = i & V_ASN1_CONSTRUCTED; 129195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 129295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (olen) 129395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *olen = plen; 129495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 129595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (oclass) 129695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *oclass = pclass; 129795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 129895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (otag) 129995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *otag = ptag; 130095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 130195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *in = p; 130295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 130395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 1304