Home | History | Annotate | Download | only in asn1
      1 /* tasn_new.c */
      2 /* Written by Dr Stephen N Henson (steve (at) openssl.org) for the OpenSSL
      3  * project 2000.
      4  */
      5 /* ====================================================================
      6  * Copyright (c) 2000-2004 The OpenSSL Project.  All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  *
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in
     17  *    the documentation and/or other materials provided with the
     18  *    distribution.
     19  *
     20  * 3. All advertising materials mentioning features or use of this
     21  *    software must display the following acknowledgment:
     22  *    "This product includes software developed by the OpenSSL Project
     23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     24  *
     25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     26  *    endorse or promote products derived from this software without
     27  *    prior written permission. For written permission, please contact
     28  *    licensing (at) OpenSSL.org.
     29  *
     30  * 5. Products derived from this software may not be called "OpenSSL"
     31  *    nor may "OpenSSL" appear in their names without prior written
     32  *    permission of the OpenSSL Project.
     33  *
     34  * 6. Redistributions of any form whatsoever must retain the following
     35  *    acknowledgment:
     36  *    "This product includes software developed by the OpenSSL Project
     37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     38  *
     39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     50  * OF THE POSSIBILITY OF SUCH DAMAGE.
     51  * ====================================================================
     52  *
     53  * This product includes cryptographic software written by Eric Young
     54  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     55  * Hudson (tjh (at) cryptsoft.com).
     56  *
     57  */
     58 
     59 
     60 #include <stddef.h>
     61 #include <openssl/asn1.h>
     62 #include <openssl/objects.h>
     63 #include <openssl/err.h>
     64 #include <openssl/asn1t.h>
     65 #include <string.h>
     66 
     67 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
     68 								int combine);
     69 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
     70 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
     71 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
     72 
     73 ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
     74 	{
     75 	ASN1_VALUE *ret = NULL;
     76 	if (ASN1_item_ex_new(&ret, it) > 0)
     77 		return ret;
     78 	return NULL;
     79 	}
     80 
     81 /* Allocate an ASN1 structure */
     82 
     83 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
     84 	{
     85 	return asn1_item_ex_combine_new(pval, it, 0);
     86 	}
     87 
     88 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
     89 								int combine)
     90 	{
     91 	const ASN1_TEMPLATE *tt = NULL;
     92 	const ASN1_COMPAT_FUNCS *cf;
     93 	const ASN1_EXTERN_FUNCS *ef;
     94 	const ASN1_AUX *aux = it->funcs;
     95 	ASN1_aux_cb *asn1_cb;
     96 	ASN1_VALUE **pseqval;
     97 	int i;
     98 	if (aux && aux->asn1_cb)
     99 		asn1_cb = aux->asn1_cb;
    100 	else
    101 		asn1_cb = 0;
    102 
    103 	if (!combine) *pval = NULL;
    104 
    105 #ifdef CRYPTO_MDEBUG
    106 	if (it->sname)
    107 		CRYPTO_push_info(it->sname);
    108 #endif
    109 
    110 	switch(it->itype)
    111 		{
    112 
    113 		case ASN1_ITYPE_EXTERN:
    114 		ef = it->funcs;
    115 		if (ef && ef->asn1_ex_new)
    116 			{
    117 			if (!ef->asn1_ex_new(pval, it))
    118 				goto memerr;
    119 			}
    120 		break;
    121 
    122 		case ASN1_ITYPE_COMPAT:
    123 		cf = it->funcs;
    124 		if (cf && cf->asn1_new) {
    125 			*pval = cf->asn1_new();
    126 			if (!*pval)
    127 				goto memerr;
    128 		}
    129 		break;
    130 
    131 		case ASN1_ITYPE_PRIMITIVE:
    132 		if (it->templates)
    133 			{
    134 			if (!ASN1_template_new(pval, it->templates))
    135 				goto memerr;
    136 			}
    137 		else if (!ASN1_primitive_new(pval, it))
    138 				goto memerr;
    139 		break;
    140 
    141 		case ASN1_ITYPE_MSTRING:
    142 		if (!ASN1_primitive_new(pval, it))
    143 				goto memerr;
    144 		break;
    145 
    146 		case ASN1_ITYPE_CHOICE:
    147 		if (asn1_cb)
    148 			{
    149 			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
    150 			if (!i)
    151 				goto auxerr;
    152 			if (i==2)
    153 				{
    154 #ifdef CRYPTO_MDEBUG
    155 				if (it->sname)
    156 					CRYPTO_pop_info();
    157 #endif
    158 				return 1;
    159 				}
    160 			}
    161 		if (!combine)
    162 			{
    163 			*pval = OPENSSL_malloc(it->size);
    164 			if (!*pval)
    165 				goto memerr;
    166 			memset(*pval, 0, it->size);
    167 			}
    168 		asn1_set_choice_selector(pval, -1, it);
    169 		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
    170 				goto auxerr;
    171 		break;
    172 
    173 		case ASN1_ITYPE_NDEF_SEQUENCE:
    174 		case ASN1_ITYPE_SEQUENCE:
    175 		if (asn1_cb)
    176 			{
    177 			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
    178 			if (!i)
    179 				goto auxerr;
    180 			if (i==2)
    181 				{
    182 #ifdef CRYPTO_MDEBUG
    183 				if (it->sname)
    184 					CRYPTO_pop_info();
    185 #endif
    186 				return 1;
    187 				}
    188 			}
    189 		if (!combine)
    190 			{
    191 			*pval = OPENSSL_malloc(it->size);
    192 			if (!*pval)
    193 				goto memerr;
    194 			memset(*pval, 0, it->size);
    195 			asn1_do_lock(pval, 0, it);
    196 			asn1_enc_init(pval, it);
    197 			}
    198 		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
    199 			{
    200 			pseqval = asn1_get_field_ptr(pval, tt);
    201 			if (!ASN1_template_new(pseqval, tt))
    202 				goto memerr;
    203 			}
    204 		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
    205 				goto auxerr;
    206 		break;
    207 	}
    208 #ifdef CRYPTO_MDEBUG
    209 	if (it->sname) CRYPTO_pop_info();
    210 #endif
    211 	return 1;
    212 
    213 	memerr:
    214 	ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);
    215 #ifdef CRYPTO_MDEBUG
    216 	if (it->sname) CRYPTO_pop_info();
    217 #endif
    218 	return 0;
    219 
    220 	auxerr:
    221 	ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);
    222 	ASN1_item_ex_free(pval, it);
    223 #ifdef CRYPTO_MDEBUG
    224 	if (it->sname) CRYPTO_pop_info();
    225 #endif
    226 	return 0;
    227 
    228 	}
    229 
    230 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
    231 	{
    232 	const ASN1_EXTERN_FUNCS *ef;
    233 
    234 	switch(it->itype)
    235 		{
    236 
    237 		case ASN1_ITYPE_EXTERN:
    238 		ef = it->funcs;
    239 		if (ef && ef->asn1_ex_clear)
    240 			ef->asn1_ex_clear(pval, it);
    241 		else *pval = NULL;
    242 		break;
    243 
    244 
    245 		case ASN1_ITYPE_PRIMITIVE:
    246 		if (it->templates)
    247 			asn1_template_clear(pval, it->templates);
    248 		else
    249 			asn1_primitive_clear(pval, it);
    250 		break;
    251 
    252 		case ASN1_ITYPE_MSTRING:
    253 		asn1_primitive_clear(pval, it);
    254 		break;
    255 
    256 		case ASN1_ITYPE_COMPAT:
    257 		case ASN1_ITYPE_CHOICE:
    258 		case ASN1_ITYPE_SEQUENCE:
    259 		case ASN1_ITYPE_NDEF_SEQUENCE:
    260 		*pval = NULL;
    261 		break;
    262 		}
    263 	}
    264 
    265 
    266 int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
    267 	{
    268 	const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
    269 	int ret;
    270 	if (tt->flags & ASN1_TFLG_OPTIONAL)
    271 		{
    272 		asn1_template_clear(pval, tt);
    273 		return 1;
    274 		}
    275 	/* If ANY DEFINED BY nothing to do */
    276 
    277 	if (tt->flags & ASN1_TFLG_ADB_MASK)
    278 		{
    279 		*pval = NULL;
    280 		return 1;
    281 		}
    282 #ifdef CRYPTO_MDEBUG
    283 	if (tt->field_name)
    284 		CRYPTO_push_info(tt->field_name);
    285 #endif
    286 	/* If SET OF or SEQUENCE OF, its a STACK */
    287 	if (tt->flags & ASN1_TFLG_SK_MASK)
    288 		{
    289 		STACK_OF(ASN1_VALUE) *skval;
    290 		skval = sk_ASN1_VALUE_new_null();
    291 		if (!skval)
    292 			{
    293 			ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
    294 			ret = 0;
    295 			goto done;
    296 			}
    297 		*pval = (ASN1_VALUE *)skval;
    298 		ret = 1;
    299 		goto done;
    300 		}
    301 	/* Otherwise pass it back to the item routine */
    302 	ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
    303 	done:
    304 #ifdef CRYPTO_MDEBUG
    305 	if (it->sname)
    306 		CRYPTO_pop_info();
    307 #endif
    308 	return ret;
    309 	}
    310 
    311 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
    312 	{
    313 	/* If ADB or STACK just NULL the field */
    314 	if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK))
    315 		*pval = NULL;
    316 	else
    317 		asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
    318 	}
    319 
    320 
    321 /* NB: could probably combine most of the real XXX_new() behaviour and junk
    322  * all the old functions.
    323  */
    324 
    325 int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
    326 	{
    327 	ASN1_TYPE *typ;
    328 	ASN1_STRING *str;
    329 	int utype;
    330 
    331 	if (it && it->funcs)
    332 		{
    333 		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
    334 		if (pf->prim_new)
    335 			return pf->prim_new(pval, it);
    336 		}
    337 
    338 	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
    339 		utype = -1;
    340 	else
    341 		utype = it->utype;
    342 	switch(utype)
    343 		{
    344 		case V_ASN1_OBJECT:
    345 		*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
    346 		return 1;
    347 
    348 		case V_ASN1_BOOLEAN:
    349 		*(ASN1_BOOLEAN *)pval = it->size;
    350 		return 1;
    351 
    352 		case V_ASN1_NULL:
    353 		*pval = (ASN1_VALUE *)1;
    354 		return 1;
    355 
    356 		case V_ASN1_ANY:
    357 		typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
    358 		if (!typ)
    359 			return 0;
    360 		typ->value.ptr = NULL;
    361 		typ->type = -1;
    362 		*pval = (ASN1_VALUE *)typ;
    363 		break;
    364 
    365 		default:
    366 		str = ASN1_STRING_type_new(utype);
    367 		if (it->itype == ASN1_ITYPE_MSTRING && str)
    368 			str->flags |= ASN1_STRING_FLAG_MSTRING;
    369 		*pval = (ASN1_VALUE *)str;
    370 		break;
    371 		}
    372 	if (*pval)
    373 		return 1;
    374 	return 0;
    375 	}
    376 
    377 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
    378 	{
    379 	int utype;
    380 	if (it && it->funcs)
    381 		{
    382 		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
    383 		if (pf->prim_clear)
    384 			pf->prim_clear(pval, it);
    385 		else
    386 			*pval = NULL;
    387 		return;
    388 		}
    389 	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
    390 		utype = -1;
    391 	else
    392 		utype = it->utype;
    393 	if (utype == V_ASN1_BOOLEAN)
    394 		*(ASN1_BOOLEAN *)pval = it->size;
    395 	else *pval = NULL;
    396 	}
    397