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