Merge branch 'vendor/OPENSSL'
[dragonfly.git] / crypto / openssl / crypto / asn1 / tasn_new.c
1 /* tasn_new.c */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 2000.
4  */
5 /* ====================================================================
6  * Copyright (c) 2000-2004 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer. 
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
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
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 void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
72
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
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
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         if (!combine) *pval = NULL;
104
105 #ifdef CRYPTO_MDEBUG
106         if (it->sname)
107                 CRYPTO_push_info(it->sname);
108 #endif
109
110         switch(it->itype)
111                 {
112
113                 case ASN1_ITYPE_EXTERN:
114                 ef = it->funcs;
115                 if (ef && ef->asn1_ex_new)
116                         {
117                         if (!ef->asn1_ex_new(pval, it))
118                                 goto memerr;
119                         }
120                 break;
121
122                 case ASN1_ITYPE_COMPAT:
123                 cf = it->funcs;
124                 if (cf && cf->asn1_new) {
125                         *pval = cf->asn1_new();
126                         if (!*pval)
127                                 goto memerr;
128                 }
129                 break;
130
131                 case ASN1_ITYPE_PRIMITIVE:
132                 if (it->templates)
133                         {
134                         if (!ASN1_template_new(pval, it->templates))
135                                 goto memerr;
136                         }
137                 else if (!ASN1_primitive_new(pval, it))
138                                 goto memerr;
139                 break;
140
141                 case ASN1_ITYPE_MSTRING:
142                 if (!ASN1_primitive_new(pval, it))
143                                 goto memerr;
144                 break;
145
146                 case ASN1_ITYPE_CHOICE:
147                 if (asn1_cb)
148                         {
149                         i = asn1_cb(ASN1_OP_NEW_PRE, pval, it);
150                         if (!i)
151                                 goto auxerr;
152                         if (i==2)
153                                 {
154 #ifdef CRYPTO_MDEBUG
155                                 if (it->sname)
156                                         CRYPTO_pop_info();
157 #endif
158                                 return 1;
159                                 }
160                         }
161                 if (!combine)
162                         {
163                         *pval = OPENSSL_malloc(it->size);
164                         if (!*pval)
165                                 goto memerr;
166                         memset(*pval, 0, it->size);
167                         }
168                 asn1_set_choice_selector(pval, -1, it);
169                 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it))
170                                 goto auxerr;
171                 break;
172
173                 case ASN1_ITYPE_NDEF_SEQUENCE:
174                 case ASN1_ITYPE_SEQUENCE:
175                 if (asn1_cb)
176                         {
177                         i = asn1_cb(ASN1_OP_NEW_PRE, pval, it);
178                         if (!i)
179                                 goto auxerr;
180                         if (i==2)
181                                 {
182 #ifdef CRYPTO_MDEBUG
183                                 if (it->sname)
184                                         CRYPTO_pop_info();
185 #endif
186                                 return 1;
187                                 }
188                         }
189                 if (!combine)
190                         {
191                         *pval = OPENSSL_malloc(it->size);
192                         if (!*pval)
193                                 goto memerr;
194                         memset(*pval, 0, it->size);
195                         asn1_do_lock(pval, 0, it);
196                         asn1_enc_init(pval, it);
197                         }
198                 for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
199                         {
200                         pseqval = asn1_get_field_ptr(pval, tt);
201                         if (!ASN1_template_new(pseqval, tt))
202                                 goto memerr;
203                         }
204                 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it))
205                                 goto auxerr;
206                 break;
207         }
208 #ifdef CRYPTO_MDEBUG
209         if (it->sname) CRYPTO_pop_info();
210 #endif
211         return 1;
212
213         memerr:
214         ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);
215 #ifdef CRYPTO_MDEBUG
216         if (it->sname) CRYPTO_pop_info();
217 #endif
218         return 0;
219
220         auxerr:
221         ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);
222         ASN1_item_ex_free(pval, it);
223 #ifdef CRYPTO_MDEBUG
224         if (it->sname) CRYPTO_pop_info();
225 #endif
226         return 0;
227
228         }
229
230 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
231         {
232         const ASN1_EXTERN_FUNCS *ef;
233
234         switch(it->itype)
235                 {
236
237                 case ASN1_ITYPE_EXTERN:
238                 ef = it->funcs;
239                 if (ef && ef->asn1_ex_clear) 
240                         ef->asn1_ex_clear(pval, it);
241                 else *pval = NULL;
242                 break;
243
244
245                 case ASN1_ITYPE_PRIMITIVE:
246                 if (it->templates) 
247                         asn1_template_clear(pval, it->templates);
248                 else
249                         asn1_primitive_clear(pval, it);
250                 break;
251
252                 case ASN1_ITYPE_MSTRING:
253                 asn1_primitive_clear(pval, it);
254                 break;
255
256                 case ASN1_ITYPE_COMPAT:
257                 case ASN1_ITYPE_CHOICE:
258                 case ASN1_ITYPE_SEQUENCE:
259                 case ASN1_ITYPE_NDEF_SEQUENCE:
260                 *pval = NULL;
261                 break;
262                 }
263         }
264
265
266 int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
267         {
268         const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
269         int ret;
270         if (tt->flags & ASN1_TFLG_OPTIONAL)
271                 {
272                 asn1_template_clear(pval, tt);
273                 return 1;
274                 }
275         /* If ANY DEFINED BY nothing to do */
276
277         if (tt->flags & ASN1_TFLG_ADB_MASK)
278                 {
279                 *pval = NULL;
280                 return 1;
281                 }
282 #ifdef CRYPTO_MDEBUG
283         if (tt->field_name)
284                 CRYPTO_push_info(tt->field_name);
285 #endif
286         /* If SET OF or SEQUENCE OF, its a STACK */
287         if (tt->flags & ASN1_TFLG_SK_MASK)
288                 {
289                 STACK_OF(ASN1_VALUE) *skval;
290                 skval = sk_ASN1_VALUE_new_null();
291                 if (!skval)
292                         {
293                         ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
294                         ret = 0;
295                         goto done;
296                         }
297                 *pval = (ASN1_VALUE *)skval;
298                 ret = 1;
299                 goto done;
300                 }
301         /* Otherwise pass it back to the item routine */
302         ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
303         done:
304 #ifdef CRYPTO_MDEBUG
305         if (it->sname)
306                 CRYPTO_pop_info();
307 #endif
308         return ret;
309         }
310
311 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
312         {
313         /* If ADB or STACK just NULL the field */
314         if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) 
315                 *pval = NULL;
316         else
317                 asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
318         }
319
320
321 /* NB: could probably combine most of the real XXX_new() behaviour and junk
322  * all the old functions.
323  */
324
325 int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
326         {
327         ASN1_TYPE *typ;
328         int utype;
329
330         if (it && it->funcs)
331                 {
332                 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
333                 if (pf->prim_new)
334                         return pf->prim_new(pval, it);
335                 }
336
337         if (!it || (it->itype == ASN1_ITYPE_MSTRING))
338                 utype = -1;
339         else
340                 utype = it->utype;
341         switch(utype)
342                 {
343                 case V_ASN1_OBJECT:
344                 *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
345                 return 1;
346
347                 case V_ASN1_BOOLEAN:
348                 if (it)
349                         *(ASN1_BOOLEAN *)pval = it->size;
350                 else
351                         *(ASN1_BOOLEAN *)pval = -1;
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                 *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype);
369                 break;
370                 }
371         if (*pval)
372                 return 1;
373         return 0;
374         }
375
376 void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
377         {
378         int utype;
379         if (it && it->funcs)
380                 {
381                 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
382                 if (pf->prim_clear)
383                         pf->prim_clear(pval, it);
384                 else 
385                         *pval = NULL;
386                 return;
387                 }
388         if (!it || (it->itype == ASN1_ITYPE_MSTRING))
389                 utype = -1;
390         else
391                 utype = it->utype;
392         if (utype == V_ASN1_BOOLEAN)
393                 *(ASN1_BOOLEAN *)pval = it->size;
394         else *pval = NULL;
395         }