tasn_dec.c 30.4 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 101 102 103 104 105 106 107 108
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 */
0,	0,	B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING,   /* tags 16-19 */
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;
161 162 163
	const unsigned char *p, *q;
	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;
286 287 288
			*wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
								| it->utype);
			}
D
 
Dr. Stephen Henson 已提交
289 290 291

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

292 293 294 295 296
		if (tag != -1)
			*wp = imphack;

		if (ptmpval)
			return 1;
D
 
Dr. Stephen Henson 已提交
297 298 299 300 301 302

		ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
		goto err;


		case ASN1_ITYPE_CHOICE:
303
		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
D
 
Dr. Stephen Henson 已提交
304
				goto auxerr;
305 306

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

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

D
 
Dr. Stephen Henson 已提交
351 352
		asn1_set_choice_selector(pval, i, it);
		*in = p;
353
		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
D
 
Dr. Stephen Henson 已提交
354 355 356
				goto auxerr;
		return 1;

357
		case ASN1_ITYPE_NDEF_SEQUENCE:
D
 
Dr. Stephen Henson 已提交
358 359 360 361 362
		case ASN1_ITYPE_SEQUENCE:
		p = *in;
		tmplen = len;

		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
363 364
		if (tag == -1)
			{
D
 
Dr. Stephen Henson 已提交
365 366
			tag = V_ASN1_SEQUENCE;
			aclass = V_ASN1_UNIVERSAL;
367
			}
D
 
Dr. Stephen Henson 已提交
368
		/* Get SEQUENCE length and update len, p */
369 370 371 372 373 374
		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 已提交
375
			goto err;
376 377 378 379 380
			}
		else if (ret == -1)
			return -1;
		if (aux && (aux->flags & ASN1_AFLG_BROKEN))
			{
D
 
Dr. Stephen Henson 已提交
381 382
			len = tmplen - (p - *in);
			seq_nolen = 1;
383 384 385 386 387 388 389
			}
		/* 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 已提交
390
			goto err;
391
			}
D
 
Dr. Stephen Henson 已提交
392

393
		if (!*pval && !ASN1_item_ex_new(pval, it))
394 395 396 397
			{
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
				ERR_R_NESTED_ASN1_ERROR);
			goto err;
D
 
Dr. Stephen Henson 已提交
398
			}
399

400
		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
D
 
Dr. Stephen Henson 已提交
401 402 403
				goto auxerr;

		/* Get each field entry */
404 405
		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
			{
D
 
Dr. Stephen Henson 已提交
406 407 408
			const ASN1_TEMPLATE *seqtt;
			ASN1_VALUE **pseqval;
			seqtt = asn1_do_adb(pval, tt, 1);
409 410
			if (!seqtt)
				goto err;
D
 
Dr. Stephen Henson 已提交
411 412
			pseqval = asn1_get_field_ptr(pval, seqtt);
			/* Have we ran out of data? */
413 414
			if (!len)
				break;
D
 
Dr. Stephen Henson 已提交
415
			q = p;
416 417 418 419 420 421
			if (asn1_check_eoc(&p, len))
				{
				if (!seq_eoc)
					{
					ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
							ASN1_R_UNEXPECTED_EOC);
D
 
Dr. Stephen Henson 已提交
422
					goto err;
423
					}
D
 
Dr. Stephen Henson 已提交
424 425 426 427
				len -= p - q;
				seq_eoc = 0;
				q = p;
				break;
428 429 430 431 432 433
				}
			/* 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 已提交
434
			 */
435 436
			if (i == (it->tcount - 1))
				isopt = 0;
437
			else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
438 439 440 441 442 443 444
			/* 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 已提交
445 446
				errtt = seqtt;
				goto err;
447 448 449 450 451
				}
			else if (ret == -1)
				{
				/* OPTIONAL component absent.
				 * Free and zero the field.
D
 
Dr. Stephen Henson 已提交
452 453 454
				 */
				ASN1_template_free(pseqval, seqtt);
				continue;
455
				}
D
 
Dr. Stephen Henson 已提交
456 457
			/* Update length */
			len -= p - q;
458 459
			}

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

		/* 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.
		 */
478 479
		for (; i < it->tcount; tt++, i++)
			{
D
 
Dr. Stephen Henson 已提交
480 481
			const ASN1_TEMPLATE *seqtt;
			seqtt = asn1_do_adb(pval, tt, 1);
482 483 484 485
			if (!seqtt)
				goto err;
			if (seqtt->flags & ASN1_TFLG_OPTIONAL)
				{
D
 
Dr. Stephen Henson 已提交
486 487 488
				ASN1_VALUE **pseqval;
				pseqval = asn1_get_field_ptr(pval, seqtt);
				ASN1_template_free(pseqval, seqtt);
489 490 491
				}
			else
				{
D
 
Dr. Stephen Henson 已提交
492
				errtt = seqtt;
493 494
				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
							ASN1_R_FIELD_MISSING);
D
 
Dr. Stephen Henson 已提交
495
				goto err;
496
				}
