tasn_dec.c 30.5 KB
Newer Older
D
 
Dr. Stephen Henson 已提交
1 2 3 4 5
/* tasn_dec.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
 * project 2000.
 */
/* ====================================================================
6
 * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
D
 
Dr. Stephen Henson 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */


#include <stddef.h>
61
#include <string.h>
D
 
Dr. Stephen Henson 已提交
62 63 64 65 66 67
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/err.h>

68
static int asn1_check_eoc(const unsigned char **in, long len);
69
static int asn1_find_end(const unsigned char **in, long len, char inf);
70 71 72 73

static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
				char inf, int tag, int aclass);

74
static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
				char *inf, char *cst,
				const unsigned char **in, long len,
				int exptag, int expclass, char opt,
				ASN1_TLC *ctx);

static int asn1_template_ex_d2i(ASN1_VALUE **pval,
				const unsigned char **in, long len,
				const ASN1_TEMPLATE *tt, char opt,
				ASN1_TLC *ctx);
static int asn1_template_noexp_d2i(ASN1_VALUE **val,
				const unsigned char **in, long len,
				const ASN1_TEMPLATE *tt, char opt,
				ASN1_TLC *ctx);
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
				const unsigned char **in, long len,
				const ASN1_ITEM *it,
				int tag, int aclass, char opt, ASN1_TLC *ctx);
D
 
Dr. Stephen Henson 已提交
94

D
 
Dr. Stephen Henson 已提交
95
/* Table to convert tags to bit values, used for MSTRING type */
96
static unsigned long tag2bit[32] = {
D
 
Dr. Stephen Henson 已提交
97 98 99 100
0,	0,	0,	B_ASN1_BIT_STRING,	/* tags  0 -  3 */
B_ASN1_OCTET_STRING,	0,	0,		B_ASN1_UNKNOWN,/* tags  4- 7 */
B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,/* tags  8-11 */
B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */
101
B_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */
D
 
Dr. Stephen Henson 已提交
102 103 104 105 106 107 108
B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING,       /* tags 20-22 */
B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,			       /* tags 23-24 */	
B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING,  /* tags 25-27 */
B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */
	};

unsigned long ASN1_tag2bit(int tag)
109 110
	{
	if ((tag < 0) || (tag > 30)) return 0;
D
 
Dr. Stephen Henson 已提交
111
	return tag2bit[tag];
112
	}
D
 
Dr. Stephen Henson 已提交
113

D
 
Dr. Stephen Henson 已提交
114 115
/* Macro to initialize and invalidate the cache */

116
#define asn1_tlc_clear(c)	if (c) (c)->valid = 0
D
 
Dr. Stephen Henson 已提交
117 118 119 120 121 122 123 124 125

/* Decode an ASN1 item, this currently behaves just 
 * like a standard 'd2i' function. 'in' points to 
 * a buffer to read the data from, in future we will
 * have more advanced versions that can input data
 * a piece at a time and this will simply be a special
 * case.
 */

126 127 128
ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
		const unsigned char **in, long len, const ASN1_ITEM *it)
	{
D
 
Dr. Stephen Henson 已提交
129 130
	ASN1_TLC c;
	ASN1_VALUE *ptmpval = NULL;
131 132
	if (!pval)
		pval = &ptmpval;
D
 
Dr. Stephen Henson 已提交
133
	asn1_tlc_clear(&c);
134
	if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 
D
 
Dr. Stephen Henson 已提交
135 136
		return *pval;
	return NULL;
137
	}
D
 
Dr. Stephen Henson 已提交
138

139 140 141
int ASN1_template_d2i(ASN1_VALUE **pval,
		const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
	{
D
 
Dr. Stephen Henson 已提交
142 143 144
	ASN1_TLC c;
	asn1_tlc_clear(&c);
	return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
145
	}
D
 
Dr. Stephen Henson 已提交
146 147 148 149 150 151


/* Decode an item, taking care of IMPLICIT tagging, if any.
 * If 'opt' set and tag mismatch return -1 to handle OPTIONAL
 */

152 153 154 155
int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
			const ASN1_ITEM *it,
			int tag, int aclass, char opt, ASN1_TLC *ctx)
	{
D
 
Dr. Stephen Henson 已提交
156 157 158 159 160
	const ASN1_TEMPLATE *tt, *errtt = NULL;
	const ASN1_COMPAT_FUNCS *cf;
	const ASN1_EXTERN_FUNCS *ef;
	const ASN1_AUX *aux = it->funcs;
	ASN1_aux_cb *asn1_cb;
N
Nils Larsch 已提交
161
	const unsigned char *p = NULL, *q;
162 163
	unsigned char *wp=NULL;	/* BIG FAT WARNING!  BREAKS CONST WHERE USED */
	unsigned char imphack = 0, oclass;
D
 
Dr. Stephen Henson 已提交
164 165 166 167 168 169
	char seq_eoc, seq_nolen, cst, isopt;
	long tmplen;
	int i;
	int otag;
	int ret = 0;
	ASN1_VALUE *pchval, **pchptr, *ptmpval;
170 171 172 173
	if (!pval)
		return 0;
	if (aux && aux->asn1_cb)
		asn1_cb = aux->asn1_cb;
D
 
Dr. Stephen Henson 已提交
174 175
	else asn1_cb = 0;

176 177
	switch(it->itype)
		{
D
 
Dr. Stephen Henson 已提交
178
		case ASN1_ITYPE_PRIMITIVE:
179 180 181 182 183 184 185
		if (it->templates)
			{
			/* tagging or OPTIONAL is currently illegal on an item
			 * template because the flags can't get passed down.
			 * In practice this isn't a problem: we include the
			 * relevant flags from the item template in the
			 * template itself.
186
			 */
187 188 189 190
			if ((tag != -1) || opt)
				{
				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
				ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
191
				goto err;
192 193 194
				}
			return asn1_template_ex_d2i(pval, in, len,
					it->templates, opt, ctx);
195
		}
196 197
		return asn1_d2i_ex_primitive(pval, in, len, it,
						tag, aclass, opt, ctx);
D
 
Dr. Stephen Henson 已提交
198 199 200 201 202
		break;

		case ASN1_ITYPE_MSTRING:
		p = *in;
		/* Just read in tag and class */
203 204 205 206 207 208
		ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
						&p, len, -1, 0, 1, ctx);
		if (!ret)
			{
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
					ERR_R_NESTED_ASN1_ERROR);
D
 
Dr. Stephen Henson 已提交
209
			goto err;
210 211
			}

