xref: /onnv-gate/usr/src/common/openssl/crypto/asn1/tasn_fre.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* tasn_fre.c */
20Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
30Sstevel@tonic-gate  * project 2000.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate /* ====================================================================
60Sstevel@tonic-gate  * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
90Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
100Sstevel@tonic-gate  * are met:
110Sstevel@tonic-gate  *
120Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
130Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
140Sstevel@tonic-gate  *
150Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
160Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
170Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
180Sstevel@tonic-gate  *    distribution.
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this
210Sstevel@tonic-gate  *    software must display the following acknowledgment:
220Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
230Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
240Sstevel@tonic-gate  *
250Sstevel@tonic-gate  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
260Sstevel@tonic-gate  *    endorse or promote products derived from this software without
270Sstevel@tonic-gate  *    prior written permission. For written permission, please contact
280Sstevel@tonic-gate  *    licensing@OpenSSL.org.
290Sstevel@tonic-gate  *
300Sstevel@tonic-gate  * 5. Products derived from this software may not be called "OpenSSL"
310Sstevel@tonic-gate  *    nor may "OpenSSL" appear in their names without prior written
320Sstevel@tonic-gate  *    permission of the OpenSSL Project.
330Sstevel@tonic-gate  *
340Sstevel@tonic-gate  * 6. Redistributions of any form whatsoever must retain the following
350Sstevel@tonic-gate  *    acknowledgment:
360Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
370Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
380Sstevel@tonic-gate  *
390Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
400Sstevel@tonic-gate  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
410Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
420Sstevel@tonic-gate  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
430Sstevel@tonic-gate  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
440Sstevel@tonic-gate  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
450Sstevel@tonic-gate  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
460Sstevel@tonic-gate  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
470Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
480Sstevel@tonic-gate  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
490Sstevel@tonic-gate  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
500Sstevel@tonic-gate  * OF THE POSSIBILITY OF SUCH DAMAGE.
510Sstevel@tonic-gate  * ====================================================================
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * This product includes cryptographic software written by Eric Young
540Sstevel@tonic-gate  * (eay@cryptsoft.com).  This product includes software written by Tim
550Sstevel@tonic-gate  * Hudson (tjh@cryptsoft.com).
560Sstevel@tonic-gate  *
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate 
590Sstevel@tonic-gate 
600Sstevel@tonic-gate #include <stddef.h>
610Sstevel@tonic-gate #include <openssl/asn1.h>
620Sstevel@tonic-gate #include <openssl/asn1t.h>
630Sstevel@tonic-gate #include <openssl/objects.h>
640Sstevel@tonic-gate 
650Sstevel@tonic-gate static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine);
660Sstevel@tonic-gate 
670Sstevel@tonic-gate /* Free up an ASN1 structure */
680Sstevel@tonic-gate 
ASN1_item_free(ASN1_VALUE * val,const ASN1_ITEM * it)690Sstevel@tonic-gate void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
70*2139Sjp161948 	{
710Sstevel@tonic-gate 	asn1_item_combine_free(&val, it, 0);
72*2139Sjp161948 	}
730Sstevel@tonic-gate 
ASN1_item_ex_free(ASN1_VALUE ** pval,const ASN1_ITEM * it)740Sstevel@tonic-gate void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
75*2139Sjp161948 	{
760Sstevel@tonic-gate 	asn1_item_combine_free(pval, it, 0);
77*2139Sjp161948 	}
780Sstevel@tonic-gate 
asn1_item_combine_free(ASN1_VALUE ** pval,const ASN1_ITEM * it,int combine)790Sstevel@tonic-gate static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
80*2139Sjp161948 	{
810Sstevel@tonic-gate 	const ASN1_TEMPLATE *tt = NULL, *seqtt;
820Sstevel@tonic-gate 	const ASN1_EXTERN_FUNCS *ef;
830Sstevel@tonic-gate 	const ASN1_COMPAT_FUNCS *cf;
840Sstevel@tonic-gate 	const ASN1_AUX *aux = it->funcs;
850Sstevel@tonic-gate 	ASN1_aux_cb *asn1_cb;
860Sstevel@tonic-gate 	int i;
87*2139Sjp161948 	if (!pval)
88*2139Sjp161948 		return;
89*2139Sjp161948 	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
90*2139Sjp161948 		return;
91*2139Sjp161948 	if (aux && aux->asn1_cb)
92*2139Sjp161948 		asn1_cb = aux->asn1_cb;
93*2139Sjp161948 	else
94*2139Sjp161948 		asn1_cb = 0;
950Sstevel@tonic-gate 
96*2139Sjp161948 	switch(it->itype)
97*2139Sjp161948 		{
980Sstevel@tonic-gate 
990Sstevel@tonic-gate 		case ASN1_ITYPE_PRIMITIVE:
100*2139Sjp161948 		if (it->templates)
101*2139Sjp161948 			ASN1_template_free(pval, it->templates);
102*2139Sjp161948 		else
103*2139Sjp161948 			ASN1_primitive_free(pval, it);
1040Sstevel@tonic-gate 		break;
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 		case ASN1_ITYPE_MSTRING:
1070Sstevel@tonic-gate 		ASN1_primitive_free(pval, it);
1080Sstevel@tonic-gate 		break;
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate 		case ASN1_ITYPE_CHOICE:
111*2139Sjp161948 		if (asn1_cb)
112*2139Sjp161948 			{
1130Sstevel@tonic-gate 			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it);
114*2139Sjp161948 			if (i == 2)
115*2139Sjp161948 				return;
116*2139Sjp161948 			}
1170Sstevel@tonic-gate 		i = asn1_get_choice_selector(pval, it);
118*2139Sjp161948 		if (asn1_cb)
119*2139Sjp161948 			asn1_cb(ASN1_OP_FREE_PRE, pval, it);
120*2139Sjp161948 		if ((i >= 0) && (i < it->tcount))
121*2139Sjp161948 			{
1220Sstevel@tonic-gate 			ASN1_VALUE **pchval;
1230Sstevel@tonic-gate 			tt = it->templates + i;
1240Sstevel@tonic-gate 			pchval = asn1_get_field_ptr(pval, tt);
1250Sstevel@tonic-gate 			ASN1_template_free(pchval, tt);
126*2139Sjp161948 			}
127*2139Sjp161948 		if (asn1_cb)
128*2139Sjp161948 			asn1_cb(ASN1_OP_FREE_POST, pval, it);
129*2139Sjp161948 		if (!combine)
130*2139Sjp161948 			{
1310Sstevel@tonic-gate 			OPENSSL_free(*pval);
1320Sstevel@tonic-gate 			*pval = NULL;
133*2139Sjp161948 			}
1340Sstevel@tonic-gate 		break;
1350Sstevel@tonic-gate 
1360Sstevel@tonic-gate 		case ASN1_ITYPE_COMPAT:
1370Sstevel@tonic-gate 		cf = it->funcs;
138*2139Sjp161948 		if (cf && cf->asn1_free)
139*2139Sjp161948 			cf->asn1_free(*pval);
1400Sstevel@tonic-gate 		break;
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 		case ASN1_ITYPE_EXTERN:
1430Sstevel@tonic-gate 		ef = it->funcs;
144*2139Sjp161948 		if (ef && ef->asn1_ex_free)
145*2139Sjp161948 			ef->asn1_ex_free(pval, it);
1460Sstevel@tonic-gate 		break;
1470Sstevel@tonic-gate 
148*2139Sjp161948 		case ASN1_ITYPE_NDEF_SEQUENCE:
1490Sstevel@tonic-gate 		case ASN1_ITYPE_SEQUENCE:
150*2139Sjp161948 		if (asn1_do_lock(pval, -1, it) > 0)
151*2139Sjp161948 			return;
152*2139Sjp161948 		if (asn1_cb)
153*2139Sjp161948 			{
1540Sstevel@tonic-gate 			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it);
155*2139Sjp161948 			if (i == 2)
156*2139Sjp161948 				return;
157*2139Sjp161948 			}
1580Sstevel@tonic-gate 		asn1_enc_free(pval, it);
1590Sstevel@tonic-gate 		/* If we free up as normal we will invalidate any
1600Sstevel@tonic-gate 		 * ANY DEFINED BY field and we wont be able to
1610Sstevel@tonic-gate 		 * determine the type of the field it defines. So
1620Sstevel@tonic-gate 		 * free up in reverse order.
1630Sstevel@tonic-gate 		 */
1640Sstevel@tonic-gate 		tt = it->templates + it->tcount - 1;
165*2139Sjp161948 		for (i = 0; i < it->tcount; tt--, i++)
166*2139Sjp161948 			{
1670Sstevel@tonic-gate 			ASN1_VALUE **pseqval;
1680Sstevel@tonic-gate 			seqtt = asn1_do_adb(pval, tt, 0);
169*2139Sjp161948 			if (!seqtt)
170*2139Sjp161948 				continue;
1710Sstevel@tonic-gate 			pseqval = asn1_get_field_ptr(pval, seqtt);
1720Sstevel@tonic-gate 			ASN1_template_free(pseqval, seqtt);
173*2139Sjp161948 			}
174*2139Sjp161948 		if (asn1_cb)
175*2139Sjp161948 			asn1_cb(ASN1_OP_FREE_POST, pval, it);
176*2139Sjp161948 		if (!combine)
177*2139Sjp161948 			{
1780Sstevel@tonic-gate 			OPENSSL_free(*pval);
1790Sstevel@tonic-gate 			*pval = NULL;
180*2139Sjp161948 			}
1810Sstevel@tonic-gate 		break;
182*2139Sjp161948 		}
1830Sstevel@tonic-gate 	}
1840Sstevel@tonic-gate 
ASN1_template_free(ASN1_VALUE ** pval,const ASN1_TEMPLATE * tt)1850Sstevel@tonic-gate void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
186*2139Sjp161948 	{
1870Sstevel@tonic-gate 	int i;
188*2139Sjp161948 	if (tt->flags & ASN1_TFLG_SK_MASK)
189*2139Sjp161948 		{
1900Sstevel@tonic-gate 		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
191*2139Sjp161948 		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
192*2139Sjp161948 			{
1930Sstevel@tonic-gate 			ASN1_VALUE *vtmp;
1940Sstevel@tonic-gate 			vtmp = sk_ASN1_VALUE_value(sk, i);
195*2139Sjp161948 			asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
196*2139Sjp161948 									0);
197*2139Sjp161948 			}
1980Sstevel@tonic-gate 		sk_ASN1_VALUE_free(sk);
1990Sstevel@tonic-gate 		*pval = NULL;
200*2139Sjp161948 		}
201*2139Sjp161948 	else
202*2139Sjp161948 		asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
2030Sstevel@tonic-gate 						tt->flags & ASN1_TFLG_COMBINE);
204*2139Sjp161948 	}
2050Sstevel@tonic-gate 
ASN1_primitive_free(ASN1_VALUE ** pval,const ASN1_ITEM * it)2060Sstevel@tonic-gate void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
207*2139Sjp161948 	{
2080Sstevel@tonic-gate 	int utype;
209*2139Sjp161948 	if (it)
210*2139Sjp161948 		{
2110Sstevel@tonic-gate 		const ASN1_PRIMITIVE_FUNCS *pf;
2120Sstevel@tonic-gate 		pf = it->funcs;
213*2139Sjp161948 		if (pf && pf->prim_free)
214*2139Sjp161948 			{
2150Sstevel@tonic-gate 			pf->prim_free(pval, it);
2160Sstevel@tonic-gate 			return;
217*2139Sjp161948 			}
2180Sstevel@tonic-gate 		}
2190Sstevel@tonic-gate 	/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
220*2139Sjp161948 	if (!it)
221*2139Sjp161948 		{
2220Sstevel@tonic-gate 		ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
2230Sstevel@tonic-gate 		utype = typ->type;
2240Sstevel@tonic-gate 		pval = (ASN1_VALUE **)&typ->value.ptr;
225*2139Sjp161948 		if (!*pval)
226*2139Sjp161948 			return;
227*2139Sjp161948 		}
228*2139Sjp161948 	else if (it->itype == ASN1_ITYPE_MSTRING)
229*2139Sjp161948 		{
2300Sstevel@tonic-gate 		utype = -1;
231*2139Sjp161948 		if (!*pval)
232*2139Sjp161948 			return;
233*2139Sjp161948 		}
234*2139Sjp161948 	else
235*2139Sjp161948 		{
2360Sstevel@tonic-gate 		utype = it->utype;
237*2139Sjp161948 		if ((utype != V_ASN1_BOOLEAN) && !*pval)
238*2139Sjp161948 			return;
239*2139Sjp161948 		}
2400Sstevel@tonic-gate 
241*2139Sjp161948 	switch(utype)
242*2139Sjp161948 		{
2430Sstevel@tonic-gate 		case V_ASN1_OBJECT:
2440Sstevel@tonic-gate 		ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
2450Sstevel@tonic-gate 		break;
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate 		case V_ASN1_BOOLEAN:
2480Sstevel@tonic-gate 		if (it)
2490Sstevel@tonic-gate 			*(ASN1_BOOLEAN *)pval = it->size;
2500Sstevel@tonic-gate 		else
2510Sstevel@tonic-gate 			*(ASN1_BOOLEAN *)pval = -1;
2520Sstevel@tonic-gate 		return;
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 		case V_ASN1_NULL:
2550Sstevel@tonic-gate 		break;
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 		case V_ASN1_ANY:
2580Sstevel@tonic-gate 		ASN1_primitive_free(pval, NULL);
2590Sstevel@tonic-gate 		OPENSSL_free(*pval);
2600Sstevel@tonic-gate 		break;
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate 		default:
2630Sstevel@tonic-gate 		ASN1_STRING_free((ASN1_STRING *)*pval);
2640Sstevel@tonic-gate 		*pval = NULL;
2650Sstevel@tonic-gate 		break;
266*2139Sjp161948 		}
2670Sstevel@tonic-gate 	*pval = NULL;
268*2139Sjp161948 	}
269