D
 
Dr. Stephen Henson 已提交
497 498
			}
		/* Save encoding */
499 500
		if (!asn1_enc_save(pval, *in, p - *in, it))
			goto auxerr;
D
 
Dr. Stephen Henson 已提交
501
		*in = p;
502
		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
D
 
Dr. Stephen Henson 已提交
503 504 505 506 507
				goto auxerr;
		return 1;

		default:
		return 0;
508
		}
D
 
Dr. Stephen Henson 已提交
509 510 511 512
	auxerr:
	ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
	err:
	ASN1_item_ex_free(pval, it);
513 514 515 516 517
	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 已提交
518
	return 0;
519
	}
D
 
Dr. Stephen Henson 已提交
520

521 522
/* Templates are handled with two separate functions.
 * One handles any EXPLICIT tag and the other handles the rest.
D
 
Dr. Stephen Henson 已提交
523 524
 */

525 526 527 528 529
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 已提交
530 531 532
	int flags, aclass;
	int ret;
	long len;
533
	const unsigned char *p, *q;
D
 
Dr. Stephen Henson 已提交
534
	char exp_eoc;
535 536
	if (!val)
		return 0;
D
 
Dr. Stephen Henson 已提交
537 538 539 540 541 542
	flags = tt->flags;
	aclass = flags & ASN1_TFLG_TAG_CLASS;

	p = *in;

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

	*in = p;
	return 1;

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

612 613 614 615 616
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 已提交
617 618
	int flags, aclass;
	int ret;
619
	const unsigned char *p, *q;
620 621
	if (!val)
		return 0;
D
 
Dr. Stephen Henson 已提交
622 623 624 625 626 627
	flags = tt->flags;
	aclass = flags & ASN1_TFLG_TAG_CLASS;

	p = *in;
	q = p;

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

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

	*in = p;
	return 1;

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

759 760 761 762 763
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 已提交
764 765 766
	int ret = 0, utype;
	long plen;
	char cst, inf, free_cont = 0;
767
	const unsigned char *p;
D
 
Dr. Stephen Henson 已提交
768
	BUF_MEM buf;
769
	const unsigned char *cont = NULL;
D
 
Dr. Stephen Henson 已提交
770
	long len; 
771 772
	if (!pval)
		{
D
 
Dr. Stephen Henson 已提交
773 774
		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
		return 0; /* Should never happen */
775
		}
D
 
Dr. Stephen Henson 已提交
776

777 778
	if (it->itype == ASN1_ITYPE_MSTRING)
		{
D
 
Dr. Stephen Henson 已提交
779 780
		utype = tag;
		tag = -1;
781 782 783
		}
	else
		utype = it->utype;
D
 
Dr. Stephen Henson 已提交
784

785 786
	if (utype == V_ASN1_ANY)
		{
D
 
Dr. Stephen Henson 已提交
787 788
		/* If type is ANY need to figure out type from tag */
		unsigned char oclass;
789 790 791 792
		if (tag >= 0)
			{
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
					ASN1_R_ILLEGAL_TAGGED_ANY);
D
 
Dr. Stephen Henson 已提交
793
			return 0;
794 795 796 797 798
			}
		if (opt)
			{
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
					ASN1_R_ILLEGAL_OPTIONAL_ANY);
D
 
Dr. Stephen Henson 已提交
799
			return 0;
800
			}
D
 
Dr. Stephen Henson 已提交
801
		p = *in;
802 803 804 805 806 807
		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 已提交
808
			return 0;
809 810 811
			}
		if (oclass != V_ASN1_UNIVERSAL)
			utype = V_ASN1_OTHER;
D
 
Dr. Stephen Henson 已提交
812
		}
813 814
	if (tag == -1)
		{
D
 
Dr. Stephen Henson 已提交
815 816
		tag = utype;
		aclass = V_ASN1_UNIVERSAL;
817
		}
D
 
Dr. Stephen Henson 已提交
818 819
	p = *in;
	/* Check header */
820 821 822 823
	ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
				&p, inlen, tag, aclass, opt, ctx);
	if (!ret)
		{
D
 
Dr. Stephen Henson 已提交
824 825
		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
		return 0;
826 827 828
		}
	else if (ret == -1)
		return -1;
