Add NULL check in i2d_PrivateKey()
[openssl.git] / crypto / asn1 / tasn_new.c
1 /*
2  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3  * 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 #include <stddef.h>
60 #include <openssl/asn1.h>
61 #include <openssl/objects.h>
62 #include <openssl/err.h>
63 #include <openssl/asn1t.h>
64 #include <string.h>
65 #include "asn1_locl.h"
66
67 static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
68                                int embed);
69 static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
70                               int embed);
71 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
72 static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
73 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
74 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
75
76 ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
77 {
78     ASN1_VALUE *ret = NULL;
79     if (ASN1_item_ex_new(&ret, it) > 0)
80         return ret;
81     return NULL;
82 }
83
84 /* Allocate an ASN1 structure */
85
86 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
87 {
88     return asn1_item_embed_new(pval, it, 0);
89 }
90
91 int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
92 {
93     const ASN1_TEMPLATE *tt = NULL;
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 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
105     OPENSSL_mem_debug_push(it->sname ? it->sname : "asn1_item_embed_new");
106 #endif
107
108     switch (it->itype) {
109
110     case ASN1_ITYPE_EXTERN:
111         ef = it->funcs;
112         if (ef && ef->asn1_ex_new) {
113             if (!ef->asn1_ex_new(pval, it))
114                 goto memerr;
115         }
116         break;
117
118     case ASN1_ITYPE_PRIMITIVE:
119         if (it->templates) {
120             if (!asn1_template_new(pval, it->templates))
121                 goto memerr;
122         } else if (!asn1_primitive_new(pval, it, embed))
123             goto memerr;
124         break;
125
126     case ASN1_ITYPE_MSTRING:
127         if (!asn1_primitive_new(pval, it, embed))
128             goto memerr;
129         break;
130
131     case ASN1_ITYPE_CHOICE:
132         if (asn1_cb) {
133             i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
134             if (!i)
135                 goto auxerr;
136             if (i == 2) {
137 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
138                 OPENSSL_mem_debug_pop();
139 #endif
140                 return 1;
141             }
142         }
143         if (embed) {
144             memset(*pval, 0, it->size);
145         } else {
146             *pval = OPENSSL_zalloc(it->size);
147             if (*pval == NULL)
148                 goto memerr;
149         }
150         asn1_set_choice_selector(pval, -1, it);
151         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
152             goto auxerr;
153         break;
154
155     case ASN1_ITYPE_NDEF_SEQUENCE:
156     case ASN1_ITYPE_SEQUENCE:
157         if (asn1_cb) {
158             i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
159             if (!i)
160                 goto auxerr;
161             if (i == 2) {
162 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
163                 OPENSSL_mem_debug_pop();
164 #endif
165                 return 1;
166             }
167         }
168         if (embed) {
169             memset(*pval, 0, it->size);
170         } else {
171             *pval = OPENSSL_zalloc(it->size);
172             if (*pval == NULL)
173                 goto memerr;
174         }
175         asn1_do_lock(pval, 0, it);
176         asn1_enc_init(pval, it);
177         for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
178             pseqval = asn1_get_field_ptr(pval, tt);
179             if (!asn1_template_new(pseqval, tt))
180                 goto memerr;
181         }
182         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
183             goto auxerr;
184         break;
185     }
186 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
187     OPENSSL_mem_debug_pop();
188 #endif
189     return 1;
190
191  memerr:
192     ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ERR_R_MALLOC_FAILURE);
193 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
194     OPENSSL_mem_debug_pop();
195 #endif
196     return 0;
197
198  auxerr:
199     ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ASN1_R_AUX_ERROR);
200     ASN1_item_ex_free(pval, it);
201 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
202     OPENSSL_mem_debug_pop();
203 #endif
204     return 0;
205
206 }
207
208 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
209 {
210     const ASN1_EXTERN_FUNCS *ef;
211
212     switch (it->itype) {
213
214     case ASN1_ITYPE_EXTERN:
215         ef = it->funcs;
216         if (ef && ef->asn1_ex_clear)
217             ef->asn1_ex_clear(pval, it);
218         else
219             *pval = NULL;
220         break;
221
222     case ASN1_ITYPE_PRIMITIVE:
223         if (it->templates)
224             asn1_template_clear(pval, it->templates);
225         else
226             asn1_primitive_clear(pval, it);
227         break;
228
229     case ASN1_ITYPE_MSTRING:
230         asn1_primitive_clear(pval, it);
231         break;
232
233     case ASN1_ITYPE_CHOICE:
234     case ASN1_ITYPE_SEQUENCE:
235     case ASN1_ITYPE_NDEF_SEQUENCE:
236         *pval = NULL;
237         break;
238     }
239 }
240
241 static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
242 {
243     const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
244     int embed = tt->flags & ASN1_TFLG_EMBED;
245     ASN1_VALUE *tval;
246     int ret;
247     if (embed) {
248         tval = (ASN1_VALUE *)pval;
249         pval = &tval;
250     }
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 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
262     OPENSSL_mem_debug_push(tt->field_name
263             ? tt->field_name : "asn1_template_new");
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_embed_new(pval, it, embed);
280  done:
281 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
282     OPENSSL_mem_debug_pop();
283 #endif
284     return ret;
285 }
286
287 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
288 {
289     /* If ADB or STACK just NULL the field */
290     if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
291         *pval = NULL;
292     else
293         asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
294 }
295
296 /*
297  * NB: could probably combine most of the real XXX_new() behaviour and junk
298  * all the old functions.
299  */
300
301 static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
302                               int embed)
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(*typ));
336         if (typ == NULL)
337             return 0;
338         typ->value.ptr = NULL;
339         typ->type = -1;
340         *pval = (ASN1_VALUE *)typ;
341         break;
342
343     default:
344         if (embed) {
345             str = *(ASN1_STRING **)pval;
346             memset(str, 0, sizeof(*str));
347             str->type = utype;
348             str->flags = ASN1_STRING_FLAG_EMBED;
349         } else {
350             str = ASN1_STRING_type_new(utype);
351             *pval = (ASN1_VALUE *)str;
352         }
353         if (it->itype == ASN1_ITYPE_MSTRING && str)
354             str->flags |= ASN1_STRING_FLAG_MSTRING;
355         break;
356     }
357     if (*pval)
358         return 1;
359     return 0;
360 }
361
362 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
363 {
364     int utype;
365     if (it && it->funcs) {
366         const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
367         if (pf->prim_clear)
368             pf->prim_clear(pval, it);
369         else
370             *pval = NULL;
371         return;
372     }
373     if (!it || (it->itype == ASN1_ITYPE_MSTRING))
374         utype = -1;
375     else
376         utype = it->utype;
377     if (utype == V_ASN1_BOOLEAN)
378         *(ASN1_BOOLEAN *)pval = it->size;
379     else
380         *pval = NULL;
381 }