Enable/disable crypto-mdebug just like other features
[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_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
69                                int embed);
70 static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
71                               int embed);
72 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
73 static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
74 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
75 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
76
77 ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
78 {
79     ASN1_VALUE *ret = NULL;
80     if (ASN1_item_ex_new(&ret, it) > 0)
81         return ret;
82     return NULL;
83 }
84
85 /* Allocate an ASN1 structure */
86
87 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
88 {
89     return asn1_item_embed_new(pval, it, 0);
90 }
91
92 int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
93 {
94     const ASN1_TEMPLATE *tt = NULL;
95     const ASN1_EXTERN_FUNCS *ef;
96     const ASN1_AUX *aux = it->funcs;
97     ASN1_aux_cb *asn1_cb;
98     ASN1_VALUE **pseqval;
99     int i;
100     if (aux && aux->asn1_cb)
101         asn1_cb = aux->asn1_cb;
102     else
103         asn1_cb = 0;
104
105 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
106     OPENSSL_mem_debug_push(it->sname ? it->sname : "asn1_item_embed_new");
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_PRIMITIVE:
120         if (it->templates) {
121             if (!asn1_template_new(pval, it->templates))
122                 goto memerr;
123         } else if (!asn1_primitive_new(pval, it, embed))
124             goto memerr;
125         break;
126
127     case ASN1_ITYPE_MSTRING:
128         if (!asn1_primitive_new(pval, it, embed))
129             goto memerr;
130         break;
131
132     case ASN1_ITYPE_CHOICE:
133         if (asn1_cb) {
134             i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
135             if (!i)
136                 goto auxerr;
137             if (i == 2) {
138 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
139                 OPENSSL_mem_debug_pop();
140 #endif
141                 return 1;
142             }
143         }
144         if (embed) {
145             memset(*pval, 0, it->size);
146         } else {
147             *pval = OPENSSL_zalloc(it->size);
148             if (*pval == NULL)
149                 goto memerr;
150         }
151         asn1_set_choice_selector(pval, -1, it);
152         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
153             goto auxerr;
154         break;
155
156     case ASN1_ITYPE_NDEF_SEQUENCE:
157     case ASN1_ITYPE_SEQUENCE:
158         if (asn1_cb) {
159             i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
160             if (!i)
161                 goto auxerr;
162             if (i == 2) {
163 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
164                 OPENSSL_mem_debug_pop();
165 #endif
166                 return 1;
167             }
168         }
169         if (embed) {
170             memset(*pval, 0, it->size);
171         } else {
172             *pval = OPENSSL_zalloc(it->size);
173             if (*pval == NULL)
174                 goto memerr;
175         }
176         asn1_do_lock(pval, 0, it);
177         asn1_enc_init(pval, it);
178         for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
179             pseqval = asn1_get_field_ptr(pval, tt);
180             if (!asn1_template_new(pseqval, tt))
181                 goto memerr;
182         }
183         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
184             goto auxerr;
185         break;
186     }
187 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
188     OPENSSL_mem_debug_pop();
189 #endif
190     return 1;
191
192  memerr:
193     ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ERR_R_MALLOC_FAILURE);
194 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
195     OPENSSL_mem_debug_pop();
196 #endif
197     return 0;
198
199  auxerr:
200     ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ASN1_R_AUX_ERROR);
201     ASN1_item_ex_free(pval, it);
202 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
203     OPENSSL_mem_debug_pop();
204 #endif
205     return 0;
206
207 }
208
209 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
210 {
211     const ASN1_EXTERN_FUNCS *ef;
212
213     switch (it->itype) {
214
215     case ASN1_ITYPE_EXTERN:
216         ef = it->funcs;
217         if (ef && ef->asn1_ex_clear)
218             ef->asn1_ex_clear(pval, it);
219         else
220             *pval = NULL;
221         break;
222
223     case ASN1_ITYPE_PRIMITIVE:
224         if (it->templates)
225             asn1_template_clear(pval, it->templates);
226         else
227             asn1_primitive_clear(pval, it);
228         break;
229
230     case ASN1_ITYPE_MSTRING:
231         asn1_primitive_clear(pval, it);
232         break;
233
234     case ASN1_ITYPE_CHOICE:
235     case ASN1_ITYPE_SEQUENCE:
236     case ASN1_ITYPE_NDEF_SEQUENCE:
237         *pval = NULL;
238         break;
239     }
240 }
241
242 static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
243 {
244     const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
245     int embed = tt->flags & ASN1_TFLG_EMBED;
246     ASN1_VALUE *tval;
247     int ret;
248     if (embed) {
249         tval = (ASN1_VALUE *)pval;
250         pval = &tval;
251     }
252     if (tt->flags & ASN1_TFLG_OPTIONAL) {
253         asn1_template_clear(pval, tt);
254         return 1;
255     }
256     /* If ANY DEFINED BY nothing to do */
257
258     if (tt->flags & ASN1_TFLG_ADB_MASK) {
259         *pval = NULL;
260         return 1;
261     }
262 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
263     OPENSSL_mem_debug_push(tt->field_name
264             ? tt->field_name : "asn1_template_new");
265 #endif
266     /* If SET OF or SEQUENCE OF, its a STACK */
267     if (tt->flags & ASN1_TFLG_SK_MASK) {
268         STACK_OF(ASN1_VALUE) *skval;
269         skval = sk_ASN1_VALUE_new_null();
270         if (!skval) {
271             ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
272             ret = 0;
273             goto done;
274         }
275         *pval = (ASN1_VALUE *)skval;
276         ret = 1;
277         goto done;
278     }
279     /* Otherwise pass it back to the item routine */
280     ret = asn1_item_embed_new(pval, it, embed);
281  done:
282 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
283     OPENSSL_mem_debug_pop();
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 static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
303                               int embed)
304 {
305     ASN1_TYPE *typ;
306     ASN1_STRING *str;
307     int utype;
308
309     if (!it)
310         return 0;
311
312     if (it->funcs) {
313         const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
314         if (pf->prim_new)
315             return pf->prim_new(pval, it);
316     }
317
318     if (it->itype == ASN1_ITYPE_MSTRING)
319         utype = -1;
320     else
321         utype = it->utype;
322     switch (utype) {
323     case V_ASN1_OBJECT:
324         *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
325         return 1;
326
327     case V_ASN1_BOOLEAN:
328         *(ASN1_BOOLEAN *)pval = it->size;
329         return 1;
330
331     case V_ASN1_NULL:
332         *pval = (ASN1_VALUE *)1;
333         return 1;
334
335     case V_ASN1_ANY:
336         typ = OPENSSL_malloc(sizeof(*typ));
337         if (typ == NULL)
338             return 0;
339         typ->value.ptr = NULL;
340         typ->type = -1;
341         *pval = (ASN1_VALUE *)typ;
342         break;
343
344     default:
345         if (embed) {
346             str = *(ASN1_STRING **)pval;
347             memset(str, 0, sizeof(*str));
348             str->type = utype;
349             str->flags = ASN1_STRING_FLAG_EMBED;
350         } else {
351             str = ASN1_STRING_type_new(utype);
352             *pval = (ASN1_VALUE *)str;
353         }
354         if (it->itype == ASN1_ITYPE_MSTRING && str)
355             str->flags |= ASN1_STRING_FLAG_MSTRING;
356         break;
357     }
358     if (*pval)
359         return 1;
360     return 0;
361 }
362
363 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
364 {
365     int utype;
366     if (it && it->funcs) {
367         const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
368         if (pf->prim_clear)
369             pf->prim_clear(pval, it);
370         else
371             *pval = NULL;
372         return;
373     }
374     if (!it || (it->itype == ASN1_ITYPE_MSTRING))
375         utype = -1;
376     else
377         utype = it->utype;
378     if (utype == V_ASN1_BOOLEAN)
379         *(ASN1_BOOLEAN *)pval = it->size;
380     else
381         *pval = NULL;
382 }