D
 
Dr. Stephen Henson 已提交
212
		/* Must be UNIVERSAL class */
213 214
		if (oclass != V_ASN1_UNIVERSAL)
			{
D
 
Dr. Stephen Henson 已提交
215
			/* If OPTIONAL, assume this is OK */
216 217 218
			if (opt) return -1;
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
					ASN1_R_MSTRING_NOT_UNIVERSAL);
D
 
Dr. Stephen Henson 已提交
219
			goto err;
220
			}
D
 
Dr. Stephen Henson 已提交
221
		/* Check tag matches bit map */
222 223
		if (!(ASN1_tag2bit(otag) & it->utype))
			{
D
 
Dr. Stephen Henson 已提交
224
			/* If OPTIONAL, assume this is OK */
225 226 227 228
			if (opt)
				return -1;
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
					ASN1_R_MSTRING_WRONG_TAG);
D
 
Dr. Stephen Henson 已提交
229
			goto err;
230 231 232
			}
		return asn1_d2i_ex_primitive(pval, in, len,
						it, otag, 0, 0, ctx);
D
 
Dr. Stephen Henson 已提交
233 234 235 236

		case ASN1_ITYPE_EXTERN:
		/* Use new style d2i */
		ef = it->funcs;
237 238
		return ef->asn1_ex_d2i(pval, in, len,
						it, tag, aclass, opt, ctx);
D
 
Dr. Stephen Henson 已提交
239 240 241 242 243 244

		case ASN1_ITYPE_COMPAT:
		/* we must resort to old style evil hackery */
		cf = it->funcs;

		/* If OPTIONAL see if it is there */
245 246
		if (opt)
			{
D
 
Dr. Stephen Henson 已提交
247 248
			int exptag;
			p = *in;
249 250
			if (tag == -1)
				exptag = it->utype;
D
 
Dr. Stephen Henson 已提交
251
			else exptag = tag;
252 253 254 255 256 257 258 259 260
			/* Don't care about anything other than presence
			 * of expected tag */

			ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL,
					&p, len, exptag, aclass, 1, ctx);
			if (!ret)
				{
				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
					ERR_R_NESTED_ASN1_ERROR);
D
 
Dr. Stephen Henson 已提交
261
				goto err;
262 263 264
				}
			if (ret == -1)
				return -1;
D
 
Dr. Stephen Henson 已提交
265
			}
266

D
 
Dr. Stephen Henson 已提交
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
		/* This is the old style evil hack IMPLICIT handling:
		 * since the underlying code is expecting a tag and
		 * class other than the one present we change the
		 * buffer temporarily then change it back afterwards.
		 * This doesn't and never did work for tags > 30.
		 *
		 * Yes this is *horrible* but it is only needed for
		 * old style d2i which will hopefully not be around
		 * for much longer.
		 * FIXME: should copy the buffer then modify it so
		 * the input buffer can be const: we should *always*
		 * copy because the old style d2i might modify the
		 * buffer.
		 */

282 283
		if (tag != -1)
			{
284 285
			wp = *(unsigned char **)in;
			imphack = *wp;
N
Nils Larsch 已提交
286 287 288 289 290 291
			if (p == NULL)
				{
				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
					ERR_R_NESTED_ASN1_ERROR);
				goto err;
				}
292 293 294
			*wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
								| it->utype);
			}
D
 
Dr. Stephen Henson 已提交
295 296 297

		ptmpval = cf->asn1_d2i(pval, in, len);

298 299 300 301 302
		if (tag != -1)
			*wp = imphack;

		if (ptmpval)
			return 1;
D
 
Dr. Stephen Henson 已提交
303 304 305 306 307 308

		ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
		goto err;


		case ASN1_ITYPE_CHOICE:
309
		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
D
 
Dr. Stephen Henson 已提交
310
				goto auxerr;
311 312

		/* Allocate structure */
313 314 315 316 317
		if (!*pval && !ASN1_item_ex_new(pval, it))
			{
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
						ERR_R_NESTED_ASN1_ERROR);
			goto err;
318
			}
D
 
Dr. Stephen Henson 已提交
319 320 321
		/* CHOICE type, try each possibility in turn */
		pchval = NULL;
		p = *in;
D
Dr. Stephen Henson 已提交
322
		for (i = 0, tt=it->templates; i < it->tcount; i++, tt++)
323
			{
324
			pchptr = asn1_get_field_ptr(pval, tt);
D
 
Dr. Stephen Henson 已提交
325 326 327
			/* We mark field as OPTIONAL so its absence
			 * can be recognised.
			 */
328
			ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
D
 
Dr. Stephen Henson 已提交
329
			/* If field not present, try the next one */
330 331
			if (ret == -1)
				continue;
D
 
Dr. Stephen Henson 已提交
332
			/* If positive return, read OK, break loop */
333 334
			if (ret > 0)
				break;
D
 
Dr. Stephen Henson 已提交
335 336
			/* Otherwise must be an ASN1 parsing error */
			errtt = tt;
337 338
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
						ERR_R_NESTED_ASN1_ERROR);
339
			goto err;
340 341
			}

D
 
Dr. Stephen Henson 已提交
342
		/* Did we fall off the end without reading anything? */
343 344
		if (i == it->tcount)
			{
D
 
Dr. Stephen Henson 已提交
345
			/* If OPTIONAL, this is OK */
346 347
			if (opt)
				{
348 349 350
				/* Free and zero it */
				ASN1_item_ex_free(pval, it);
				return -1;
351 352 353
				}
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
					ASN1_R_NO_MATCHING_CHOICE_TYPE);
354
			goto err;
355 356
			}

D
 
Dr. Stephen Henson 已提交
357 358
		asn1_set_choice_selector(pval, i, it);
		*in = p;
359
		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
D
 
Dr. Stephen Henson 已提交
360 361 362
				goto auxerr;
		return 1;

363
		case ASN1_ITYPE_NDEF_SEQUENCE:
D
 
Dr. Stephen Henson 已提交
364 365 366 367 368
		case ASN1_ITYPE_SEQUENCE:
		p = *in;
		tmplen = len;

		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
