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 <openssl/asn1t.h>
     60 #include <openssl/mem.h>
     61 
     62 
     63 static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine);
     64 
     65 /* Free up an ASN1 structure */
     66 
     67 void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
     68 	{
     69 	asn1_item_combine_free(&val, it, 0);
     70 	}
     71 
     72 void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
     73 	{
     74 	asn1_item_combine_free(pval, it, 0);
     75 	}
     76 
     77 static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
     78 	{
     79 	const ASN1_TEMPLATE *tt = NULL, *seqtt;
     80 	const ASN1_EXTERN_FUNCS *ef;
     81 	const ASN1_COMPAT_FUNCS *cf;
     82 	const ASN1_AUX *aux = it->funcs;
     83 	ASN1_aux_cb *asn1_cb;
     84 	int i;
     85 	if (!pval)
     86 		return;
     87 	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
     88 		return;
     89 	if (aux && aux->asn1_cb)
     90 		asn1_cb = aux->asn1_cb;
     91 	else
     92 		asn1_cb = 0;
     93 
     94 	switch(it->itype)
     95 		{
     96 
     97 		case ASN1_ITYPE_PRIMITIVE:
     98 		if (it->templates)
     99 			ASN1_template_free(pval, it->templates);
    100 		else
    101 			ASN1_primitive_free(pval, it);
    102 		break;
    103 
    104 		case ASN1_ITYPE_MSTRING:
    105 		ASN1_primitive_free(pval, it);
    106 		break;
    107 
    108 		case ASN1_ITYPE_CHOICE:
    109 		if (asn1_cb)
    110 			{
    111 			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
    112 			if (i == 2)
    113 				return;
    114 			}
    115 		i = asn1_get_choice_selector(pval, it);
    116 		if ((i >= 0) && (i < it->tcount))
    117 			{
    118 			ASN1_VALUE **pchval;
    119 			tt = it->templates + i;
    120 			pchval = asn1_get_field_ptr(pval, tt);
    121 			ASN1_template_free(pchval, tt);
    122 			}
    123 		if (asn1_cb)
    124 			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
    125 		if (!combine)
    126 			{
    127 			OPENSSL_free(*pval);
    128 			*pval = NULL;
    129 			}
    130 		break;
    131 
    132 		case ASN1_ITYPE_COMPAT:
    133 		cf = it->funcs;
    134 		if (cf && cf->asn1_free)
    135 			cf->asn1_free(*pval);
    136 		break;
    137 
    138 		case ASN1_ITYPE_EXTERN:
    139 		ef = it->funcs;
    140 		if (ef && ef->asn1_ex_free)
    141 			ef->asn1_ex_free(pval, it);
    142 		break;
    143 
    144 		case ASN1_ITYPE_NDEF_SEQUENCE:
    145 		case ASN1_ITYPE_SEQUENCE:
    146 		if (!asn1_refcount_dec_and_test_zero(pval, it))
    147 			return;
    148 		if (asn1_cb)
    149 			{
    150 			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
    151 			if (i == 2)
    152 				return;
    153 			}
    154 		asn1_enc_free(pval, it);
    155 		/* If we free up as normal we will invalidate any
    156 		 * ANY DEFINED BY field and we wont be able to
    157 		 * determine the type of the field it defines. So
    158 		 * free up in reverse order.
    159 		 */
    160 		tt = it->templates + it->tcount - 1;
    161 		for (i = 0; i < it->tcount; tt--, i++)
    162 			{
    163 			ASN1_VALUE **pseqval;
    164 			seqtt = asn1_do_adb(pval, tt, 0);
    165 			if (!seqtt)
    166 				continue;
    167 			pseqval = asn1_get_field_ptr(pval, seqtt);
    168 			ASN1_template_free(pseqval, seqtt);
    169 			}
    170 		if (asn1_cb)
    171 			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
    172 		if (!combine)
    173 			{
    174 			OPENSSL_free(*pval);
    175 			*pval = NULL;
    176 			}
    177 		break;
    178 		}
    179 	}
    180 
    181 void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
    182 	{
    183 	size_t i;
    184 	if (tt->flags & ASN1_TFLG_SK_MASK)
    185 		{
    186 		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
    187 		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
    188 			{
    189 			ASN1_VALUE *vtmp;
    190 			vtmp = sk_ASN1_VALUE_value(sk, i);
    191 			asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
    192 									0);
    193 			}
    194 		sk_ASN1_VALUE_free(sk);
    195 		*pval = NULL;
    196 		}
    197 	else
    198 		asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
    199 						tt->flags & ASN1_TFLG_COMBINE);
    200 	}
    201 
    202 void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
    203 	{
    204 	int utype;
    205 	if (it)
    206 		{
    207 		const ASN1_PRIMITIVE_FUNCS *pf;
    208 		pf = it->funcs;
    209 		if (pf && pf->prim_free)
    210 			{
    211 			pf->prim_free(pval, it);
    212 			return;
    213 			}
    214 		}
    215 	/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
    216 	if (!it)
    217 		{
    218 		ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
    219 		utype = typ->type;
    220 		pval = &typ->value.asn1_value;
    221 		if (!*pval)
    222 			return;
    223 		}
    224 	else if (it->itype == ASN1_ITYPE_MSTRING)
    225 		{
    226 		utype = -1;
    227 		if (!*pval)
    228 			return;
    229 		}
    230 	else
    231 		{
    232 		utype = it->utype;
    233 		if ((utype != V_ASN1_BOOLEAN) && !*pval)
    234 			return;
    235 		}
    236 
    237 	switch(utype)
    238 		{
    239 		case V_ASN1_OBJECT:
    240 		ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
    241 		break;
    242 
    243 		case V_ASN1_BOOLEAN:
    244 		if (it)
    245 			*(ASN1_BOOLEAN *)pval = it->size;
    246 		else
    247 			*(ASN1_BOOLEAN *)pval = -1;
    248 		return;
    249 
    250 		case V_ASN1_NULL:
    251 		break;
    252 
    253 		case V_ASN1_ANY:
    254 		ASN1_primitive_free(pval, NULL);
    255 		OPENSSL_free(*pval);
    256 		break;
    257 
    258 		default:
    259 		ASN1_STRING_free((ASN1_STRING *)*pval);
    260 		*pval = NULL;
    261 		break;
    262 		}
    263 	*pval = NULL;
    264 	}
    265