tasn_dec.c 30.2 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-2004 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))
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))
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))
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))
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 582 583
			if (!asn1_check_eoc(&p, len))
				{
				ASN1err(ASN1_F_ASN1_TEMPLATE_D2I,
						ASN1_R_MISSING_EOC);
D
 
Dr. Stephen Henson 已提交
584
				goto err;
585
				}
D
 
Dr. Stephen Henson 已提交
586
			}
587 588 589 590 591 592 593 594
		else
			{
			/* Otherwise we must hit the EXPLICIT tag end or its
			 * an error */
			if (len)
				{
				ASN1err(ASN1_F_ASN1_TEMPLATE_D2I,
					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 652 653
		ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
					&p, len, sktag, skaclass, opt, ctx);
		if (!ret)
			{
			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
						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 675 676
		if (!*val)
			{
			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
						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 690 691
			if (asn1_check_eoc(&p, len))
				{
				if (!sk_eoc)
					{
					ASN1err(ASN1_F_ASN1_TEMPLATE_D2I,
							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 703 704
			if (!ASN1_item_ex_d2i(&skfield, &p, len,
						ASN1_ITEM_ptr(tt->item),
						-1, 0, 0, ctx))
				{
				ASN1err(ASN1_F_ASN1_TEMPLATE_D2I,
					ERR_R_NESTED_ASN1_ERROR);
D
 
Dr. Stephen Henson 已提交
705
				goto err;
706
				}
D
 
Dr. Stephen Henson 已提交
707
			len -= p - q;
708 709 710 711
			if (!sk_push((STACK *)*val, (char *)skfield))
				{
				ASN1err(ASN1_F_ASN1_TEMPLATE_D2I,
						ERR_R_MALLOC_FAILURE);
D
 
Dr. Stephen Henson 已提交
712
				goto err;
713
				}
D
 
Dr. Stephen Henson 已提交
714
			}
715 716
		if (sk_eoc)
			{
D
 
Dr. Stephen Henson 已提交
717 718
			ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC);
			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 728 729
		ret = ASN1_item_ex_d2i(val, &p, len,
			ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
		if (!ret)
			{
			ASN1err(ASN1_F_ASN1_TEMPLATE_D2I,
						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 742 743
		ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
							-1, 0, opt, ctx);
		if (!ret)
			{
			ASN1err(ASN1_F_ASN1_TEMPLATE_D2I,
					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 927
			typ = ASN1_TYPE_new();
			*pval = (ASN1_VALUE *)typ;
928 929 930 931 932 933
			}
		else
			typ = (ASN1_TYPE *)*pval;

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

		case V_ASN1_NULL:
945 946 947 948
		if (len)
			{
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
						ASN1_R_NULL_IS_WRONG_LENGTH);
D
 
Dr. Stephen Henson 已提交
949
			goto err;
950
			}
D
 
Dr. Stephen Henson 已提交
951 952 953 954
		*pval = (ASN1_VALUE *)1;
		break;

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

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

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

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

1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 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

/* 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
	 * are encountered increment the expected eoc count otherwise just
	 * 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 已提交
1113 1114 1115
/* 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
1116
 * if it is indefinite length.
D
 
Dr. Stephen Henson 已提交
1117 1118
 */

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

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

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

1178
static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
1179 1180 1181 1182 1183 1184 1185 1186 1187
	{
	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 已提交
1188
			}
1189
		memcpy(buf->data + len, *p, plen);
D
 
Dr. Stephen Henson 已提交
1190
		}
1191 1192 1193
	*p += plen;
	return 1;
	}
D
 
Dr. Stephen Henson 已提交
1194 1195 1196

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

1197
static int asn1_check_eoc(const unsigned char **in, long len)
1198
	{
1199
	const unsigned char *p;
1200
	if (len < 2) return 0;
D
 
Dr. Stephen Henson 已提交
1201
	p = *in;
1202 1203
	if (!p[0] && !p[1])
		{
D
 
Dr. Stephen Henson 已提交
1204 1205
		*in += 2;
		return 1;
1206
		}
D
 
Dr. Stephen Henson 已提交
1207
	return 0;
1208
	}
D
 
Dr. Stephen Henson 已提交
1209 1210 1211 1212 1213 1214 1215 1216

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

1217 1218 1219 1220 1221 1222
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 已提交
1223 1224 1225
	int i;
	int ptag, pclass;
	long plen;
1226
	const unsigned char *p, *q;
D
 
Dr. Stephen Henson 已提交
1227 1228 1229
	p = *in;
	q = p;

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

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

1285 1286
	if (i & 1)
		plen = len - (p - q);
D
 
Dr. Stephen Henson 已提交
1287

1288 1289
	if (inf)
		*inf = i & 1;
D
 
Dr. Stephen Henson 已提交
1290

1291 1292
	if (cst)
		*cst = i & V_ASN1_CONSTRUCTED;
D
 
Dr. Stephen Henson 已提交
1293

1294 1295 1296 1297 1298 1299 1300 1301
	if (olen)
		*olen = plen;

	if (oclass)
		*oclass = pclass;

	if (otag)
		*otag = ptag;
D
 
Dr. Stephen Henson 已提交
1302 1303 1304

	*in = p;
	return 1;
1305
	}