369 370
		if (tag == -1)
			{
D
 
Dr. Stephen Henson 已提交
371 372
			tag = V_ASN1_SEQUENCE;
			aclass = V_ASN1_UNIVERSAL;
373
			}
D
 
Dr. Stephen Henson 已提交
374
		/* Get SEQUENCE length and update len, p */
375 376 377 378 379 380
		ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
					&p, len, tag, aclass, opt, ctx);
		if (!ret)
			{
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
					ERR_R_NESTED_ASN1_ERROR);
D
 
Dr. Stephen Henson 已提交
381
			goto err;
382 383 384 385 386
			}
		else if (ret == -1)
			return -1;
		if (aux && (aux->flags & ASN1_AFLG_BROKEN))
			{
D
 
Dr. Stephen Henson 已提交
387 388
			len = tmplen - (p - *in);
			seq_nolen = 1;
389 390 391 392 393 394 395
			}
		/* If indefinite we don't do a length check */
		else seq_nolen = seq_eoc;
		if (!cst)
			{
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
				ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
D
 
Dr. Stephen Henson 已提交
396
			goto err;
397
			}
D
 
Dr. Stephen Henson 已提交
398

399
		if (!*pval && !ASN1_item_ex_new(pval, it))
400 401 402 403
			{
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
				ERR_R_NESTED_ASN1_ERROR);
			goto err;
D
 
Dr. Stephen Henson 已提交
404
			}
405

406
		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
D
 
Dr. Stephen Henson 已提交
407 408 409
				goto auxerr;

		/* Get each field entry */
410 411
		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
			{
D
 
Dr. Stephen Henson 已提交
412 413 414
			const ASN1_TEMPLATE *seqtt;
			ASN1_VALUE **pseqval;
			seqtt = asn1_do_adb(pval, tt, 1);
415 416
			if (!seqtt)
				goto err;
D
 
Dr. Stephen Henson 已提交
417 418
			pseqval = asn1_get_field_ptr(pval, seqtt);
			/* Have we ran out of data? */
419 420
			if (!len)
				break;
D
 
Dr. Stephen Henson 已提交
421
			q = p;
422 423 424 425 426 427
			if (asn1_check_eoc(&p, len))
				{
				if (!seq_eoc)
					{
					ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
							ASN1_R_UNEXPECTED_EOC);
D
 
Dr. Stephen Henson 已提交
428
					goto err;
429
					}
D
 
Dr. Stephen Henson 已提交
430 431 432 433
				len -= p - q;
				seq_eoc = 0;
				q = p;
				break;
434 435 436 437 438 439
				}
			/* This determines the OPTIONAL flag value. The field
			 * cannot be omitted if it is the last of a SEQUENCE
			 * and there is still data to be read. This isn't
			 * strictly necessary but it increases efficiency in
			 * some cases.
D
 
Dr. Stephen Henson 已提交
440
			 */
441 442
			if (i == (it->tcount - 1))
				isopt = 0;
443
			else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
444 445 446 447 448 449 450
			/* attempt to read in field, allowing each to be
			 * OPTIONAL */

			ret = asn1_template_ex_d2i(pseqval, &p, len,
							seqtt, isopt, ctx);
			if (!ret)
				{
D
 
Dr. Stephen Henson 已提交
451 452
				errtt = seqtt;
				goto err;
453 454 455 456 457
				}
			else if (ret == -1)
				{
				/* OPTIONAL component absent.
				 * Free and zero the field.
D
 
Dr. Stephen Henson 已提交
458 459 460
				 */
				ASN1_template_free(pseqval, seqtt);
				continue;
461
				}
D
 
Dr. Stephen Henson 已提交
462 463
			/* Update length */
			len -= p - q;
464 465
			}

D
 
Dr. Stephen Henson 已提交
466
		/* Check for EOC if expecting one */
467 468
		if (seq_eoc && !asn1_check_eoc(&p, len))
			{
D
 
Dr. Stephen Henson 已提交
469 470
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);
			goto err;
471
			}
D
 
Dr. Stephen Henson 已提交
472
		/* Check all data read */
473 474 475 476
		if (!seq_nolen && len)
			{
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
					ASN1_R_SEQUENCE_LENGTH_MISMATCH);
D
 
Dr. Stephen Henson 已提交
477
			goto err;
478
			}
D
 
Dr. Stephen Henson 已提交
479 480 481 482 483

		/* If we get here we've got no more data in the SEQUENCE,
		 * however we may not have read all fields so check all
		 * remaining are OPTIONAL and clear any that are.
		 */
484 485
		for (; i < it->tcount; tt++, i++)
			{
D
 
Dr. Stephen Henson 已提交
486 487
			const ASN1_TEMPLATE *seqtt;
			seqtt = asn1_do_adb(pval, tt, 1);
488 489 490 491
			if (!seqtt)
				goto err;
			if (seqtt->flags & ASN1_TFLG_OPTIONAL)
				{
D
 
Dr. Stephen Henson 已提交
492 493 494
				ASN1_VALUE **pseqval;
				pseqval = asn1_get_field_ptr(pval, seqtt);
				ASN1_template_free(pseqval, seqtt);
495 496 497
				}
			else
				{
D
 
Dr. Stephen Henson 已提交
498
				errtt = seqtt;
499 500
				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
							ASN1_R_FIELD_MISSING);
D
 
Dr. Stephen Henson 已提交
501
				goto err;
502
				}
D
 
Dr. Stephen Henson 已提交
503 504
			}
		/* Save encoding */
505 506
		if (!asn1_enc_save(pval, *in, p - *in, it))
			goto auxerr;
D
 
Dr. Stephen Henson 已提交
507
		*in = p;
508
		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
D
 
Dr. Stephen Henson 已提交
509 510 511 512 513
				goto auxerr;
		return 1;

		default:
		return 0;
514
		}
D
 
Dr. Stephen Henson 已提交
515 516 517 518
	auxerr:
	ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
	err:
	ASN1_item_ex_free(pval, it);
519 520 521 522 523
	if (errtt)
		ERR_add_error_data(4, "Field=", errtt->field_name,
					", Type=", it->sname);
	else
		ERR_add_error_data(2, "Type=", it->sname);
D
 
Dr. Stephen Henson 已提交
524
	return 0;
525
	}
D
 
