• 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 <string.h>
60 
61 #include <openssl/asn1t.h>
62 #include <openssl/err.h>
63 #include <openssl/mem.h>
64 #include <openssl/obj.h>
65 
66 
67 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
68 								int combine);
69 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
70 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
71 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
72 
ASN1_item_new(const ASN1_ITEM * it)73 ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
74 	{
75 	ASN1_VALUE *ret = NULL;
76 	if (ASN1_item_ex_new(&ret, it) > 0)
77 		return ret;
78 	return NULL;
79 	}
80 
81 /* Allocate an ASN1 structure */
82 
ASN1_item_ex_new(ASN1_VALUE ** pval,const ASN1_ITEM * it)83 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
84 	{
85 	return asn1_item_ex_combine_new(pval, it, 0);
86 	}
87 
asn1_item_ex_combine_new(ASN1_VALUE ** pval,const ASN1_ITEM * it,int combine)88 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
89 								int combine)
90 	{
91 	const ASN1_TEMPLATE *tt = NULL;
92 	const ASN1_COMPAT_FUNCS *cf;
93 	const ASN1_EXTERN_FUNCS *ef;
94 	const ASN1_AUX *aux = it->funcs;
95 	ASN1_aux_cb *asn1_cb;
96 	ASN1_VALUE **pseqval;
97 	int i;
98 	if (aux && aux->asn1_cb)
99 		asn1_cb = aux->asn1_cb;
100 	else
101 		asn1_cb = 0;
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_refcount_set_one(pval, 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, ERR_R_MALLOC_FAILURE);
213 	ASN1_item_ex_free(pval, it);
214 #ifdef CRYPTO_MDEBUG
215 	if (it->sname) CRYPTO_pop_info();
216 #endif
217 	return 0;
218 
219 	auxerr:
220 	OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
221 	ASN1_item_ex_free(pval, it);
222 #ifdef CRYPTO_MDEBUG
223 	if (it->sname) CRYPTO_pop_info();
224 #endif
225 	return 0;
226 
227 	}
228 
asn1_item_clear(ASN1_VALUE ** pval,const ASN1_ITEM * it)229 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
230 	{
231 	const ASN1_EXTERN_FUNCS *ef;
232 
233 	switch(it->itype)
234 		{
235 
236 		case ASN1_ITYPE_EXTERN:
237 		ef = it->funcs;
238 		if (ef && ef->asn1_ex_clear)
239 			ef->asn1_ex_clear(pval, it);
240 		else *pval = NULL;
241 		break;
242 
243 
244 		case ASN1_ITYPE_PRIMITIVE:
245 		if (it->templates)
246 			asn1_template_clear(pval, it->templates);
247 		else
248 			asn1_primitive_clear(pval, it);
249 		break;
250 
251 		case ASN1_ITYPE_MSTRING:
252 		asn1_primitive_clear(pval, it);
253 		break;
254 
255 		case ASN1_ITYPE_COMPAT:
256 		case ASN1_ITYPE_CHOICE:
257 		case ASN1_ITYPE_SEQUENCE:
258 		case ASN1_ITYPE_NDEF_SEQUENCE:
259 		*pval = NULL;
260 		break;
261 		}
262 	}
263 
264 
ASN1_template_new(ASN1_VALUE ** pval,const ASN1_TEMPLATE * tt)265 int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
266 	{
267 	const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
268 	int ret;
269 	if (tt->flags & ASN1_TFLG_OPTIONAL)
270 		{
271 		asn1_template_clear(pval, tt);
272 		return 1;
273 		}
274 	/* If ANY DEFINED BY nothing to do */
275 
276 	if (tt->flags & ASN1_TFLG_ADB_MASK)
277 		{
278 		*pval = NULL;
279 		return 1;
280 		}
281 #ifdef CRYPTO_MDEBUG
282 	if (tt->field_name)
283 		CRYPTO_push_info(tt->field_name);
284 #endif
285 	/* If SET OF or SEQUENCE OF, its a STACK */
286 	if (tt->flags & ASN1_TFLG_SK_MASK)
287 		{
288 		STACK_OF(ASN1_VALUE) *skval;
289 		skval = sk_ASN1_VALUE_new_null();
290 		if (!skval)
291 			{
292 			OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
293 			ret = 0;
294 			goto done;
295 			}
296 		*pval = (ASN1_VALUE *)skval;
297 		ret = 1;
298 		goto done;
299 		}
300 	/* Otherwise pass it back to the item routine */
301 	ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
302 	done:
303 #ifdef CRYPTO_MDEBUG
304 	if (it->sname)
305 		CRYPTO_pop_info();
306 #endif
307 	return ret;
308 	}
309 
asn1_template_clear(ASN1_VALUE ** pval,const ASN1_TEMPLATE * tt)310 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
311 	{
312 	/* If ADB or STACK just NULL the field */
313 	if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK))
314 		*pval = NULL;
315 	else
316 		asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
317 	}
318 
319 
320 /* NB: could probably combine most of the real XXX_new() behaviour and junk
321  * all the old functions.
322  */
323 
ASN1_primitive_new(ASN1_VALUE ** pval,const ASN1_ITEM * it)324 int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
325 	{
326 	ASN1_TYPE *typ;
327 	ASN1_STRING *str;
328 	int utype;
329 
330 	if (!it)
331 		return 0;
332 
333 	if (it->funcs)
334 		{
335 		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
336 		if (pf->prim_new)
337 			return pf->prim_new(pval, it);
338 		}
339 
340 	if (it->itype == ASN1_ITYPE_MSTRING)
341 		utype = -1;
342 	else
343 		utype = it->utype;
344 	switch(utype)
345 		{
346 		case V_ASN1_OBJECT:
347 		*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
348 		return 1;
349 
350 		case V_ASN1_BOOLEAN:
351 		*(ASN1_BOOLEAN *)pval = it->size;
352 		return 1;
353 
354 		case V_ASN1_NULL:
355 		*pval = (ASN1_VALUE *)1;
356 		return 1;
357 
358 		case V_ASN1_ANY:
359 		typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
360 		if (!typ)
361 			return 0;
362 		typ->value.ptr = NULL;
363 		typ->type = -1;
364 		*pval = (ASN1_VALUE *)typ;
365 		break;
366 
367 		default:
368 		str = ASN1_STRING_type_new(utype);
369 		if (it->itype == ASN1_ITYPE_MSTRING && str)
370 			str->flags |= ASN1_STRING_FLAG_MSTRING;
371 		*pval = (ASN1_VALUE *)str;
372 		break;
373 		}
374 	if (*pval)
375 		return 1;
376 	return 0;
377 	}
378 
asn1_primitive_clear(ASN1_VALUE ** pval,const ASN1_ITEM * it)379 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
380 	{
381 	int utype;
382 	if (it && it->funcs)
383 		{
384 		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
385 		if (pf->prim_clear)
386 			pf->prim_clear(pval, it);
387 		else
388 			*pval = NULL;
389 		return;
390 		}
391 	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
392 		utype = -1;
393 	else
394 		utype = it->utype;
395 	if (utype == V_ASN1_BOOLEAN)
396 		*(ASN1_BOOLEAN *)pval = it->size;
397 	else *pval = NULL;
398 	}
399