Line data Source code
1 : /* tasn_fre.c */
2 : /*
3 : * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4 : * 2000.
5 : */
6 : /* ====================================================================
7 : * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
8 : *
9 : * Redistribution and use in source and binary forms, with or without
10 : * modification, are permitted provided that the following conditions
11 : * are met:
12 : *
13 : * 1. Redistributions of source code must retain the above copyright
14 : * notice, this list of conditions and the following disclaimer.
15 : *
16 : * 2. Redistributions in binary form must reproduce the above copyright
17 : * notice, this list of conditions and the following disclaimer in
18 : * the documentation and/or other materials provided with the
19 : * distribution.
20 : *
21 : * 3. All advertising materials mentioning features or use of this
22 : * software must display the following acknowledgment:
23 : * "This product includes software developed by the OpenSSL Project
24 : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 : *
26 : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 : * endorse or promote products derived from this software without
28 : * prior written permission. For written permission, please contact
29 : * licensing@OpenSSL.org.
30 : *
31 : * 5. Products derived from this software may not be called "OpenSSL"
32 : * nor may "OpenSSL" appear in their names without prior written
33 : * permission of the OpenSSL Project.
34 : *
35 : * 6. Redistributions of any form whatsoever must retain the following
36 : * acknowledgment:
37 : * "This product includes software developed by the OpenSSL Project
38 : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 : *
40 : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 : * OF THE POSSIBILITY OF SUCH DAMAGE.
52 : * ====================================================================
53 : *
54 : * This product includes cryptographic software written by Eric Young
55 : * (eay@cryptsoft.com). This product includes software written by Tim
56 : * Hudson (tjh@cryptsoft.com).
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,
66 : int combine);
67 :
68 : /* Free up an ASN1 structure */
69 :
70 54044 : void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
71 : {
72 54044 : asn1_item_combine_free(&val, it, 0);
73 54043 : }
74 :
75 0 : void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
76 : {
77 0 : asn1_item_combine_free(pval, it, 0);
78 0 : }
79 :
80 186978 : static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
81 : int combine)
82 : {
83 : const ASN1_TEMPLATE *tt = NULL, *seqtt;
84 : const ASN1_EXTERN_FUNCS *ef;
85 : const ASN1_COMPAT_FUNCS *cf;
86 186978 : const ASN1_AUX *aux = it->funcs;
87 : ASN1_aux_cb *asn1_cb;
88 : int i;
89 186978 : if (!pval)
90 : return;
91 186979 : if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
92 : return;
93 181595 : if (aux && aux->asn1_cb)
94 6841 : asn1_cb = aux->asn1_cb;
95 : else
96 : asn1_cb = 0;
97 :
98 181595 : switch (it->itype) {
99 :
100 : case ASN1_ITYPE_PRIMITIVE:
101 88874 : if (it->templates)
102 3362 : ASN1_template_free(pval, it->templates);
103 : else
104 85512 : ASN1_primitive_free(pval, it);
105 : break;
106 :
107 : case ASN1_ITYPE_MSTRING:
108 32745 : ASN1_primitive_free(pval, it);
109 32745 : break;
110 :
111 : case ASN1_ITYPE_CHOICE:
112 6040 : if (asn1_cb) {
113 0 : i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
114 0 : if (i == 2)
115 : return;
116 : }
117 6040 : i = asn1_get_choice_selector(pval, it);
118 6040 : if ((i >= 0) && (i < it->tcount)) {
119 : ASN1_VALUE **pchval;
120 6040 : tt = it->templates + i;
121 6040 : pchval = asn1_get_field_ptr(pval, tt);
122 6040 : ASN1_template_free(pchval, tt);
123 : }
124 6040 : if (asn1_cb)
125 0 : asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
126 6040 : if (!combine) {
127 6040 : OPENSSL_free(*pval);
128 6040 : *pval = NULL;
129 : }
130 : break;
131 :
132 : case ASN1_ITYPE_COMPAT:
133 : cf = it->funcs;
134 0 : if (cf && cf->asn1_free)
135 0 : cf->asn1_free(*pval);
136 : break;
137 :
138 : case ASN1_ITYPE_EXTERN:
139 : ef = it->funcs;
140 3362 : if (ef && ef->asn1_ex_free)
141 3362 : ef->asn1_ex_free(pval, it);
142 : break;
143 :
144 : case ASN1_ITYPE_NDEF_SEQUENCE:
145 : case ASN1_ITYPE_SEQUENCE:
146 50574 : if (asn1_do_lock(pval, -1, it) > 0)
147 : return;
148 47107 : if (asn1_cb) {
149 3374 : i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
150 3374 : if (i == 2)
151 : return;
152 : }
153 47107 : asn1_enc_free(pval, it);
154 : /*
155 : * If we free up as normal we will invalidate any ANY DEFINED BY
156 : * field and we wont be able to determine the type of the field it
157 : * defines. So free up in reverse order.
158 : */
159 47107 : tt = it->templates + it->tcount - 1;
160 160205 : for (i = 0; i < it->tcount; tt--, i++) {
161 : ASN1_VALUE **pseqval;
162 113096 : seqtt = asn1_do_adb(pval, tt, 0);
163 113097 : if (!seqtt)
164 0 : continue;
165 113097 : pseqval = asn1_get_field_ptr(pval, seqtt);
166 113098 : ASN1_template_free(pseqval, seqtt);
167 : }
168 47109 : if (asn1_cb)
169 3374 : asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
170 47109 : if (!combine) {
171 47109 : OPENSSL_free(*pval);
172 47109 : *pval = NULL;
173 : }
174 : break;
175 : }
176 : }
177 :
178 131891 : void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
179 : {
180 : int i;
181 131891 : if (tt->flags & ASN1_TFLG_SK_MASK) {
182 5502 : STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
183 12068 : for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
184 : ASN1_VALUE *vtmp;
185 6566 : vtmp = sk_ASN1_VALUE_value(sk, i);
186 6566 : asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0);
187 : }
188 5502 : sk_ASN1_VALUE_free(sk);
189 5502 : *pval = NULL;
190 : } else
191 126389 : asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
192 : tt->flags & ASN1_TFLG_COMBINE);
193 131895 : }
194 :
195 124068 : void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
196 : {
197 : int utype;
198 124068 : if (it) {
199 : const ASN1_PRIMITIVE_FUNCS *pf;
200 118250 : pf = it->funcs;
201 118250 : if (pf && pf->prim_free) {
202 0 : pf->prim_free(pval, it);
203 0 : return;
204 : }
205 : }
206 : /* Special case: if 'it' is NULL free contents of ASN1_TYPE */
207 124068 : if (!it) {
208 5812 : ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
209 5812 : utype = typ->type;
210 5812 : pval = &typ->value.asn1_value;
211 5812 : if (!*pval)
212 : return;
213 118256 : } else if (it->itype == ASN1_ITYPE_MSTRING) {
214 : utype = -1;
215 32745 : if (!*pval)
216 : return;
217 : } else {
218 85511 : utype = it->utype;
219 85511 : if ((utype != V_ASN1_BOOLEAN) && !*pval)
220 : return;
221 : }
222 :
223 107579 : switch (utype) {
224 : case V_ASN1_OBJECT:
225 38920 : ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
226 38921 : break;
227 :
228 : case V_ASN1_BOOLEAN:
229 8890 : if (it)
230 8890 : *(ASN1_BOOLEAN *)pval = it->size;
231 : else
232 0 : *(ASN1_BOOLEAN *)pval = -1;
233 : return;
234 :
235 : case V_ASN1_NULL:
236 : break;
237 :
238 : case V_ASN1_ANY:
239 5812 : ASN1_primitive_free(pval, NULL);
240 5812 : OPENSSL_free(*pval);
241 5812 : break;
242 :
243 : default:
244 53960 : ASN1_STRING_free((ASN1_STRING *)*pval);
245 53963 : *pval = NULL;
246 53963 : break;
247 : }
248 98693 : *pval = NULL;
249 : }
|