Dr. Stephen Henson 已提交
526

527 528
/* Templates are handled with two separate functions.
 * One handles any EXPLICIT tag and the other handles the rest.
D
 
Dr. Stephen Henson 已提交
529 530
 */

531 532 533 534 535
static int asn1_template_ex_d2i(ASN1_VALUE **val,
				const unsigned char **in, long inlen,
				const ASN1_TEMPLATE *tt, char opt,
							ASN1_TLC *ctx)
	{
D
 
Dr. Stephen Henson 已提交
536 537 538
	int flags, aclass;
	int ret;
	long len;
539
	const unsigned char *p, *q;
D
 
Dr. Stephen Henson 已提交
540
	char exp_eoc;
541 542
	if (!val)
		return 0;
D
 
Dr. Stephen Henson 已提交
543 544 545 546 547 548
	flags = tt->flags;
	aclass = flags & ASN1_TFLG_TAG_CLASS;

	p = *in;

	/* Check if EXPLICIT tag expected */
549 550
	if (flags & ASN1_TFLG_EXPTAG)
		{
D
 
Dr. Stephen Henson 已提交
551
		char cst;
552 553 554
		/* Need to work out amount of data available to the inner
		 * content and where it starts: so read in EXPLICIT header to
		 * get the info.
D
 
Dr. Stephen Henson 已提交
555
		 */
556 557
		ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
					&p, inlen, tt->tag, aclass, opt, ctx);
D
 
Dr. Stephen Henson 已提交
558
		q = p;
559 560 561 562
		if (!ret)
			{
			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
					ERR_R_NESTED_ASN1_ERROR);
D
 
Dr. Stephen Henson 已提交
563
			return 0;
564 565 566 567 568 569 570
			}
		else if (ret == -1)
			return -1;
		if (!cst)
			{
			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
					ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
D
 
Dr. Stephen Henson 已提交
571
			return 0;
572
			}
D
 
Dr. Stephen Henson 已提交
573 574
		/* We've found the field so it can't be OPTIONAL now */
		ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
575 576 577 578
		if (!ret)
			{
			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
					ERR_R_NESTED_ASN1_ERROR);
D
 
Dr. Stephen Henson 已提交
579
			return 0;
580
			}
D
 
Dr. Stephen Henson 已提交
581 582
		/* We read the field in OK so update length */
		len -= p - q;
583 584
		if (exp_eoc)
			{
D
 
Dr. Stephen Henson 已提交
585
			/* If NDEF we must have an EOC here */
586 587
			if (!asn1_check_eoc(&p, len))
				{
B
Bodo Möller 已提交
588
				ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
589
						ASN1_R_MISSING_EOC);
D
 
Dr. Stephen Henson 已提交
590
				goto err;
591
				}
D
 
Dr. Stephen Henson 已提交
592
			}
593 594 595 596 597 598
		else
			{
			/* Otherwise we must hit the EXPLICIT tag end or its
			 * an error */
			if (len)
				{
B
Bodo Möller 已提交
599
				ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
600
					ASN1_R_EXPLICIT_LENGTH_MISMATCH);
D
 
Dr. Stephen Henson 已提交
601
				goto err;
602
				}
D
 
Dr. Stephen Henson 已提交
603 604
			}
		}
605 606 607
		else 
			return asn1_template_noexp_d2i(val, in, inlen,
								tt, opt, ctx);
D
 
Dr. Stephen Henson 已提交
608 609 610 611 612 613 614 615

	*in = p;
	return 1;

	err:
	ASN1_template_free(val, tt);
	*val = NULL;
	return 0;
616
	}
D
 
Dr. Stephen Henson 已提交
617

618 619 620 621 622
static int asn1_template_noexp_d2i(ASN1_VALUE **val,
				const unsigned char **in, long len,
				const ASN1_TEMPLATE *tt, char opt,
				ASN1_TLC *ctx)
	{
D
 
Dr. Stephen Henson 已提交
623 624
	int flags, aclass;
	int ret;
625
	const unsigned char *p, *q;
626 627
	if (!val)
		return 0;
D
 
Dr. Stephen Henson 已提交
628 629 630 631 632 633
	flags = tt->flags;
	aclass = flags & ASN1_TFLG_TAG_CLASS;

	p = *in;
	q = p;

634 635
	if (flags & ASN1_TFLG_SK_MASK)
		{
D
 
Dr. Stephen Henson 已提交
636 637 638 639
		/* SET OF, SEQUENCE OF */
		int sktag, skaclass;
		char sk_eoc;
		/* First work out expected inner tag value */
640 641
		if (flags & ASN1_TFLG_IMPTAG)
			{
D
 
Dr. Stephen Henson 已提交
642 643
			sktag = tt->tag;
			skaclass = aclass;
644 645 646
			}
		else
			{
D
 
Dr. Stephen Henson 已提交
647
			skaclass = V_ASN1_UNIVERSAL;
648 649 650 651 652
			if (flags & ASN1_TFLG_SET_OF)
				sktag = V_ASN1_SET;
			else
				sktag = V_ASN1_SEQUENCE;
			}
D
 
Dr. Stephen Henson 已提交
653
		/* Get the tag */
654 655 656 657
		ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
					&p, len, sktag, skaclass, opt, ctx);
		if (!ret)
			{
B
Bodo Möller 已提交
658
			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
659
						ERR_R_NESTED_ASN1_ERROR);
D
 
Dr. Stephen Henson 已提交
660
			return 0;
661 662 663 664 665 666 667
			}
		else if (ret == -1)
			return -1;
		if (!*val)
			*val = (ASN1_VALUE *)sk_new_null();
		else
			{
D
 
Dr. Stephen Henson 已提交
668 669 670
			/* We've got a valid STACK: free up any items present */
			STACK *sktmp = (STACK *)*val;
			ASN1_VALUE *vtmp;
671 672
			while(sk_num(sktmp) > 0)
				{
D
 
Dr. Stephen Henson 已提交
673
				vtmp = (ASN1_VALUE *)sk_pop(sktmp);
674 675 676
				ASN1_item_ex_free(&vtmp,
						ASN1_ITEM_ptr(tt->item));
				}
D
 
Dr. Stephen Henson 已提交
677 678
			}
				
679 680
		if (!*val)
			{
B
Bodo Möller 已提交
681
			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
682
						ERR_R_MALLOC_FAILURE);