D
 
Dr. Stephen Henson 已提交
829
	/* SEQUENCE, SET and "OTHER" are left in encoded form */
830 831 832 833 834
	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 已提交
835
		 */
836 837
		if (utype == V_ASN1_OTHER)
			{
D
 
Dr. Stephen Henson 已提交
838
			asn1_tlc_clear(ctx);
839
			}
D
 
Dr. Stephen Henson 已提交
840
		/* SEQUENCE and SET must be constructed */
841 842 843 844
		else if (!cst)
			{
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
				ASN1_R_TYPE_NOT_CONSTRUCTED);
D
 
Dr. Stephen Henson 已提交
845
			return 0;
846
			}
D
 
Dr. Stephen Henson 已提交
847 848 849

		cont = *in;
		/* If indefinite length constructed find the real end */
850 851
		if (inf)
			{
852
			if (!asn1_find_end(&p, plen, inf))
853
				 goto err;
D
 
Dr. Stephen Henson 已提交
854
			len = p - cont;
855 856 857
			}
		else
			{
D
 
Dr. Stephen Henson 已提交
858 859 860
			len = p - cont + plen;
			p += plen;
			buf.data = NULL;
861
			}
D
 
Dr. Stephen Henson 已提交
862
		}
863 864
	else if (cst)
		{
D
 
Dr. Stephen Henson 已提交
865 866 867 868 869 870 871 872 873
		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.
		 */
874 875
		if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL))
			goto err;
D
 
Dr. Stephen Henson 已提交
876
		len = buf.length;
D
Dr. Stephen Henson 已提交
877
		/* Append a final null to string */
878 879 880 881
		if (!BUF_MEM_grow_clean(&buf, len + 1))
			{
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
						ERR_R_MALLOC_FAILURE);
D
Dr. Stephen Henson 已提交
882
			return 0;
883
			}
D
Dr. Stephen Henson 已提交
884
		buf.data[len] = 0;
885
		cont = (const unsigned char *)buf.data;
D
 
Dr. Stephen Henson 已提交
886
		free_cont = 1;
887 888 889
		}
	else
		{
D
 
Dr. Stephen Henson 已提交
890 891 892
		cont = p;
		len = plen;
		p += plen;
893
		}
D
 
Dr. Stephen Henson 已提交
894 895

	/* We now have content length and type: translate into a structure */
896 897
	if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
		goto err;
D
 
Dr. Stephen Henson 已提交
898 899 900 901

	*in = p;
	ret = 1;
	err:
902
	if (free_cont && buf.data) OPENSSL_free(buf.data);
D
 
Dr. Stephen Henson 已提交
903
	return ret;
904
	}
D
 
Dr. Stephen Henson 已提交
905 906 907

/* Translate ASN1 content octets into a structure */

