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