D
 
Dr. Stephen Henson 已提交
683
			goto err;
684 685
			}

D
 
Dr. Stephen Henson 已提交
686
		/* Read as many items as we can */
687 688
		while(len > 0)
			{
D
 
Dr. Stephen Henson 已提交
689 690 691
			ASN1_VALUE *skfield;
			q = p;
			/* See if EOC found */
692 693 694 695
			if (asn1_check_eoc(&p, len))
				{
				if (!sk_eoc)
					{
B
Bodo Möller 已提交
696
					ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
697
							ASN1_R_UNEXPECTED_EOC);
D
 
Dr. Stephen Henson 已提交
698
					goto err;
699
					}
D
 
Dr. Stephen Henson 已提交
700 701 702
				len -= p - q;
				sk_eoc = 0;
				break;
703
				}
D
 
Dr. Stephen Henson 已提交
704
			skfield = NULL;
705 706 707 708
			if (!ASN1_item_ex_d2i(&skfield, &p, len,
						ASN1_ITEM_ptr(tt->item),
						-1, 0, 0, ctx))
				{
B
Bodo Möller 已提交
709
				ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
710
					ERR_R_NESTED_ASN1_ERROR);
D
 
Dr. Stephen Henson 已提交
711
				goto err;
712
				}
D
 
Dr. Stephen Henson 已提交
713
			len -= p - q;
714 715
			if (!sk_push((STACK *)*val, (char *)skfield))
				{
B
Bodo Möller 已提交
716
				ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
717
						ERR_R_MALLOC_FAILURE);
D
 
Dr. Stephen Henson 已提交
718
				goto err;
719
				}
D
 
Dr. Stephen Henson 已提交
720
			}
721 722
		if (sk_eoc)
			{
B
Bodo Möller 已提交
723
			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC);
D
 
Dr. Stephen Henson 已提交
724
			goto err;
725
			}
D
 
Dr. Stephen Henson 已提交
726
		}
727 728
	else if (flags & ASN1_TFLG_IMPTAG)
		{
D
 
Dr. Stephen Henson 已提交
729
		/* IMPLICIT tagging */
730 731 732 733
		ret = ASN1_item_ex_d2i(val, &p, len,
			ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
		if (!ret)
			{
B
Bodo Möller 已提交
734
			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
735
						ERR_R_NESTED_ASN1_ERROR);
D
 
Dr. Stephen Henson 已提交
736
			goto err;
737 738 739 740 741 742
			}
		else if (ret == -1)
			return -1;
		}
	else
		{
D
 
Dr. Stephen Henson 已提交
743
		/* Nothing special */
744 745 746 747
		ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
							-1, 0, opt, ctx);
		if (!ret)
			{
B
Bodo Möller 已提交
748
			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
749
					ERR_R_NESTED_ASN1_ERROR);
D
 
Dr. Stephen Henson 已提交
750
			goto err;
751 752 753 754
			}
		else if (ret == -1)
			return -1;
		}
D
 
Dr. Stephen Henson 已提交
755 756 757 758 759 760 761 762

	*in = p;
	return 1;

	err:
	ASN1_template_free(val, tt);
	*val = NULL;
	return 0;
763
	}
D
 
Dr. Stephen Henson 已提交
764

765 766 767 768 769
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
				const unsigned char **in, long inlen, 
				const ASN1_ITEM *it,
				int tag, int aclass, char opt, ASN1_TLC *ctx)
	{
D
 
Dr. Stephen Henson 已提交
770 771 772
	int ret = 0, utype;
	long plen;
	char cst, inf, free_cont = 0;
773
	const unsigned char *p;
D
 
Dr. Stephen Henson 已提交
774
	BUF_MEM buf;
775
	const unsigned char *cont = NULL;
D
 
Dr. Stephen Henson 已提交
776
	long len; 
777 778
	if (!pval)
		{
D
 
Dr. Stephen Henson 已提交
779 780
		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
		return 0; /* Should never happen */
781
		}
D
 
Dr. Stephen Henson 已提交
782

783 784
	if (it->itype == ASN1_ITYPE_MSTRING)
		{
D
 
Dr. Stephen Henson 已提交
785 786
		utype = tag;
		tag = -1;
787 788 789
		}
	else
		utype = it->utype;
D
 
Dr. Stephen Henson 已提交
790

791 792
	if (utype == V_ASN1_ANY)
		{
D
 
Dr. Stephen Henson 已提交
793 794
		/* If type is ANY need to figure out type from tag */
		unsigned char oclass;
795 796 797 798
		if (tag >= 0)
			{
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
					ASN1_R_ILLEGAL_TAGGED_ANY);
D
 
Dr. Stephen Henson 已提交
799
			return 0;
800 801 802 803 804
			}
		if (opt)
			{
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
					ASN1_R_ILLEGAL_OPTIONAL_ANY);
D
 
Dr. Stephen Henson 已提交
805
			return 0;
806
			}
D
 
Dr. Stephen Henson 已提交
807
		p = *in;
808 809 810 811 812 813
		ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
					&p, inlen, -1, 0, 0, ctx);
		if (!ret)
			{
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
					ERR_R_NESTED_ASN1_ERROR);
D
 
Dr. Stephen Henson 已提交
814
			return 0;
815 816 817
			}
		if (oclass != V_ASN1_UNIVERSAL)
			utype = V_ASN1_OTHER;
D
 
Dr. Stephen Henson 已提交
818
		}
819 820
	if (tag == -1)
		{
D
 
Dr. Stephen Henson 已提交
821 822
		tag = utype;
		aclass = V_ASN1_UNIVERSAL;
823
		}
D
 
Dr. Stephen Henson 已提交
824 825
	p = *in;
	/* Check header */
826 827 828 829
	ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
				&p, inlen, tag, aclass, opt, ctx);
	if (!ret)
		{
D
 
Dr. Stephen Henson 已提交
830 831
		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
		return 0;
832 833 834
		}
	else if (ret == -1)
		return -1;
835
        ret = 0;
D
 
Dr. Stephen Henson 已提交
836
	/* SEQUENCE, SET and "OTHER" are left in encoded form */
