xref: /aosp_15_r20/external/boringssl/src/crypto/asn1/tasn_new.c (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1 /* Copyright (C) 1995-1998 Eric Young ([email protected])
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young ([email protected]).
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 ([email protected]).
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 ([email protected])"
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 ([email protected])"
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 "../internal.h"
67 #include "internal.h"
68 
69 
70 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
71 static int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
72 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
73 static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
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   ASN1_VALUE *ret = NULL;
78   if (ASN1_item_ex_new(&ret, it) > 0) {
79     return ret;
80   }
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   const ASN1_TEMPLATE *tt = NULL;
88   const ASN1_EXTERN_FUNCS *ef;
89   ASN1_VALUE **pseqval;
90   int i;
91 
92   switch (it->itype) {
93     case ASN1_ITYPE_EXTERN:
94       ef = it->funcs;
95       if (ef && ef->asn1_ex_new) {
96         if (!ef->asn1_ex_new(pval, it)) {
97           goto memerr;
98         }
99       }
100       break;
101 
102     case ASN1_ITYPE_PRIMITIVE:
103       if (it->templates) {
104         if (!ASN1_template_new(pval, it->templates)) {
105           goto memerr;
106         }
107       } else if (!ASN1_primitive_new(pval, it)) {
108         goto memerr;
109       }
110       break;
111 
112     case ASN1_ITYPE_MSTRING:
113       if (!ASN1_primitive_new(pval, it)) {
114         goto memerr;
115       }
116       break;
117 
118     case ASN1_ITYPE_CHOICE: {
119       const ASN1_AUX *aux = it->funcs;
120       ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
121       if (asn1_cb) {
122         i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
123         if (!i) {
124           goto auxerr;
125         }
126         if (i == 2) {
127           return 1;
128         }
129       }
130       *pval = OPENSSL_zalloc(it->size);
131       if (!*pval) {
132         goto memerr;
133       }
134       asn1_set_choice_selector(pval, -1, it);
135       if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) {
136         goto auxerr2;
137       }
138       break;
139     }
140 
141     case ASN1_ITYPE_SEQUENCE: {
142       const ASN1_AUX *aux = it->funcs;
143       ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
144       if (asn1_cb) {
145         i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
146         if (!i) {
147           goto auxerr;
148         }
149         if (i == 2) {
150           return 1;
151         }
152       }
153       *pval = OPENSSL_zalloc(it->size);
154       if (!*pval) {
155         goto memerr;
156       }
157       asn1_refcount_set_one(pval, it);
158       asn1_enc_init(pval, it);
159       for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
160         pseqval = asn1_get_field_ptr(pval, tt);
161         if (!ASN1_template_new(pseqval, tt)) {
162           goto memerr2;
163         }
164       }
165       if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) {
166         goto auxerr2;
167       }
168       break;
169     }
170   }
171   return 1;
172 
173 memerr2:
174   ASN1_item_ex_free(pval, it);
175 memerr:
176   return 0;
177 
178 auxerr2:
179   ASN1_item_ex_free(pval, it);
180 auxerr:
181   OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
182   return 0;
183 }
184 
asn1_item_clear(ASN1_VALUE ** pval,const ASN1_ITEM * it)185 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) {
186   switch (it->itype) {
187     case ASN1_ITYPE_EXTERN:
188       *pval = NULL;
189       break;
190 
191     case ASN1_ITYPE_PRIMITIVE:
192       if (it->templates) {
193         asn1_template_clear(pval, it->templates);
194       } else {
195         asn1_primitive_clear(pval, it);
196       }
197       break;
198 
199     case ASN1_ITYPE_MSTRING:
200       asn1_primitive_clear(pval, it);
201       break;
202 
203     case ASN1_ITYPE_CHOICE:
204     case ASN1_ITYPE_SEQUENCE:
205       *pval = NULL;
206       break;
207   }
208 }
209 
ASN1_template_new(ASN1_VALUE ** pval,const ASN1_TEMPLATE * tt)210 static int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) {
211   const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
212   int ret;
213   if (tt->flags & ASN1_TFLG_OPTIONAL) {
214     asn1_template_clear(pval, tt);
215     return 1;
216   }
217   // If ANY DEFINED BY nothing to do
218 
219   if (tt->flags & ASN1_TFLG_ADB_MASK) {
220     *pval = NULL;
221     return 1;
222   }
223   // If SET OF or SEQUENCE OF, its a STACK
224   if (tt->flags & ASN1_TFLG_SK_MASK) {
225     STACK_OF(ASN1_VALUE) *skval;
226     skval = sk_ASN1_VALUE_new_null();
227     if (!skval) {
228       ret = 0;
229       goto done;
230     }
231     *pval = (ASN1_VALUE *)skval;
232     ret = 1;
233     goto done;
234   }
235   // Otherwise pass it back to the item routine
236   ret = ASN1_item_ex_new(pval, it);
237 done:
238   return ret;
239 }
240 
asn1_template_clear(ASN1_VALUE ** pval,const ASN1_TEMPLATE * tt)241 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) {
242   // If ADB or STACK just NULL the field
243   if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK)) {
244     *pval = NULL;
245   } else {
246     asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
247   }
248 }
249 
250 // NB: could probably combine most of the real XXX_new() behaviour and junk
251 // all the old functions.
252 
ASN1_primitive_new(ASN1_VALUE ** pval,const ASN1_ITEM * it)253 static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) {
254   if (!it) {
255     return 0;
256   }
257 
258   // Historically, |it->funcs| for primitive types contained an
259   // |ASN1_PRIMITIVE_FUNCS| table of calbacks.
260   assert(it->funcs == NULL);
261 
262   int utype;
263   if (it->itype == ASN1_ITYPE_MSTRING) {
264     utype = -1;
265   } else {
266     utype = it->utype;
267   }
268   switch (utype) {
269     case V_ASN1_OBJECT:
270       *pval = (ASN1_VALUE *)OBJ_get_undef();
271       return 1;
272 
273     case V_ASN1_BOOLEAN:
274       *(ASN1_BOOLEAN *)pval = (ASN1_BOOLEAN)it->size;
275       return 1;
276 
277     case V_ASN1_NULL:
278       *pval = (ASN1_VALUE *)1;
279       return 1;
280 
281     case V_ASN1_ANY: {
282       ASN1_TYPE *typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
283       if (!typ) {
284         return 0;
285       }
286       typ->value.ptr = NULL;
287       typ->type = -1;
288       *pval = (ASN1_VALUE *)typ;
289       break;
290     }
291 
292     default:
293       *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype);
294       break;
295   }
296   if (*pval) {
297     return 1;
298   }
299   return 0;
300 }
301 
asn1_primitive_clear(ASN1_VALUE ** pval,const ASN1_ITEM * it)302 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) {
303   int utype;
304   // Historically, |it->funcs| for primitive types contained an
305   // |ASN1_PRIMITIVE_FUNCS| table of calbacks.
306   assert(it == NULL || it->funcs == NULL);
307   if (!it || (it->itype == ASN1_ITYPE_MSTRING)) {
308     utype = -1;
309   } else {
310     utype = it->utype;
311   }
312   if (utype == V_ASN1_BOOLEAN) {
313     *(ASN1_BOOLEAN *)pval = (ASN1_BOOLEAN)it->size;
314   } else {
315     *pval = NULL;
316   }
317 }
318