1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/asn1.h>
58 
59 #include <string.h>
60 
61 #include <openssl/asn1t.h>
62 #include <openssl/err.h>
63 #include <openssl/mem.h>
64 #include <openssl/obj.h>
65 
66 #include "asn1_locl.h"
67 #include "../internal.h"
68 
69 
70 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
71                                     int combine);
72 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
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 
ASN1_item_new(const ASN1_ITEM * it)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 
ASN1_item_ex_new(ASN1_VALUE ** pval,const ASN1_ITEM * it)86 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
87 {
88     return asn1_item_ex_combine_new(pval, it, 0);
89 }
90 
asn1_item_ex_combine_new(ASN1_VALUE ** pval,const ASN1_ITEM * it,int combine)91 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
92                                     int combine)
93 {
94     const ASN1_TEMPLATE *tt = NULL;
95     const ASN1_COMPAT_FUNCS *cf;
96     const ASN1_EXTERN_FUNCS *ef;
97     const ASN1_AUX *aux = it->funcs;
98     ASN1_aux_cb *asn1_cb;
99     ASN1_VALUE **pseqval;
100     int i;
101     if (aux && aux->asn1_cb)
102         asn1_cb = aux->asn1_cb;
103     else
104         asn1_cb = 0;
105 
106 #ifdef CRYPTO_MDEBUG
107     if (it->sname)
108         CRYPTO_push_info(it->sname);
109 #endif
110 
111     switch (it->itype) {
112 
113     case ASN1_ITYPE_EXTERN:
114         ef = it->funcs;
115         if (ef && ef->asn1_ex_new) {
116             if (!ef->asn1_ex_new(pval, it))
117                 goto memerr;
118         }
119         break;
120 
121     case ASN1_ITYPE_COMPAT:
122         cf = it->funcs;
123         if (cf && cf->asn1_new) {
124             *pval = cf->asn1_new();
125             if (!*pval)
126                 goto memerr;
127         }
128         break;
129 
130     case ASN1_ITYPE_PRIMITIVE:
131         if (it->templates) {
132             if (!ASN1_template_new(pval, it->templates))
133                 goto memerr;
134         } else if (!ASN1_primitive_new(pval, it))
135             goto memerr;
136         break;
137 
138     case ASN1_ITYPE_MSTRING:
139         if (!ASN1_primitive_new(pval, it))
140             goto memerr;
141         break;
142 
143     case ASN1_ITYPE_CHOICE:
144         if (asn1_cb) {
145             i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
146             if (!i)
147                 goto auxerr;
148             if (i == 2) {
149 #ifdef CRYPTO_MDEBUG
150                 if (it->sname)
151                     CRYPTO_pop_info();
152 #endif
153                 return 1;
154             }
155         }
156         if (!combine) {
157             *pval = OPENSSL_malloc(it->size);
158             if (!*pval)
159                 goto memerr;
160             OPENSSL_memset(*pval, 0, it->size);
161         }
162         asn1_set_choice_selector(pval, -1, it);
163         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
164             goto auxerr2;
165         break;
166 
167     case ASN1_ITYPE_NDEF_SEQUENCE:
168     case ASN1_ITYPE_SEQUENCE:
169         if (asn1_cb) {
170             i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
171             if (!i)
172                 goto auxerr;
173             if (i == 2) {
174 #ifdef CRYPTO_MDEBUG
175                 if (it->sname)
176                     CRYPTO_pop_info();
177 #endif
178                 return 1;
179             }
180         }
181         if (!combine) {
182             *pval = OPENSSL_malloc(it->size);
183             if (!*pval)
184                 goto memerr;
185             OPENSSL_memset(*pval, 0, it->size);
186             asn1_refcount_set_one(pval, it);
187             asn1_enc_init(pval, it);
188         }
189         for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
190             pseqval = asn1_get_field_ptr(pval, tt);
191             if (!ASN1_template_new(pseqval, tt))
192                 goto memerr2;
193         }
194         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
195             goto auxerr2;
196         break;
197     }
198 #ifdef CRYPTO_MDEBUG
199     if (it->sname)
200         CRYPTO_pop_info();
201 #endif
202     return 1;
203 
204  memerr2:
205     asn1_item_combine_free(pval, it, combine);
206  memerr:
207     OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
208 #ifdef CRYPTO_MDEBUG
209     if (it->sname)
210         CRYPTO_pop_info();
211 #endif
212     return 0;
213 
214  auxerr2:
215     asn1_item_combine_free(pval, it, combine);
216  auxerr:
217     OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
218 #ifdef CRYPTO_MDEBUG
219     if (it->sname)
220         CRYPTO_pop_info();
221 #endif
222     return 0;
223 
224 }
225 
asn1_item_clear(ASN1_VALUE ** pval,const ASN1_ITEM * it)226 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
227 {
228     const ASN1_EXTERN_FUNCS *ef;
229 
230     switch (it->itype) {
231 
232     case ASN1_ITYPE_EXTERN:
233         ef = it->funcs;
234         if (ef && ef->asn1_ex_clear)
235             ef->asn1_ex_clear(pval, it);
236         else
237             *pval = NULL;
238         break;
239 
240     case ASN1_ITYPE_PRIMITIVE:
241         if (it->templates)
242             asn1_template_clear(pval, it->templates);
243         else
244             asn1_primitive_clear(pval, it);
245         break;
246 
247     case ASN1_ITYPE_MSTRING:
248         asn1_primitive_clear(pval, it);
249         break;
250 
251     case ASN1_ITYPE_COMPAT:
252     case ASN1_ITYPE_CHOICE:
253     case ASN1_ITYPE_SEQUENCE:
254     case ASN1_ITYPE_NDEF_SEQUENCE:
255         *pval = NULL;
256         break;
257     }
258 }
259 
ASN1_template_new(ASN1_VALUE ** pval,const ASN1_TEMPLATE * tt)260 int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
261 {
262     const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
263     int ret;
264     if (tt->flags & ASN1_TFLG_OPTIONAL) {
265         asn1_template_clear(pval, tt);
266         return 1;
267     }
268     /* If ANY DEFINED BY nothing to do */
269 
270     if (tt->flags & ASN1_TFLG_ADB_MASK) {
271         *pval = NULL;
272         return 1;
273     }
274 #ifdef CRYPTO_MDEBUG
275     if (tt->field_name)
276         CRYPTO_push_info(tt->field_name);
277 #endif
278     /* If SET OF or SEQUENCE OF, its a STACK */
279     if (tt->flags & ASN1_TFLG_SK_MASK) {
280         STACK_OF(ASN1_VALUE) *skval;
281         skval = sk_ASN1_VALUE_new_null();
282         if (!skval) {
283             OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
284             ret = 0;
285             goto done;
286         }
287         *pval = (ASN1_VALUE *)skval;
288         ret = 1;
289         goto done;
290     }
291     /* Otherwise pass it back to the item routine */
292     ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
293  done:
294 #ifdef CRYPTO_MDEBUG
295     if (it->sname)
296         CRYPTO_pop_info();
297 #endif
298     return ret;
299 }
300 
asn1_template_clear(ASN1_VALUE ** pval,const ASN1_TEMPLATE * tt)301 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
302 {
303     /* If ADB or STACK just NULL the field */
304     if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
305         *pval = NULL;
306     else
307         asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
308 }
309 
310 /*
311  * NB: could probably combine most of the real XXX_new() behaviour and junk
312  * all the old functions.
313  */
314 
ASN1_primitive_new(ASN1_VALUE ** pval,const ASN1_ITEM * it)315 int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
316 {
317     ASN1_TYPE *typ;
318     ASN1_STRING *str;
319     int utype;
320 
321     if (!it)
322         return 0;
323 
324     if (it->funcs) {
325         const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
326         if (pf->prim_new)
327             return pf->prim_new(pval, it);
328     }
329 
330     if (it->itype == ASN1_ITYPE_MSTRING)
331         utype = -1;
332     else
333         utype = it->utype;
334     switch (utype) {
335     case V_ASN1_OBJECT:
336         *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
337         return 1;
338 
339     case V_ASN1_BOOLEAN:
340         *(ASN1_BOOLEAN *)pval = it->size;
341         return 1;
342 
343     case V_ASN1_NULL:
344         *pval = (ASN1_VALUE *)1;
345         return 1;
346 
347     case V_ASN1_ANY:
348         typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
349         if (!typ)
350             return 0;
351         typ->value.ptr = NULL;
352         typ->type = -1;
353         *pval = (ASN1_VALUE *)typ;
354         break;
355 
356     default:
357         str = ASN1_STRING_type_new(utype);
358         if (it->itype == ASN1_ITYPE_MSTRING && str)
359             str->flags |= ASN1_STRING_FLAG_MSTRING;
360         *pval = (ASN1_VALUE *)str;
361         break;
362     }
363     if (*pval)
364         return 1;
365     return 0;
366 }
367 
asn1_primitive_clear(ASN1_VALUE ** pval,const ASN1_ITEM * it)368 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
369 {
370     int utype;
371     if (it && it->funcs) {
372         const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
373         if (pf->prim_clear)
374             pf->prim_clear(pval, it);
375         else
376             *pval = NULL;
377         return;
378     }
379     if (!it || (it->itype == ASN1_ITYPE_MSTRING))
380         utype = -1;
381     else
382         utype = it->utype;
383     if (utype == V_ASN1_BOOLEAN)
384         *(ASN1_BOOLEAN *)pval = it->size;
385     else
386         *pval = NULL;
387 }
388