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