908 909 910
int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
			int utype, char *free_cont, const ASN1_ITEM *it)
	{
911
	ASN1_VALUE **opval = NULL;
D
 
Dr. Stephen Henson 已提交
912 913 914 915
	ASN1_STRING *stmp;
	ASN1_TYPE *typ = NULL;
	int ret = 0;
	const ASN1_PRIMITIVE_FUNCS *pf;
916
	ASN1_INTEGER **tint;
D
 
Dr. Stephen Henson 已提交
917
	pf = it->funcs;
918 919 920

	if (pf && pf->prim_c2i)
		return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
D
 
Dr. Stephen Henson 已提交
921
	/* If ANY type clear type and set pointer to internal value */
922 923 924 925
	if (it->utype == V_ASN1_ANY)
		{
		if (!*pval)
			{
D
 
Dr. Stephen Henson 已提交
926
			typ = ASN1_TYPE_new();
N
Nils Larsch 已提交
927 928
			if (typ == NULL)
				goto err;
D
 
Dr. Stephen Henson 已提交
929
			*pval = (ASN1_VALUE *)typ;
930 931 932 933 934 935
			}
		else
			typ = (ASN1_TYPE *)*pval;

		if (utype != typ->type)
			ASN1_TYPE_set(typ, utype, NULL);
936
		opval = pval;
D
 
Dr. Stephen Henson 已提交
937
		pval = (ASN1_VALUE **)&typ->value.ptr;
938 939 940
		}
	switch(utype)
		{
D
 
Dr. Stephen Henson 已提交
941
		case V_ASN1_OBJECT:
942 943
		if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
			goto err;
D
 
Dr. Stephen Henson 已提交
944 945 946
		break;

		case V_ASN1_NULL:
947 948
		if (len)
			{
B
Bodo Möller 已提交
949
			ASN1err(ASN1_F_ASN1_EX_C2I,
950
						ASN1_R_NULL_IS_WRONG_LENGTH);
D
 
Dr. Stephen Henson 已提交
951
			goto err;
952
			}
D
 
Dr. Stephen Henson 已提交
953 954 955 956
		*pval = (ASN1_VALUE *)1;
		break;

		case V_ASN1_BOOLEAN:
957 958
		if (len != 1)
			{
B
Bodo Möller 已提交
959
			ASN1err(ASN1_F_ASN1_EX_C2I,
960
						ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
D
 
Dr. Stephen Henson 已提交
961
			goto err;
962 963 964
			}
		else
			{
D
 
Dr. Stephen Henson 已提交
965 966 967
			ASN1_BOOLEAN *tbool;
			tbool = (ASN1_BOOLEAN *)pval;
			*tbool = *cont;
968
			}
D
 
Dr. Stephen Henson 已提交
969 970 971
		break;

		case V_ASN1_BIT_STRING:
972 973
		if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
			goto err;
D
 
Dr. Stephen Henson 已提交
974 975 976 977 978 979
		break;

		case V_ASN1_INTEGER:
		case V_ASN1_NEG_INTEGER:
		case V_ASN1_ENUMERATED:
		case V_ASN1_NEG_ENUMERATED:
980
		tint = (ASN1_INTEGER **)pval;
981 982
		if (!c2i_ASN1_INTEGER(tint, &cont, len))
			goto err;
983 984
		/* Fixup type to match the expected form */
		(*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
D
 
Dr. Stephen Henson 已提交
985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
		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 */
1006 1007
		if (!*pval)
			{
D
 
Dr. Stephen Henson 已提交
1008
			stmp = ASN1_STRING_type_new(utype);
1009 1010
			if (!stmp)
				{
B
Bodo Möller 已提交
1011
				ASN1err(ASN1_F_ASN1_EX_C2I,
1012
							ERR_R_MALLOC_FAILURE);
D
 
Dr. Stephen Henson 已提交
1013
				goto err;
1014
				}
D
 
Dr. Stephen Henson 已提交
1015
			*pval = (ASN1_VALUE *)stmp;
1016 1017 1018
			}
		else
			{
D
 
Dr. Stephen Henson 已提交
1019 1020
			stmp = (ASN1_STRING *)*pval;
			stmp->type = utype;
1021
			}
D
 
Dr. Stephen Henson 已提交
1022
		/* If we've already allocated a buffer use it */
1023 1024 1025 1026
		if (*free_cont)
			{
			if (stmp->data)
				OPENSSL_free(stmp->data);
1027
			stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
D
 
Dr. Stephen Henson 已提交
1028 1029
			stmp->length = len;
			*free_cont = 0;
1030 1031 1032 1033 1034
			}
		else
			{
			if (!ASN1_STRING_set(stmp, cont, len))
				{
B
Bodo Möller 已提交
1035
				ASN1err(ASN1_F_ASN1_EX_C2I,
1036
							ERR_R_MALLOC_FAILURE);
D
 
Dr. Stephen Henson 已提交
1037 1038 1039
				ASN1_STRING_free(stmp);	
				*pval = NULL;
				goto err;
1040
				}
D
 
Dr. Stephen Henson 已提交
1041 1042
			}
		break;
1043
		}
D
 
Dr. Stephen Henson 已提交
1044
	/* If ASN1_ANY and NULL type fix up value */
1045 1046
	if (typ && (utype == V_ASN1_NULL))
		 typ->value.ptr = NULL;
D
 
Dr. Stephen Henson 已提交
1047 1048 1049

	ret = 1;
	err:
1050
	if (!ret)
1051 1052 1053 1054 1055
		{
		ASN1_TYPE_free(typ);
		if (opval)
			*opval = NULL;
		}
D
 
Dr. Stephen Henson 已提交
1056
	return ret;
1057
	}
D
 
Dr. Stephen Henson 已提交
1058

1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079

/* 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 已提交
1080
	 * are encountered increment the expected eoc count otherwise just
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
	 * 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 已提交
1115 1116 1117
/* 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
1118
 * if it is indefinite length.
D
 
Dr. Stephen Henson 已提交
1119 1120
 */

1121 1122 1123
static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
				char inf, int tag, int aclass)
	{
1124
	const unsigned char *p, *q;
D
 
Dr. Stephen Henson 已提交
1125 1126 1127 1128
	long plen;
	char cst, ininf;
	p = *in;
	inf &= 1;
1129 1130 1131 1132
	/* If no buffer and not indefinite length constructed just pass over
	 * the encoded data */
	if (!buf && !inf)
		{
D
 
Dr. Stephen Henson 已提交
1133 1134
		*in += len;
		return 1;
1135 1136 1137
		}
	while(len > 0)
		{
D
 
Dr. Stephen Henson 已提交
1138 1139
		q = p;
		/* Check for EOC */
1140 1141 1142 1143 1144 1145 1146 1147
		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 已提交
1148
				return 0;
1149
				}
D
 
Dr. Stephen Henson 已提交
1150 1151
			inf = 0;
			break;
1152 1153 1154 1155 1156
			}

		if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
					len, tag, aclass, 0, NULL))
			{
D
 
Dr. Stephen Henson 已提交
1157 1158
			ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
			return 0;
1159 1160
			}

