• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/asn1.h>
58 
59 #include <openssl/asn1t.h>
60 #include <openssl/mem.h>
61 
62 
63 static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine);
64 
65 /* Free up an ASN1 structure */
66 
ASN1_item_free(ASN1_VALUE * val,const ASN1_ITEM * it)67 void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
68 	{
69 	asn1_item_combine_free(&val, it, 0);
70 	}
71 
ASN1_item_ex_free(ASN1_VALUE ** pval,const ASN1_ITEM * it)72 void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
73 	{
74 	asn1_item_combine_free(pval, it, 0);
75 	}
76 
asn1_item_combine_free(ASN1_VALUE ** pval,const ASN1_ITEM * it,int combine)77 static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
78 	{
79 	const ASN1_TEMPLATE *tt = NULL, *seqtt;
80 	const ASN1_EXTERN_FUNCS *ef;
81 	const ASN1_COMPAT_FUNCS *cf;
82 	const ASN1_AUX *aux = it->funcs;
83 	ASN1_aux_cb *asn1_cb;
84 	int i;
85 	if (!pval)
86 		return;
87 	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
88 		return;
89 	if (aux && aux->asn1_cb)
90 		asn1_cb = aux->asn1_cb;
91 	else
92 		asn1_cb = 0;
93 
94 	switch(it->itype)
95 		{
96 
97 		case ASN1_ITYPE_PRIMITIVE:
98 		if (it->templates)
99 			ASN1_template_free(pval, it->templates);
100 		else
101 			ASN1_primitive_free(pval, it);
102 		break;
103 
104 		case ASN1_ITYPE_MSTRING:
105 		ASN1_primitive_free(pval, it);
106 		break;
107 
108 		case ASN1_ITYPE_CHOICE:
109 		if (asn1_cb)
110 			{
111 			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
112 			if (i == 2)
113 				return;
114 			}
115 		i = asn1_get_choice_selector(pval, it);
116 		if ((i >= 0) && (i < it->tcount))
117 			{
118 			ASN1_VALUE **pchval;
119 			tt = it->templates + i;
120 			pchval = asn1_get_field_ptr(pval, tt);
121 			ASN1_template_free(pchval, tt);
122 			}
123 		if (asn1_cb)
124 			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
125 		if (!combine)
126 			{
127 			OPENSSL_free(*pval);
128 			*pval = NULL;
129 			}
130 		break;
131 
132 		case ASN1_ITYPE_COMPAT:
133 		cf = it->funcs;
134 		if (cf && cf->asn1_free)
135 			cf->asn1_free(*pval);
136 		break;
137 
138 		case ASN1_ITYPE_EXTERN:
139 		ef = it->funcs;
140 		if (ef && ef->asn1_ex_free)
141 			ef->asn1_ex_free(pval, it);
142 		break;
143 
144 		case ASN1_ITYPE_NDEF_SEQUENCE:
145 		case ASN1_ITYPE_SEQUENCE:
146 		if (!asn1_refcount_dec_and_test_zero(pval, it))
147 			return;
148 		if (asn1_cb)
149 			{
150 			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
151 			if (i == 2)
152 				return;
153 			}
154 		asn1_enc_free(pval, it);
155 		/* If we free up as normal we will invalidate any
156 		 * ANY DEFINED BY field and we wont be able to
157 		 * determine the type of the field it defines. So
158 		 * free up in reverse order.
159 		 */
160 		tt = it->templates + it->tcount - 1;
161 		for (i = 0; i < it->tcount; tt--, i++)
162 			{
163 			ASN1_VALUE **pseqval;
164 			seqtt = asn1_do_adb(pval, tt, 0);
165 			if (!seqtt)
166 				continue;
167 			pseqval = asn1_get_field_ptr(pval, seqtt);
168 			ASN1_template_free(pseqval, seqtt);
169 			}
170 		if (asn1_cb)
171 			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
172 		if (!combine)
173 			{
174 			OPENSSL_free(*pval);
175 			*pval = NULL;
176 			}
177 		break;
178 		}
179 	}
180 
ASN1_template_free(ASN1_VALUE ** pval,const ASN1_TEMPLATE * tt)181 void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
182 	{
183 	size_t i;
184 	if (tt->flags & ASN1_TFLG_SK_MASK)
185 		{
186 		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
187 		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
188 			{
189 			ASN1_VALUE *vtmp;
190 			vtmp = sk_ASN1_VALUE_value(sk, i);
191 			asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
192 									0);
193 			}
194 		sk_ASN1_VALUE_free(sk);
195 		*pval = NULL;
196 		}
197 	else
198 		asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
199 						tt->flags & ASN1_TFLG_COMBINE);
200 	}
201 
ASN1_primitive_free(ASN1_VALUE ** pval,const ASN1_ITEM * it)202 void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
203 	{
204 	int utype;
205 	if (it)
206 		{
207 		const ASN1_PRIMITIVE_FUNCS *pf;
208 		pf = it->funcs;
209 		if (pf && pf->prim_free)
210 			{
211 			pf->prim_free(pval, it);
212 			return;
213 			}
214 		}
215 	/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
216 	if (!it)
217 		{
218 		ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
219 		utype = typ->type;
220 		pval = &typ->value.asn1_value;
221 		if (!*pval)
222 			return;
223 		}
224 	else if (it->itype == ASN1_ITYPE_MSTRING)
225 		{
226 		utype = -1;
227 		if (!*pval)
228 			return;
229 		}
230 	else
231 		{
232 		utype = it->utype;
233 		if ((utype != V_ASN1_BOOLEAN) && !*pval)
234 			return;
235 		}
236 
237 	switch(utype)
238 		{
239 		case V_ASN1_OBJECT:
240 		ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
241 		break;
242 
243 		case V_ASN1_BOOLEAN:
244 		if (it)
245 			*(ASN1_BOOLEAN *)pval = it->size;
246 		else
247 			*(ASN1_BOOLEAN *)pval = -1;
248 		return;
249 
250 		case V_ASN1_NULL:
251 		break;
252 
253 		case V_ASN1_ANY:
254 		ASN1_primitive_free(pval, NULL);
255 		OPENSSL_free(*pval);
256 		break;
257 
258 		default:
259 		ASN1_STRING_free((ASN1_STRING *)*pval);
260 		*pval = NULL;
261 		break;
262 		}
263 	*pval = NULL;
264 	}
265