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