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