837 838 839 840 841
	if ((utype == V_ASN1_SEQUENCE)
		|| (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER))
		{
		/* Clear context cache for type OTHER because the auto clear
		 * when we have a exact match wont work
D
 
Dr. Stephen Henson 已提交
842
		 */
843 844
		if (utype == V_ASN1_OTHER)
			{
D
 
Dr. Stephen Henson 已提交
845
			asn1_tlc_clear(ctx);
846
			}
D
 
Dr. Stephen Henson 已提交
847
		/* SEQUENCE and SET must be constructed */
848 849 850 851
		else if (!cst)
			{
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
				ASN1_R_TYPE_NOT_CONSTRUCTED);
D
 
Dr. Stephen Henson 已提交
852
			return 0;
853
			}
D
 
Dr. Stephen Henson 已提交
854 855 856

		cont = *in;
		/* If indefinite length constructed find the real end */
857 858
		if (inf)
			{
859
			if (!asn1_find_end(&p, plen, inf))
860
				 goto err;
D
 
Dr. Stephen Henson 已提交
861
			len = p - cont;
862 863 864
			}
		else
			{
D
 
Dr. Stephen Henson 已提交
865 866 867
			len = p - cont + plen;
			p += plen;
			buf.data = NULL;
868
			}
D
 
Dr. Stephen Henson 已提交
869
		}
870 871
	else if (cst)
		{
D
 
Dr. Stephen Henson 已提交
872 873 874 875 876 877 878 879 880
		buf.length = 0;
		buf.max = 0;
		buf.data = NULL;
		/* Should really check the internal tags are correct but
		 * some things may get this wrong. The relevant specs
		 * say that constructed string types should be OCTET STRINGs
		 * internally irrespective of the type. So instead just check
		 * for UNIVERSAL class and ignore the tag.
		 */
881
		if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL))
D
Dr. Stephen Henson 已提交
882 883
			{
			free_cont = 1;
884
			goto err;
D
Dr. Stephen Henson 已提交
885
			}
D
 
Dr. Stephen Henson 已提交
886
		len = buf.length;
D
Dr. Stephen Henson 已提交
887
		/* Append a final null to string */
888 889 890 891
		if (!BUF_MEM_grow_clean(&buf, len + 1))
			{
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
						ERR_R_MALLOC_FAILURE);
D
Dr. Stephen Henson 已提交
892
			return 0;
893
			}
D
Dr. Stephen Henson 已提交
894
		buf.data[len] = 0;
895
		cont = (const unsigned char *)buf.data;
D
 
Dr. Stephen Henson 已提交
896
		free_cont = 1;
897 898 899
		}
	else
		{
D
 
Dr. Stephen Henson 已提交
900 901 902
		cont = p;
		len = plen;
		p += plen;
903
		}
D
 
Dr. Stephen Henson 已提交
904 905

	/* We now have content length and type: translate into a structure */
906 907
	if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
		goto err;
D
 
Dr. Stephen Henson 已提交
908 909 910 911

	*in = p;
	ret = 1;
	err:
912
	if (free_cont && buf.data) OPENSSL_free(buf.data);
D
 
Dr. Stephen Henson 已提交
913
	return ret;
914
	}
D
 
Dr. Stephen Henson 已提交
915 916 917

/* Translate ASN1 content octets into a structure */

