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