D
 
Dr. Stephen Henson 已提交
1161
		/* If indefinite length constructed update max length */
1162 1163
		if (cst)
			{
1164
#ifdef OPENSSL_ALLOW_NESTED_ASN1_STRINGS
1165 1166
			if (!asn1_collect(buf, &p, plen, ininf, tag, aclass))
				return 0;
1167 1168 1169 1170
#else
			ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING);
			return 0;
#endif
1171
			}
1172
		else if (plen && !collect_data(buf, &p, plen))
1173
			return 0;
D
 
Dr. Stephen Henson 已提交
1174
		len -= p - q;
1175 1176 1177
		}
	if (inf)
		{
D
 
Dr. Stephen Henson 已提交
1178 1179
		ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
		return 0;
1180
		}
D
 
Dr. Stephen Henson 已提交
1181 1182
	*in = p;
	return 1;
1183
	}
D
 
Dr. Stephen Henson 已提交
1184

1185
static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
1186 1187 1188 1189 1190 1191 1192 1193 1194
	{
	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 已提交
1195
			}
1196
		memcpy(buf->data + len, *p, plen);
D
 
Dr. Stephen Henson 已提交
1197
		}
1198 1199 1200
	*p += plen;
	return 1;
	}
D
 
Dr. Stephen Henson 已提交
1201 1202 1203

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

1204
static int asn1_check_eoc(const unsigned char **in, long len)
1205
	{
1206
	const unsigned char *p;
1207
	if (len < 2) return 0;
D
 
Dr. Stephen Henson 已提交
1208
	p = *in;
1209 1210
	if (!p[0] && !p[1])
		{
D
 
Dr. Stephen Henson 已提交
1211 1212
		*in += 2;
		return 1;
1213
		}
D
 
Dr. Stephen Henson 已提交
1214
	return 0;
1215
	}
D
 
Dr. Stephen Henson 已提交
1216 1217 1218 1219 1220 1221 1222 1223

/* 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.
 */

1224 1225 1226 1227 1228 1229
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 已提交
1230 1231 1232
	int i;
	int ptag, pclass;
	long plen;
1233
	const unsigned char *p, *q;
D
 
Dr. Stephen Henson 已提交
1234 1235 1236
	p = *in;
	q = p;

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

1269 1270
	if (i & 0x80)
		{
D
 
Dr. Stephen Henson 已提交
1271 1272 1273
		ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
		asn1_tlc_clear(ctx);
		return 0;
1274 1275 1276 1277 1278 1279 1280
		}
	if (exptag >= 0)
		{
		if ((exptag != ptag) || (expclass != pclass))
			{
			/* If type is OPTIONAL, not an error:
			 * indicate missing type.
D
 
Dr. Stephen Henson 已提交
1281
			 */
1282
			if (opt) return -1;
D
 
Dr. Stephen Henson 已提交
1283 1284 1285
			asn1_tlc_clear(ctx);
			ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
			return 0;
1286 1287 1288
			}
		/* We have a tag and class match:
		 * assume we are going to do something with it */
D
 
Dr. Stephen Henson 已提交
1289
		asn1_tlc_clear(ctx);
1290
		}
D
 
Dr. Stephen Henson 已提交
1291

1292 1293
	if (i & 1)
		plen = len - (p - q);
D
 
Dr. Stephen Henson 已提交
1294

1295 1296
	if (inf)
		*inf = i & 1;
D
 
Dr. Stephen Henson 已提交
1297

1298 1299
	if (cst)
		*cst = i & V_ASN1_CONSTRUCTED;
D
 
Dr. Stephen Henson 已提交
1300

1301 1302 1303 1304 1305 1306 1307 1308
	if (olen)
		*olen = plen;

	if (oclass)
		*oclass = pclass;

	if (otag)
		*otag = ptag;
D
 
Dr. Stephen Henson 已提交
1309 1310 1311

	*in = p;
	return 1;
1312
	}