918 919 920
int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
			int utype, char *free_cont, const ASN1_ITEM *it)
	{
921
	ASN1_VALUE **opval = NULL;
D
 
Dr. Stephen Henson 已提交
922 923 924 925
	ASN1_STRING *stmp;
	ASN1_TYPE *typ = NULL;
	int ret = 0;
	const ASN1_PRIMITIVE_FUNCS *pf;
926
	ASN1_INTEGER **tint;
D
 
Dr. Stephen Henson 已提交
927
	pf = it->funcs;
928 929 930

	if (pf && pf->prim_c2i)
		return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
D
 
Dr. Stephen Henson 已提交
931
	/* If ANY type clear type and set pointer to internal value */
932 933 934 935
	if (it->utype == V_ASN1_ANY)
		{
		if (!*pval)
			{
D
 
Dr. Stephen Henson 已提交
936
			typ = ASN1_TYPE_new();
N
Nils Larsch 已提交
937 938
			if (typ == NULL)
				goto err;
D
 
Dr. Stephen Henson 已提交
939
			*pval = (ASN1_VALUE *)typ;
940 941 942 943 944 945
			}
		else
			typ = (ASN1_TYPE *)*pval;

		if (utype != typ->type)
			ASN1_TYPE_set(typ, utype, NULL);
946
		opval = pval;
D
 
Dr. Stephen Henson 已提交
947
		pval = (ASN1_VALUE **)&typ->value.ptr;
948 949 950
		}
	switch(utype)
		{
D
 
Dr. Stephen Henson 已提交
951
		case V_ASN1_OBJECT:
952 953
		if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
			goto err;
D
 
Dr. Stephen Henson 已提交
954 955 956
		break;

		case V_ASN1_NULL:
957 958
		if (len)
			{
B
Bodo Möller 已提交
959
			ASN1err(ASN1_F_ASN1_EX_C2I,
960
						ASN1_R_NULL_IS_WRONG_LENGTH);
D
 
Dr. Stephen Henson 已提交
961
			goto err;
962
			}
D
 
Dr. Stephen Henson 已提交
963 964 965 966
		*pval = (ASN1_VALUE *)1;
		break;

		case V_ASN1_BOOLEAN:
967 968
		if (len != 1)
			{
B
Bodo Möller 已提交
969
			ASN1err(ASN1_F_ASN1_EX_C2I,
970
						ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
D
 
Dr. Stephen Henson 已提交
971
			goto err;
972 973 974
			}
		else
			{
D
 
Dr. Stephen Henson 已提交
975 976 977
			ASN1_BOOLEAN *tbool;
			tbool = (ASN1_BOOLEAN *)pval;
			*tbool = *cont;
978
			}
D
 
Dr. Stephen Henson 已提交
979 980 981
		break;

		case V_ASN1_BIT_STRING:
982 983
		if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
			goto err;
D
 
Dr. Stephen Henson 已提交
984 985 986 987 988 989
		break;

		case V_ASN1_INTEGER:
		case V_ASN1_NEG_INTEGER:
		case V_ASN1_ENUMERATED:
		case V_ASN1_NEG_ENUMERATED:
990
		tint = (ASN1_INTEGER **)pval;
991 992
		if (!c2i_ASN1_INTEGER(tint, &cont, len))
			goto err;
993 994
		/* Fixup type to match the expected form */
		(*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
D
 
Dr. Stephen Henson 已提交
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015
		break;

		case V_ASN1_OCTET_STRING:
		case V_ASN1_NUMERICSTRING:
		case V_ASN1_PRINTABLESTRING:
		case V_ASN1_T61STRING:
		case V_ASN1_VIDEOTEXSTRING:
		case V_ASN1_IA5STRING:
		case V_ASN1_UTCTIME:
		case V_ASN1_GENERALIZEDTIME:
		case V_ASN1_GRAPHICSTRING:
		case V_ASN1_VISIBLESTRING:
		case V_ASN1_GENERALSTRING:
		case V_ASN1_UNIVERSALSTRING:
		case V_ASN1_BMPSTRING:
		case V_ASN1_UTF8STRING:
		case V_ASN1_OTHER:
		case V_ASN1_SET:
		case V_ASN1_SEQUENCE:
		default:
		/* All based on ASN1_STRING and handled the same */
1016 1017
		if (!*pval)
			{
D
 
Dr. Stephen Henson 已提交
1018
			stmp = ASN1_STRING_type_new(utype);
1019 1020
			if (!stmp)
				{
B
Bodo Möller 已提交
1021
				ASN1err(ASN1_F_ASN1_EX_C2I,
1022
							ERR_R_MALLOC_FAILURE);
D
 
Dr. Stephen Henson 已提交
1023
				goto err;
1024
				}
D
 
Dr. Stephen Henson 已提交
1025
			*pval = (ASN1_VALUE *)stmp;
1026 1027 1028
			}
		else
			{
D
 
Dr. Stephen Henson 已提交
1029 1030
			stmp = (ASN1_STRING *)*pval;
			stmp->type = utype;
1031
			}
D
 
Dr. Stephen Henson 已提交
1032
		/* If we've already allocated a buffer use it */
1033 1034 1035 1036
		if (*free_cont)
			{
			if (stmp->data)
				OPENSSL_free(stmp->data);
1037
			stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
D
 
Dr. Stephen Henson 已提交
1038 1039
			stmp->length = len;
			*free_cont = 0;
1040 1041 1042 1043 1044
			}
		else
			{
			if (!ASN1_STRING_set(stmp, cont, len))
				{
B
Bodo Möller 已提交
1045
				ASN1err(ASN1_F_ASN1_EX_C2I,
1046
							ERR_R_MALLOC_FAILURE);
D
 
Dr. Stephen Henson 已提交
1047 1048 1049
				ASN1_STRING_free(stmp);	
				*pval = NULL;
				goto err;
1050
				}
D
 
Dr. Stephen Henson 已提交
1051 1052
			}
		break;
1053
		}
D
 
Dr. Stephen Henson 已提交
1054
	/* If ASN1_ANY and NULL type fix up value */
1055 1056
	if (typ && (utype == V_ASN1_NULL))
		 typ->value.ptr = NULL;
D
 
Dr. Stephen Henson 已提交
1057 1058 1059

	ret = 1;
	err:
1060
	if (!ret)
1061 1062 1063 1064 1065
		{
		ASN1_TYPE_free(typ);
		if (opval)
			*opval = NULL;
		}
D
 
Dr. Stephen Henson 已提交
1066
	return ret;
1067
	}
D
 
Dr. Stephen Henson 已提交
1068

1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089

/* This function finds the end of an ASN1 structure when passed its maximum
 * length, whether it is indefinite length and a pointer to the content.
 * This is more efficient than calling asn1_collect because it does not
 * recurse on each indefinite length header.
 */

static int asn1_find_end(const unsigned char **in, long len, char inf)
	{
	int expected_eoc;
	long plen;
	const unsigned char *p = *in, *q;
	/* If not indefinite length constructed just add length */
	if (inf == 0)
		{
		*in += len;
		return 1;
		}
	expected_eoc = 1;
	/* Indefinite length constructed form. Find the end when enough EOCs
	 * are found. If more indefinite length constructed headers
D
Typo.  
Dr. Stephen Henson 已提交
1090
	 * are encountered increment the expected eoc count otherwise just
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124
	 * skip to the end of the data.
	 */
	while (len > 0)
		{
		if(asn1_check_eoc(&p, len))
			{
			expected_eoc--;
			if (expected_eoc == 0)
				break;
			len -= 2;
			continue;
			}
		q = p;
		/* Just read in a header: only care about the length */
		if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
				-1, 0, 0, NULL))
			{
			ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
			return 0;
			}
		if (inf)
			expected_eoc++;
		else
			p += plen;
		len -= p - q;
		}
	if (expected_eoc)
		{
		ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC);
		return 0;
		}
	*in = p;
	return 1;
	}
D
 
Dr. Stephen Henson 已提交
1125 1126 1127
/* This function collects the asn1 data from a constructred string
 * type into a buffer. The values of 'in' and 'len' should refer
 * to the contents of the constructed type and 'inf' should be set
1128
 * if it is indefinite length.
D
 
Dr. Stephen Henson 已提交
1129 1130
 */

1131 1132 1133
static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
				char inf, int tag, int aclass)
	{
1134
	const unsigned char *p, *q;
D
 
Dr. Stephen Henson 已提交
1135 1136 1137 1138
	long plen;
	char cst, ininf;
	p = *in;
	inf &= 1;
1139 1140 1141 1142
	/* If no buffer and not indefinite length constructed just pass over
	 * the encoded data */
	if (!buf && !inf)
		{
D
 
Dr. Stephen Henson 已提交
1143 1144
		*in += len;
		return 1;
1145 1146 1147
		}
	while(len > 0)
		{
D
 
Dr. Stephen Henson 已提交
1148 1149
		q = p;
		/* Check for EOC */
1150 1151 1152 1153 1154 1155 1156 1157
		if (asn1_check_eoc(&p, len))
			{
			/* EOC is illegal outside indefinite length
			 * constructed form */
			if (!inf)
				{
				ASN1err(ASN1_F_ASN1_COLLECT,
					ASN1_R_UNEXPECTED_EOC);
D
 
Dr. Stephen Henson 已提交
1158
				return 0;
1159
				}
D
 
Dr. Stephen Henson 已提交
1160 1161
			inf = 0;
			break;
1162 1163 1164 1165 1166
			}

		if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
					len, tag, aclass, 0, NULL))
			{
D
 
Dr. Stephen Henson 已提交
1167 1168
			ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
			return 0;
1169 1170
			}

