Reorganize local header files
[openssl.git] / crypto / asn1 / tasn_new.c
1 /*
2  * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stddef.h>
11 #include <openssl/asn1.h>
12 #include <openssl/objects.h>
13 #include <openssl/err.h>
14 #include <openssl/asn1t.h>
15 #include <string.h>
16 #include "asn1_local.h"
17
18 static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
19                                int embed);
20 static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
21                               int embed);
22 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
23 static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
24 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
25 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
26
27 ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
28 {
29     ASN1_VALUE *ret = NULL;
30     if (ASN1_item_ex_new(&ret, it) > 0)
31         return ret;
32     return NULL;
33 }
34
35 /* Allocate an ASN1 structure */
36
37 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
38 {
39     return asn1_item_embed_new(pval, it, 0);
40 }
41
42 int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
43 {
44     const ASN1_TEMPLATE *tt = NULL;
45     const ASN1_EXTERN_FUNCS *ef;
46     const ASN1_AUX *aux = it->funcs;
47     ASN1_aux_cb *asn1_cb;
48     ASN1_VALUE **pseqval;
49     int i;
50     if (aux && aux->asn1_cb)
51         asn1_cb = aux->asn1_cb;
52     else
53         asn1_cb = 0;
54
55     switch (it->itype) {
56
57     case ASN1_ITYPE_EXTERN:
58         ef = it->funcs;
59         if (ef && ef->asn1_ex_new) {
60             if (!ef->asn1_ex_new(pval, it))
61                 goto memerr;
62         }
63         break;
64
65     case ASN1_ITYPE_PRIMITIVE:
66         if (it->templates) {
67             if (!asn1_template_new(pval, it->templates))
68                 goto memerr;
69         } else if (!asn1_primitive_new(pval, it, embed))
70             goto memerr;
71         break;
72
73     case ASN1_ITYPE_MSTRING:
74         if (!asn1_primitive_new(pval, it, embed))
75             goto memerr;
76         break;
77
78     case ASN1_ITYPE_CHOICE:
79         if (asn1_cb) {
80             i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
81             if (!i)
82                 goto auxerr;
83             if (i == 2) {
84                 return 1;
85             }
86         }
87         if (embed) {
88             memset(*pval, 0, it->size);
89         } else {
90             *pval = OPENSSL_zalloc(it->size);
91             if (*pval == NULL)
92                 goto memerr;
93         }
94         asn1_set_choice_selector(pval, -1, it);
95         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
96             goto auxerr2;
97         break;
98
99     case ASN1_ITYPE_NDEF_SEQUENCE:
100     case ASN1_ITYPE_SEQUENCE:
101         if (asn1_cb) {
102             i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
103             if (!i)
104                 goto auxerr;
105             if (i == 2) {
106                 return 1;
107             }
108         }
109         if (embed) {
110             memset(*pval, 0, it->size);
111         } else {
112             *pval = OPENSSL_zalloc(it->size);
113             if (*pval == NULL)
114                 goto memerr;
115         }
116         /* 0 : init. lock */
117         if (asn1_do_lock(pval, 0, it) < 0) {
118             if (!embed) {
119                 OPENSSL_free(*pval);
120                 *pval = NULL;
121             }
122             goto memerr;
123         }
124         asn1_enc_init(pval, it);
125         for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
126             pseqval = asn1_get_field_ptr(pval, tt);
127             if (!asn1_template_new(pseqval, tt))
128                 goto memerr2;
129         }
130         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
131             goto auxerr2;
132         break;
133     }
134     return 1;
135
136  memerr2:
137     asn1_item_embed_free(pval, it, embed);
138  memerr:
139     ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ERR_R_MALLOC_FAILURE);
140     return 0;
141
142  auxerr2:
143     asn1_item_embed_free(pval, it, embed);
144  auxerr:
145     ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ASN1_R_AUX_ERROR);
146     return 0;
147
148 }
149
150 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
151 {
152     const ASN1_EXTERN_FUNCS *ef;
153
154     switch (it->itype) {
155
156     case ASN1_ITYPE_EXTERN:
157         ef = it->funcs;
158         if (ef && ef->asn1_ex_clear)
159             ef->asn1_ex_clear(pval, it);
160         else
161             *pval = NULL;
162         break;
163
164     case ASN1_ITYPE_PRIMITIVE:
165         if (it->templates)
166             asn1_template_clear(pval, it->templates);
167         else
168             asn1_primitive_clear(pval, it);
169         break;
170
171     case ASN1_ITYPE_MSTRING:
172         asn1_primitive_clear(pval, it);
173         break;
174
175     case ASN1_ITYPE_CHOICE:
176     case ASN1_ITYPE_SEQUENCE:
177     case ASN1_ITYPE_NDEF_SEQUENCE:
178         *pval = NULL;
179         break;
180     }
181 }
182
183 static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
184 {
185     const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
186     int embed = tt->flags & ASN1_TFLG_EMBED;
187     ASN1_VALUE *tval;
188     int ret;
189     if (embed) {
190         tval = (ASN1_VALUE *)pval;
191         pval = &tval;
192     }
193     if (tt->flags & ASN1_TFLG_OPTIONAL) {
194         asn1_template_clear(pval, tt);
195         return 1;
196     }
197     /* If ANY DEFINED BY nothing to do */
198
199     if (tt->flags & ASN1_TFLG_ADB_MASK) {
200         *pval = NULL;
201         return 1;
202     }
203     /* If SET OF or SEQUENCE OF, its a STACK */
204     if (tt->flags & ASN1_TFLG_SK_MASK) {
205         STACK_OF(ASN1_VALUE) *skval;
206         skval = sk_ASN1_VALUE_new_null();
207         if (!skval) {
208             ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
209             ret = 0;
210             goto done;
211         }
212         *pval = (ASN1_VALUE *)skval;
213         ret = 1;
214         goto done;
215     }
216     /* Otherwise pass it back to the item routine */
217     ret = asn1_item_embed_new(pval, it, embed);
218  done:
219     return ret;
220 }
221
222 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
223 {
224     /* If ADB or STACK just NULL the field */
225     if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
226         *pval = NULL;
227     else
228         asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
229 }
230
231 /*
232  * NB: could probably combine most of the real XXX_new() behaviour and junk
233  * all the old functions.
234  */
235
236 static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
237                               int embed)
238 {
239     ASN1_TYPE *typ;
240     ASN1_STRING *str;
241     int utype;
242
243     if (!it)
244         return 0;
245
246     if (it->funcs) {
247         const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
248         if (embed) {
249             if (pf->prim_clear) {
250                 pf->prim_clear(pval, it);
251                 return 1;
252             }
253         } else if (pf->prim_new) {
254             return pf->prim_new(pval, it);
255         }
256     }
257
258     if (it->itype == ASN1_ITYPE_MSTRING)
259         utype = -1;
260     else
261         utype = it->utype;
262     switch (utype) {
263     case V_ASN1_OBJECT:
264         *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
265         return 1;
266
267     case V_ASN1_BOOLEAN:
268         *(ASN1_BOOLEAN *)pval = it->size;
269         return 1;
270
271     case V_ASN1_NULL:
272         *pval = (ASN1_VALUE *)1;
273         return 1;
274
275     case V_ASN1_ANY:
276         if ((typ = OPENSSL_malloc(sizeof(*typ))) == NULL) {
277             ASN1err(ASN1_F_ASN1_PRIMITIVE_NEW, ERR_R_MALLOC_FAILURE);
278             return 0;
279         }
280         typ->value.ptr = NULL;
281         typ->type = -1;
282         *pval = (ASN1_VALUE *)typ;
283         break;
284
285     default:
286         if (embed) {
287             str = *(ASN1_STRING **)pval;
288             memset(str, 0, sizeof(*str));
289             str->type = utype;
290             str->flags = ASN1_STRING_FLAG_EMBED;
291         } else {
292             str = ASN1_STRING_type_new(utype);
293             *pval = (ASN1_VALUE *)str;
294         }
295         if (it->itype == ASN1_ITYPE_MSTRING && str)
296             str->flags |= ASN1_STRING_FLAG_MSTRING;
297         break;
298     }
299     if (*pval)
300         return 1;
301     return 0;
302 }
303
304 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
305 {
306     int utype;
307     if (it && it->funcs) {
308         const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
309         if (pf->prim_clear)
310             pf->prim_clear(pval, it);
311         else
312             *pval = NULL;
313         return;
314     }
315     if (!it || (it->itype == ASN1_ITYPE_MSTRING))
316         utype = -1;
317     else
318         utype = it->utype;
319     if (utype == V_ASN1_BOOLEAN)
320         *(ASN1_BOOLEAN *)pval = it->size;
321     else
322         *pval = NULL;
323 }