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