Home | History | Annotate | Download | only in asn1
      1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      2  * All rights reserved.
      3  *
      4  * This package is an SSL implementation written
      5  * by Eric Young (eay (at) cryptsoft.com).
      6  * The implementation was written so as to conform with Netscapes SSL.
      7  *
      8  * This library is free for commercial and non-commercial use as long as
      9  * the following conditions are aheared to.  The following conditions
     10  * apply to all code found in this distribution, be it the RC4, RSA,
     11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     12  * included with this distribution is covered by the same copyright terms
     13  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     14  *
     15  * Copyright remains Eric Young's, and as such any Copyright notices in
     16  * the code are not to be removed.
     17  * If this package is used in a product, Eric Young should be given attribution
     18  * as the author of the parts of the library used.
     19  * This can be in the form of a textual message at program startup or
     20  * in documentation (online or textual) provided with the package.
     21  *
     22  * Redistribution and use in source and binary forms, with or without
     23  * modification, are permitted provided that the following conditions
     24  * are met:
     25  * 1. Redistributions of source code must retain the copyright
     26  *    notice, this list of conditions and the following disclaimer.
     27  * 2. Redistributions in binary form must reproduce the above copyright
     28  *    notice, this list of conditions and the following disclaimer in the
     29  *    documentation and/or other materials provided with the distribution.
     30  * 3. All advertising materials mentioning features or use of this software
     31  *    must display the following acknowledgement:
     32  *    "This product includes cryptographic software written by
     33  *     Eric Young (eay (at) cryptsoft.com)"
     34  *    The word 'cryptographic' can be left out if the rouines from the library
     35  *    being used are not cryptographic related :-).
     36  * 4. If you include any Windows specific code (or a derivative thereof) from
     37  *    the apps directory (application code) you must include an acknowledgement:
     38  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     39  *
     40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     50  * SUCH DAMAGE.
     51  *
     52  * The licence and distribution terms for any publically available version or
     53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     54  * copied and put under another distribution licence
     55  * [including the GNU Public Licence.] */
     56 
     57 #include <openssl/asn1.h>
     58 
     59 #include <string.h>
     60 
     61 #include <openssl/asn1t.h>
     62 #include <openssl/err.h>
     63 #include <openssl/mem.h>
     64 #include <openssl/obj.h>
     65 
     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 #ifdef CRYPTO_MDEBUG
    104 	if (it->sname)
    105 		CRYPTO_push_info(it->sname);
    106 #endif
    107 
    108 	switch(it->itype)
    109 		{
    110 
    111 		case ASN1_ITYPE_EXTERN:
    112 		ef = it->funcs;
    113 		if (ef && ef->asn1_ex_new)
    114 			{
    115 			if (!ef->asn1_ex_new(pval, it))
    116 				goto memerr;
    117 			}
    118 		break;
    119 
    120 		case ASN1_ITYPE_COMPAT:
    121 		cf = it->funcs;
    122 		if (cf && cf->asn1_new) {
    123 			*pval = cf->asn1_new();
    124 			if (!*pval)
    125 				goto memerr;
    126 		}
    127 		break;
    128 
    129 		case ASN1_ITYPE_PRIMITIVE:
    130 		if (it->templates)
    131 			{
    132 			if (!ASN1_template_new(pval, it->templates))
    133 				goto memerr;
    134 			}
    135 		else if (!ASN1_primitive_new(pval, it))
    136 				goto memerr;
    137 		break;
    138 
    139 		case ASN1_ITYPE_MSTRING:
    140 		if (!ASN1_primitive_new(pval, it))
    141 				goto memerr;
    142 		break;
    143 
    144 		case ASN1_ITYPE_CHOICE:
    145 		if (asn1_cb)
    146 			{
    147 			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
    148 			if (!i)
    149 				goto auxerr;
    150 			if (i==2)
    151 				{
    152 #ifdef CRYPTO_MDEBUG
    153 				if (it->sname)
    154 					CRYPTO_pop_info();
    155 #endif
    156 				return 1;
    157 				}
    158 			}
    159 		if (!combine)
    160 			{
    161 			*pval = OPENSSL_malloc(it->size);
    162 			if (!*pval)
    163 				goto memerr;
    164 			memset(*pval, 0, it->size);
    165 			}
    166 		asn1_set_choice_selector(pval, -1, it);
    167 		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
    168 				goto auxerr;
    169 		break;
    170 
    171 		case ASN1_ITYPE_NDEF_SEQUENCE:
    172 		case ASN1_ITYPE_SEQUENCE:
    173 		if (asn1_cb)
    174 			{
    175 			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
    176 			if (!i)
    177 				goto auxerr;
    178 			if (i==2)
    179 				{
    180 #ifdef CRYPTO_MDEBUG
    181 				if (it->sname)
    182 					CRYPTO_pop_info();
    183 #endif
    184 				return 1;
    185 				}
    186 			}
    187 		if (!combine)
    188 			{
    189 			*pval = OPENSSL_malloc(it->size);
    190 			if (!*pval)
    191 				goto memerr;
    192 			memset(*pval, 0, it->size);
    193 			asn1_refcount_set_one(pval, it);
    194 			asn1_enc_init(pval, it);
    195 			}
    196 		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
    197 			{
    198 			pseqval = asn1_get_field_ptr(pval, tt);
    199 			if (!ASN1_template_new(pseqval, tt))
    200 				goto memerr;
    201 			}
    202 		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
    203 				goto auxerr;
    204 		break;
    205 	}
    206 #ifdef CRYPTO_MDEBUG
    207 	if (it->sname) CRYPTO_pop_info();
    208 #endif
    209 	return 1;
    210 
    211 	memerr:
    212 	OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
    213 	ASN1_item_ex_free(pval, it);
    214 #ifdef CRYPTO_MDEBUG
    215 	if (it->sname) CRYPTO_pop_info();
    216 #endif
    217 	return 0;
    218 
    219 	auxerr:
    220 	OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
    221 	ASN1_item_ex_free(pval, it);
    222 #ifdef CRYPTO_MDEBUG
    223 	if (it->sname) CRYPTO_pop_info();
    224 #endif
    225 	return 0;
    226 
    227 	}
    228 
    229 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
    230 	{
    231 	const ASN1_EXTERN_FUNCS *ef;
    232 
    233 	switch(it->itype)
    234 		{
    235 
    236 		case ASN1_ITYPE_EXTERN:
    237 		ef = it->funcs;
    238 		if (ef && ef->asn1_ex_clear)
    239 			ef->asn1_ex_clear(pval, it);
    240 		else *pval = NULL;
    241 		break;
    242 
    243 
    244 		case ASN1_ITYPE_PRIMITIVE:
    245 		if (it->templates)
    246 			asn1_template_clear(pval, it->templates);
    247 		else
    248 			asn1_primitive_clear(pval, it);
    249 		break;
    250 
    251 		case ASN1_ITYPE_MSTRING:
    252 		asn1_primitive_clear(pval, it);
    253 		break;
    254 
    255 		case ASN1_ITYPE_COMPAT:
    256 		case ASN1_ITYPE_CHOICE:
    257 		case ASN1_ITYPE_SEQUENCE:
    258 		case ASN1_ITYPE_NDEF_SEQUENCE:
    259 		*pval = NULL;
    260 		break;
    261 		}
    262 	}
    263 
    264 
    265 int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
    266 	{
    267 	const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
    268 	int ret;
    269 	if (tt->flags & ASN1_TFLG_OPTIONAL)
    270 		{
    271 		asn1_template_clear(pval, tt);
    272 		return 1;
    273 		}
    274 	/* If ANY DEFINED BY nothing to do */
    275 
    276 	if (tt->flags & ASN1_TFLG_ADB_MASK)
    277 		{
    278 		*pval = NULL;
    279 		return 1;
    280 		}
    281 #ifdef CRYPTO_MDEBUG
    282 	if (tt->field_name)
    283 		CRYPTO_push_info(tt->field_name);
    284 #endif
    285 	/* If SET OF or SEQUENCE OF, its a STACK */
    286 	if (tt->flags & ASN1_TFLG_SK_MASK)
    287 		{
    288 		STACK_OF(ASN1_VALUE) *skval;
    289 		skval = sk_ASN1_VALUE_new_null();
    290 		if (!skval)
    291 			{
    292 			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
    293 			ret = 0;
    294 			goto done;
    295 			}
    296 		*pval = (ASN1_VALUE *)skval;
    297 		ret = 1;
    298 		goto done;
    299 		}
    300 	/* Otherwise pass it back to the item routine */
    301 	ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
    302 	done:
    303 #ifdef CRYPTO_MDEBUG
    304 	if (it->sname)
    305 		CRYPTO_pop_info();
    306 #endif
    307 	return ret;
    308 	}
    309 
    310 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
    311 	{
    312 	/* If ADB or STACK just NULL the field */
    313 	if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK))
    314 		*pval = NULL;
    315 	else
    316 		asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
    317 	}
    318 
    319 
    320 /* NB: could probably combine most of the real XXX_new() behaviour and junk
    321  * all the old functions.
    322  */
    323 
    324 int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
    325 	{
    326 	ASN1_TYPE *typ;
    327 	ASN1_STRING *str;
    328 	int utype;
    329 
    330 	if (!it)
    331 		return 0;
    332 
    333 	if (it->funcs)
    334 		{
    335 		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
    336 		if (pf->prim_new)
    337 			return pf->prim_new(pval, it);
    338 		}
    339 
    340 	if (it->itype == ASN1_ITYPE_MSTRING)
    341 		utype = -1;
    342 	else
    343 		utype = it->utype;
    344 	switch(utype)
    345 		{
    346 		case V_ASN1_OBJECT:
    347 		*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
    348 		return 1;
    349 
    350 		case V_ASN1_BOOLEAN:
    351 		*(ASN1_BOOLEAN *)pval = it->size;
    352 		return 1;
    353 
    354 		case V_ASN1_NULL:
    355 		*pval = (ASN1_VALUE *)1;
    356 		return 1;
    357 
    358 		case V_ASN1_ANY:
    359 		typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
    360 		if (!typ)
    361 			return 0;
    362 		typ->value.ptr = NULL;
    363 		typ->type = -1;
    364 		*pval = (ASN1_VALUE *)typ;
    365 		break;
    366 
    367 		default:
    368 		str = ASN1_STRING_type_new(utype);
    369 		if (it->itype == ASN1_ITYPE_MSTRING && str)
    370 			str->flags |= ASN1_STRING_FLAG_MSTRING;
    371 		*pval = (ASN1_VALUE *)str;
    372 		break;
    373 		}
    374 	if (*pval)
    375 		return 1;
    376 	return 0;
    377 	}
    378 
    379 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
    380 	{
    381 	int utype;
    382 	if (it && it->funcs)
    383 		{
    384 		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
    385 		if (pf->prim_clear)
    386 			pf->prim_clear(pval, it);
    387 		else
    388 			*pval = NULL;
    389 		return;
    390 		}
    391 	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
    392 		utype = -1;
    393 	else
    394 		utype = it->utype;
    395 	if (utype == V_ASN1_BOOLEAN)
    396 		*(ASN1_BOOLEAN *)pval = it->size;
    397 	else *pval = NULL;
    398 	}
    399