• 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/err.h>
61 #include <openssl/mem.h>
62 #include <openssl/obj.h>
63 
64 
65 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
66 								int combine);
67 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
68 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
69 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
70 
ASN1_item_new(const ASN1_ITEM * it)71 ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
72 	{
73 	ASN1_VALUE *ret = NULL;
74 	if (ASN1_item_ex_new(&ret, it) > 0)
75 		return ret;
76 	return NULL;
77 	}
78 
79 /* Allocate an ASN1 structure */
80 
ASN1_item_ex_new(ASN1_VALUE ** pval,const ASN1_ITEM * it)81 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
82 	{
83 	return asn1_item_ex_combine_new(pval, it, 0);
84 	}
85 
asn1_item_ex_combine_new(ASN1_VALUE ** pval,const ASN1_ITEM * it,int combine)86 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
87 								int combine)
88 	{
89 	const ASN1_TEMPLATE *tt = NULL;
90 	const ASN1_COMPAT_FUNCS *cf;
91 	const ASN1_EXTERN_FUNCS *ef;
92 	const ASN1_AUX *aux = it->funcs;
93 	ASN1_aux_cb *asn1_cb;
94 	ASN1_VALUE **pseqval;
95 	int i;
96 	if (aux && aux->asn1_cb)
97 		asn1_cb = aux->asn1_cb;
98 	else
99 		asn1_cb = 0;
100 
101 	if (!combine) *pval = NULL;
102 
103 #ifdef CRYPTO_MDEBUG
104 	if (it->sname)
105 		CRYPTO_push_info(it->sname);
106 #endif
107 
108 	switch(it->itype)
109 		{
110 
111 		case ASN1_ITYPE_EXTERN:
112 		ef = it->funcs;
113 		if (ef && ef->asn1_ex_new)
114 			{
115 			if (!ef->asn1_ex_new(pval, it))
116 				goto memerr;
117 			}
118 		break;
119 
120 		case ASN1_ITYPE_COMPAT:
121 		cf = it->funcs;
122 		if (cf && cf->asn1_new) {
123 			*pval = cf->asn1_new();
124 			if (!*pval)
125 				goto memerr;
126 		}
127 		break;
128 
129 		case ASN1_ITYPE_PRIMITIVE:
130 		if (it->templates)
131 			{
132 			if (!ASN1_template_new(pval, it->templates))
133 				goto memerr;
134 			}
135 		else if (!ASN1_primitive_new(pval, it))
136 				goto memerr;
137 		break;
138 
139 		case ASN1_ITYPE_MSTRING:
140 		if (!ASN1_primitive_new(pval, it))
141 				goto memerr;
142 		break;
143 
144 		case ASN1_ITYPE_CHOICE:
145 		if (asn1_cb)
146 			{
147 			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
148 			if (!i)
149 				goto auxerr;
150 			if (i==2)
151 				{
152 #ifdef CRYPTO_MDEBUG
153 				if (it->sname)
154 					CRYPTO_pop_info();
155 #endif
156 				return 1;
157 				}
158 			}
159 		if (!combine)
160 			{
161 			*pval = OPENSSL_malloc(it->size);
162 			if (!*pval)
163 				goto memerr;
164 			memset(*pval, 0, it->size);
165 			}
166 		asn1_set_choice_selector(pval, -1, it);
167 		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
168 				goto auxerr;
169 		break;
170 
171 		case ASN1_ITYPE_NDEF_SEQUENCE:
172 		case ASN1_ITYPE_SEQUENCE:
173 		if (asn1_cb)
174 			{
175 			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
176 			if (!i)
177 				goto auxerr;
178 			if (i==2)
179 				{
180 #ifdef CRYPTO_MDEBUG
181 				if (it->sname)
182 					CRYPTO_pop_info();
183 #endif
184 				return 1;
185 				}
186 			}
187 		if (!combine)
188 			{
189 			*pval = OPENSSL_malloc(it->size);
190 			if (!*pval)
191 				goto memerr;
192 			memset(*pval, 0, it->size);
193 			asn1_do_lock(pval, 0, it);
194 			asn1_enc_init(pval, it);
195 			}
196 		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
197 			{
198 			pseqval = asn1_get_field_ptr(pval, tt);
199 			if (!ASN1_template_new(pseqval, tt))
200 				goto memerr;
201 			}
202 		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
203 				goto auxerr;
204 		break;
205 	}
206 #ifdef CRYPTO_MDEBUG
207 	if (it->sname) CRYPTO_pop_info();
208 #endif
209 	return 1;
210 
211 	memerr:
212 	OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new,  ERR_R_MALLOC_FAILURE);
213 #ifdef CRYPTO_MDEBUG
214 	if (it->sname) CRYPTO_pop_info();
215 #endif
216 	return 0;
217 
218 	auxerr:
219 	OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new,  ASN1_R_AUX_ERROR);
220 	ASN1_item_ex_free(pval, it);
221 #ifdef CRYPTO_MDEBUG
222 	if (it->sname) CRYPTO_pop_info();
223 #endif
224 	return 0;
225 
226 	}
227 
asn1_item_clear(ASN1_VALUE ** pval,const ASN1_ITEM * it)228 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
229 	{
230 	const ASN1_EXTERN_FUNCS *ef;
231 
232 	switch(it->itype)
233 		{
234 
235 		case ASN1_ITYPE_EXTERN:
236 		ef = it->funcs;
237 		if (ef && ef->asn1_ex_clear)
238 			ef->asn1_ex_clear(pval, it);
239 		else *pval = NULL;
240 		break;
241 
242 
243 		case ASN1_ITYPE_PRIMITIVE:
244 		if (it->templates)
245 			asn1_template_clear(pval, it->templates);
246 		else
247 			asn1_primitive_clear(pval, it);
248 		break;
249 
250 		case ASN1_ITYPE_MSTRING:
251 		asn1_primitive_clear(pval, it);
252 		break;
253 
254 		case ASN1_ITYPE_COMPAT:
255 		case ASN1_ITYPE_CHOICE:
256 		case ASN1_ITYPE_SEQUENCE:
257 		case ASN1_ITYPE_NDEF_SEQUENCE:
258 		*pval = NULL;
259 		break;
260 		}
261 	}
262 
263 
ASN1_template_new(ASN1_VALUE ** pval,const ASN1_TEMPLATE * tt)264 int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
265 	{
266 	const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
267 	int ret;
268 	if (tt->flags & ASN1_TFLG_OPTIONAL)
269 		{
270 		asn1_template_clear(pval, tt);
271 		return 1;
272 		}
273 	/* If ANY DEFINED BY nothing to do */
274 
275 	if (tt->flags & ASN1_TFLG_ADB_MASK)
276 		{
277 		*pval = NULL;
278 		return 1;
279 		}
280 #ifdef CRYPTO_MDEBUG
281 	if (tt->field_name)
282 		CRYPTO_push_info(tt->field_name);
283 #endif
284 	/* If SET OF or SEQUENCE OF, its a STACK */
285 	if (tt->flags & ASN1_TFLG_SK_MASK)
286 		{
287 		STACK_OF(ASN1_VALUE) *skval;
288 		skval = sk_ASN1_VALUE_new_null();
289 		if (!skval)
290 			{
291 			OPENSSL_PUT_ERROR(ASN1, ASN1_template_new,  ERR_R_MALLOC_FAILURE);
292 			ret = 0;
293 			goto done;
294 			}
295 		*pval = (ASN1_VALUE *)skval;
296 		ret = 1;
297 		goto done;
298 		}
299 	/* Otherwise pass it back to the item routine */
300 	ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
301 	done:
302 #ifdef CRYPTO_MDEBUG
303 	if (it->sname)
304 		CRYPTO_pop_info();
305 #endif
306 	return ret;
307 	}
308 
asn1_template_clear(ASN1_VALUE ** pval,const ASN1_TEMPLATE * tt)309 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
310 	{
311 	/* If ADB or STACK just NULL the field */
312 	if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK))
313 		*pval = NULL;
314 	else
315 		asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
316 	}
317 
318 
319 /* NB: could probably combine most of the real XXX_new() behaviour and junk
320  * all the old functions.
321  */
322 
ASN1_primitive_new(ASN1_VALUE ** pval,const ASN1_ITEM * it)323 int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
324 	{
325 	ASN1_TYPE *typ;
326 	ASN1_STRING *str;
327 	int utype;
328 
329 	if (it && it->funcs)
330 		{
331 		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
332 		if (pf->prim_new)
333 			return pf->prim_new(pval, it);
334 		}
335 
336 	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
337 		utype = -1;
338 	else
339 		utype = it->utype;
340 	switch(utype)
341 		{
342 		case V_ASN1_OBJECT:
343 		*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
344 		return 1;
345 
346 		case V_ASN1_BOOLEAN:
347 		*(ASN1_BOOLEAN *)pval = it->size;
348 		return 1;
349 
350 		case V_ASN1_NULL:
351 		*pval = (ASN1_VALUE *)1;
352 		return 1;
353 
354 		case V_ASN1_ANY:
355 		typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
356 		if (!typ)
357 			return 0;
358 		typ->value.ptr = NULL;
359 		typ->type = -1;
360 		*pval = (ASN1_VALUE *)typ;
361 		break;
362 
363 		default:
364 		str = ASN1_STRING_type_new(utype);
365 		if (it->itype == ASN1_ITYPE_MSTRING && str)
366 			str->flags |= ASN1_STRING_FLAG_MSTRING;
367 		*pval = (ASN1_VALUE *)str;
368 		break;
369 		}
370 	if (*pval)
371 		return 1;
372 	return 0;
373 	}
374 
asn1_primitive_clear(ASN1_VALUE ** pval,const ASN1_ITEM * it)375 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
376 	{
377 	int utype;
378 	if (it && it->funcs)
379 		{
380 		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
381 		if (pf->prim_clear)
382 			pf->prim_clear(pval, it);
383 		else
384 			*pval = NULL;
385 		return;
386 		}
387 	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
388 		utype = -1;
389 	else
390 		utype = it->utype;
391 	if (utype == V_ASN1_BOOLEAN)
392 		*(ASN1_BOOLEAN *)pval = it->size;
393 	else *pval = NULL;
394 	}
395