|
1 /* tasn_new.c */ |
|
2 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 EXPORT_C 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 } |