/src/boringssl/crypto/asn1/tasn_new.cc
Line | Count | Source |
1 | | // Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include <openssl/asn1.h> |
16 | | |
17 | | #include <string.h> |
18 | | |
19 | | #include <openssl/asn1t.h> |
20 | | #include <openssl/err.h> |
21 | | #include <openssl/mem.h> |
22 | | #include <openssl/obj.h> |
23 | | |
24 | | #include "../internal.h" |
25 | | #include "../mem_internal.h" |
26 | | #include "internal.h" |
27 | | |
28 | | |
29 | | using namespace bssl; |
30 | | |
31 | | static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); |
32 | | static int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); |
33 | | static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); |
34 | | static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it); |
35 | | static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); |
36 | | |
37 | 618k | ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) { |
38 | 618k | ASN1_VALUE *ret = nullptr; |
39 | 618k | if (ASN1_item_ex_new(&ret, it) > 0) { |
40 | 618k | return ret; |
41 | 618k | } |
42 | 0 | return nullptr; |
43 | 618k | } |
44 | | |
45 | | // Allocate an ASN1 structure |
46 | | |
47 | 2.36M | int bssl::ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { |
48 | 2.36M | const ASN1_TEMPLATE *tt = nullptr; |
49 | 2.36M | const ASN1_EXTERN_FUNCS *ef; |
50 | 2.36M | ASN1_VALUE **pseqval; |
51 | 2.36M | int i; |
52 | | |
53 | 2.36M | switch (it->itype) { |
54 | 0 | case ASN1_ITYPE_EXTERN: |
55 | 0 | ef = reinterpret_cast<const ASN1_EXTERN_FUNCS *>(it->funcs); |
56 | 0 | if (ef && ef->asn1_ex_new) { |
57 | 0 | if (!ef->asn1_ex_new(pval, it)) { |
58 | 0 | goto memerr; |
59 | 0 | } |
60 | 0 | } |
61 | 0 | break; |
62 | | |
63 | 1.42M | case ASN1_ITYPE_PRIMITIVE: |
64 | 1.42M | if (it->templates) { |
65 | 1.84k | if (!ASN1_template_new(pval, it->templates)) { |
66 | 0 | goto memerr; |
67 | 0 | } |
68 | 1.41M | } else if (!ASN1_primitive_new(pval, it)) { |
69 | 0 | goto memerr; |
70 | 0 | } |
71 | 1.42M | break; |
72 | | |
73 | 1.42M | case ASN1_ITYPE_MSTRING: |
74 | 2.05k | if (!ASN1_primitive_new(pval, it)) { |
75 | 0 | goto memerr; |
76 | 0 | } |
77 | 2.05k | break; |
78 | | |
79 | 349k | case ASN1_ITYPE_CHOICE: { |
80 | 349k | const ASN1_AUX *aux = reinterpret_cast<const ASN1_AUX *>(it->funcs); |
81 | 349k | ASN1_aux_cb *asn1_cb = aux != nullptr ? aux->asn1_cb : nullptr; |
82 | 349k | if (asn1_cb) { |
83 | 43.9k | i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, nullptr); |
84 | 43.9k | if (!i) { |
85 | 0 | goto auxerr; |
86 | 0 | } |
87 | 43.9k | if (i == 2) { |
88 | 0 | return 1; |
89 | 0 | } |
90 | 43.9k | } |
91 | 349k | *pval = reinterpret_cast<ASN1_VALUE *>(OPENSSL_zalloc(it->size)); |
92 | 349k | if (!*pval) { |
93 | 0 | goto memerr; |
94 | 0 | } |
95 | 349k | asn1_set_choice_selector(pval, -1, it); |
96 | 349k | if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, nullptr)) { |
97 | 0 | goto auxerr2; |
98 | 0 | } |
99 | 349k | break; |
100 | 349k | } |
101 | | |
102 | 588k | case ASN1_ITYPE_SEQUENCE: { |
103 | 588k | const ASN1_AUX *aux = reinterpret_cast<const ASN1_AUX *>(it->funcs); |
104 | 588k | ASN1_aux_cb *asn1_cb = aux != nullptr ? aux->asn1_cb : nullptr; |
105 | 588k | if (asn1_cb) { |
106 | 0 | i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, nullptr); |
107 | 0 | if (!i) { |
108 | 0 | goto auxerr; |
109 | 0 | } |
110 | 0 | if (i == 2) { |
111 | 0 | return 1; |
112 | 0 | } |
113 | 0 | } |
114 | 588k | *pval = reinterpret_cast<ASN1_VALUE *>(OPENSSL_zalloc(it->size)); |
115 | 588k | if (!*pval) { |
116 | 0 | goto memerr; |
117 | 0 | } |
118 | 588k | asn1_refcount_set_one(pval, it); |
119 | 588k | asn1_enc_init(pval, it); |
120 | 2.28M | for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { |
121 | 1.70M | pseqval = asn1_get_field_ptr(pval, tt); |
122 | 1.70M | if (!ASN1_template_new(pseqval, tt)) { |
123 | 0 | goto memerr2; |
124 | 0 | } |
125 | 1.70M | } |
126 | 588k | if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, nullptr)) { |
127 | 0 | goto auxerr2; |
128 | 0 | } |
129 | 588k | break; |
130 | 588k | } |
131 | 2.36M | } |
132 | 2.36M | return 1; |
133 | | |
134 | 0 | memerr2: |
135 | 0 | ASN1_item_ex_free(pval, it); |
136 | 0 | memerr: |
137 | 0 | return 0; |
138 | | |
139 | 0 | auxerr2: |
140 | 0 | ASN1_item_ex_free(pval, it); |
141 | 0 | auxerr: |
142 | 0 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); |
143 | 0 | return 0; |
144 | 0 | } |
145 | | |
146 | 595k | static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) { |
147 | 595k | switch (it->itype) { |
148 | 0 | case ASN1_ITYPE_EXTERN: |
149 | 0 | *pval = nullptr; |
150 | 0 | break; |
151 | | |
152 | 534k | case ASN1_ITYPE_PRIMITIVE: |
153 | 534k | if (it->templates) { |
154 | 0 | asn1_template_clear(pval, it->templates); |
155 | 534k | } else { |
156 | 534k | asn1_primitive_clear(pval, it); |
157 | 534k | } |
158 | 534k | break; |
159 | | |
160 | 3.70k | case ASN1_ITYPE_MSTRING: |
161 | 3.70k | asn1_primitive_clear(pval, it); |
162 | 3.70k | break; |
163 | | |
164 | 53.3k | case ASN1_ITYPE_CHOICE: |
165 | 56.6k | case ASN1_ITYPE_SEQUENCE: |
166 | 56.6k | *pval = nullptr; |
167 | 56.6k | break; |
168 | 595k | } |
169 | 595k | } |
170 | | |
171 | 1.70M | static int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { |
172 | 1.70M | const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); |
173 | 1.70M | int ret; |
174 | 1.70M | if (tt->flags & ASN1_TFLG_OPTIONAL) { |
175 | 655k | asn1_template_clear(pval, tt); |
176 | 655k | return 1; |
177 | 655k | } |
178 | | // If ANY DEFINED BY nothing to do |
179 | | |
180 | 1.04M | if (tt->flags & ASN1_TFLG_ADB_MASK) { |
181 | 7.06k | *pval = nullptr; |
182 | 7.06k | return 1; |
183 | 7.06k | } |
184 | | // If SET OF or SEQUENCE OF, its a STACK |
185 | 1.04M | if (tt->flags & ASN1_TFLG_SK_MASK) { |
186 | 3.47k | STACK_OF(ASN1_VALUE) *skval; |
187 | 3.47k | skval = sk_ASN1_VALUE_new_null(); |
188 | 3.47k | if (!skval) { |
189 | 0 | ret = 0; |
190 | 0 | goto done; |
191 | 0 | } |
192 | 3.47k | *pval = (ASN1_VALUE *)skval; |
193 | 3.47k | ret = 1; |
194 | 3.47k | goto done; |
195 | 3.47k | } |
196 | | // Otherwise pass it back to the item routine |
197 | 1.03M | ret = ASN1_item_ex_new(pval, it); |
198 | 1.04M | done: |
199 | 1.04M | return ret; |
200 | 1.03M | } |
201 | | |
202 | 655k | static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { |
203 | | // If ADB or STACK just NULL the field |
204 | 655k | if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK)) { |
205 | 60.1k | *pval = nullptr; |
206 | 595k | } else { |
207 | 595k | asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); |
208 | 595k | } |
209 | 655k | } |
210 | | |
211 | | // NB: could probably combine most of the real XXX_new() behaviour and junk |
212 | | // all the old functions. |
213 | | |
214 | 1.42M | static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { |
215 | 1.42M | if (!it) { |
216 | 0 | return 0; |
217 | 0 | } |
218 | | |
219 | | // Historically, |it->funcs| for primitive types contained an |
220 | | // |ASN1_PRIMITIVE_FUNCS| table of callbacks. |
221 | 1.42M | assert(it->funcs == nullptr); |
222 | | |
223 | 1.42M | int utype; |
224 | 1.42M | if (it->itype == ASN1_ITYPE_MSTRING) { |
225 | 2.05k | utype = -1; |
226 | 1.41M | } else { |
227 | 1.41M | utype = it->utype; |
228 | 1.41M | } |
229 | 1.42M | switch (utype) { |
230 | 523k | case V_ASN1_OBJECT: |
231 | 523k | *pval = (ASN1_VALUE *)OBJ_get_undef(); |
232 | 523k | return 1; |
233 | | |
234 | 0 | case V_ASN1_BOOLEAN: |
235 | 0 | *(ASN1_BOOLEAN *)pval = (ASN1_BOOLEAN)it->size; |
236 | 0 | return 1; |
237 | | |
238 | 33 | case V_ASN1_NULL: |
239 | 33 | *pval = (ASN1_VALUE *)1; |
240 | 33 | return 1; |
241 | | |
242 | 432k | case V_ASN1_ANY: { |
243 | 432k | ASN1_TYPE *typ = New<ASN1_TYPE>(); |
244 | 432k | if (!typ) { |
245 | 0 | return 0; |
246 | 0 | } |
247 | 432k | typ->value.ptr = nullptr; |
248 | 432k | typ->type = -1; |
249 | 432k | *pval = (ASN1_VALUE *)typ; |
250 | 432k | break; |
251 | 432k | } |
252 | | |
253 | 464k | default: |
254 | 464k | *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); |
255 | 464k | break; |
256 | 1.42M | } |
257 | 896k | if (*pval) { |
258 | 896k | return 1; |
259 | 896k | } |
260 | 0 | return 0; |
261 | 896k | } |
262 | | |
263 | 538k | static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) { |
264 | 538k | int utype; |
265 | | // Historically, |it->funcs| for primitive types contained an |
266 | | // |ASN1_PRIMITIVE_FUNCS| table of callbacks. |
267 | 538k | assert(it == nullptr || it->funcs == nullptr); |
268 | 538k | if (!it || (it->itype == ASN1_ITYPE_MSTRING)) { |
269 | 3.70k | utype = -1; |
270 | 534k | } else { |
271 | 534k | utype = it->utype; |
272 | 534k | } |
273 | 538k | if (utype == V_ASN1_BOOLEAN) { |
274 | 470k | *(ASN1_BOOLEAN *)pval = (ASN1_BOOLEAN)it->size; |
275 | 470k | } else { |
276 | 67.7k | *pval = nullptr; |
277 | 67.7k | } |
278 | 538k | } |