D
 
Dr. Stephen Henson 已提交
1171
		/* If indefinite length constructed update max length */
1172 1173
		if (cst)
			{
1174
#ifdef OPENSSL_ALLOW_NESTED_ASN1_STRINGS
1175 1176
			if (!asn1_collect(buf, &p, plen, ininf, tag, aclass))
				return 0;
1177 1178 1179 1180
#else
			ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING);
			return 0;
#endif
1181
			}
1182
		else if (plen && !collect_data(buf, &p, plen))
1183
			return 0;
D
 
Dr. Stephen Henson 已提交
1184
		len -= p - q;
1185 1186 1187
		}
	if (inf)
		{
D
 
Dr. Stephen Henson 已提交
1188 1189
		ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
		return 0;
1190
		}
D
 
Dr. Stephen Henson 已提交
1191 1192
	*in = p;
	return 1;
1193
	}
D
 
Dr. Stephen Henson 已提交
1194

1195
static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
1196 1197 1198 1199 1200 1201 1202 1203 1204
	{
	int len;
	if (buf)
		{
		len = buf->length;
		if (!BUF_MEM_grow_clean(buf, len + plen))
			{
			ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
			return 0;
D
 
Dr. Stephen Henson 已提交
1205
			}
1206
		memcpy(buf->data + len, *p, plen);
D
 
Dr. Stephen Henson 已提交
1207
		}
1208 1209 1210
	*p += plen;
	return 1;
	}
D
 
Dr. Stephen Henson 已提交
1211 1212 1213

/* Check for ASN1 EOC and swallow it if found */

1214
static int asn1_check_eoc(const unsigned char **in, long len)
1215
	{
1216
	const unsigned char *p;
1217
	if (len < 2) return 0;
D
 
Dr. Stephen Henson 已提交
1218
	p = *in;
1219 1220
	if (!p[0] && !p[1])
		{
D
 
Dr. Stephen Henson 已提交
1221 1222
		*in += 2;
		return 1;
1223
		}
D
 
Dr. Stephen Henson 已提交
1224
	return 0;
1225
	}
D
 
Dr. Stephen Henson 已提交
1226 1227 1228 1229 1230 1231 1232 1233

/* Check an ASN1 tag and length: a bit like ASN1_get_object
 * but it sets the length for indefinite length constructed
 * form, we don't know the exact length but we can set an
 * upper bound to the amount of data available minus the
 * header length just read.
 */

1234 1235 1236 1237 1238 1239
static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
				char *inf, char *cst,
				const unsigned char **in, long len,
				int exptag, int expclass, char opt,
				ASN1_TLC *ctx)
	{
D
 
Dr. Stephen Henson 已提交
1240 1241 1242
	int i;
	int ptag, pclass;
	long plen;
1243
	const unsigned char *p, *q;
D
 
Dr. Stephen Henson 已提交
1244 1245 1246
	p = *in;
	q = p;

1247 1248
	if (ctx && ctx->valid)
		{
D
 
Dr. Stephen Henson 已提交
1249 1250 1251 1252 1253
		i = ctx->ret;
		plen = ctx->plen;
		pclass = ctx->pclass;
		ptag = ctx->ptag;
		p += ctx->hdrlen;
1254 1255 1256
		}
	else
		{
D
 
Dr. Stephen Henson 已提交
1257
		i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
1258 1259
		if (ctx)
			{
D
 
Dr. Stephen Henson 已提交
1260 1261 1262 1263 1264 1265
			ctx->ret = i;
			ctx->plen = plen;
			ctx->pclass = pclass;
			ctx->ptag = ptag;
			ctx->hdrlen = p - q;
			ctx->valid = 1;
D
 
Dr. Stephen Henson 已提交
1266 1267
			/* If definite length, and no error, length +
			 * header can't exceed total amount of data available. 
D
 
Dr. Stephen Henson 已提交
1268
			 */
1269 1270 1271 1272
			if (!(i & 0x81) && ((plen + ctx->hdrlen) > len))
				{
				ASN1err(ASN1_F_ASN1_CHECK_TLEN,
							ASN1_R_TOO_LONG);
D
 
Dr. Stephen Henson 已提交
1273 1274
				asn1_tlc_clear(ctx);
				return 0;
1275
				}
D
 
Dr. Stephen Henson 已提交
1276
			}
D
 
Dr. Stephen Henson 已提交
1277
		}
D
 
Dr. Stephen Henson 已提交
1278

1279 1280
	if (i & 0x80)
		{
D
 
Dr. Stephen Henson 已提交
1281 1282 1283
		ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
		asn1_tlc_clear(ctx);
		return 0;
1284 1285 1286 1287 1288 1289 1290
		}
	if (exptag >= 0)
		{
		if ((exptag != ptag) || (expclass != pclass))
			{
			/* If type is OPTIONAL, not an error:
			 * indicate missing type.
D
 
Dr. Stephen Henson 已提交
1291
			 */
1292
			if (opt) return -1;
D
 
Dr. Stephen Henson 已提交
1293 1294 1295
			asn1_tlc_clear(ctx);
			ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
			return 0;
1296 1297 1298
			}
		/* We have a tag and class match:
		 * assume we are going to do something with it */
D
 
Dr. Stephen Henson 已提交
1299
		asn1_tlc_clear(ctx);
1300
		}
D
 
Dr. Stephen Henson 已提交
1301

1302 1303
	if (i & 1)
		plen = len - (p - q);
D
 
Dr. Stephen Henson 已提交
1304

1305 1306
	if (inf)
		*inf = i & 1;
D
 
Dr. Stephen Henson 已提交
1307

1308 1309
	if (cst)
		*cst = i & V_ASN1_CONSTRUCTED;
D
 
Dr. Stephen Henson 已提交
1310

1311 1312 1313 1314 1315 1316 1317 1318
	if (olen)
		*olen = plen;

	if (oclass)
		*oclass = pclass;

	if (otag)
		*otag = ptag;
D
 
Dr. Stephen Henson 已提交
1319 1320 1321

	*in = p;
	return 1;
1322
	}