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