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