diff options
Diffstat (limited to 'src/lib/libcrypto/asn1/tasn_dec.c')
-rw-r--r-- | src/lib/libcrypto/asn1/tasn_dec.c | 1260 |
1 files changed, 0 insertions, 1260 deletions
diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c deleted file mode 100644 index 31b9efee54..0000000000 --- a/src/lib/libcrypto/asn1/tasn_dec.c +++ /dev/null | |||
@@ -1,1260 +0,0 @@ | |||
1 | /* $OpenBSD: tasn_dec.c,v 1.88 2023/07/28 10:00:10 tb Exp $ */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000-2005 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 | #include <limits.h> | ||
60 | #include <stddef.h> | ||
61 | #include <string.h> | ||
62 | |||
63 | #include <openssl/asn1.h> | ||
64 | #include <openssl/asn1t.h> | ||
65 | #include <openssl/buffer.h> | ||
66 | #include <openssl/err.h> | ||
67 | #include <openssl/objects.h> | ||
68 | |||
69 | #include "asn1_local.h" | ||
70 | #include "bytestring.h" | ||
71 | |||
72 | /* | ||
73 | * Constructed types with a recursive definition (such as can be found in PKCS7) | ||
74 | * could eventually exceed the stack given malicious input with excessive | ||
75 | * recursion. Therefore we limit the stack depth. | ||
76 | */ | ||
77 | #define ASN1_MAX_CONSTRUCTED_NEST 30 | ||
78 | |||
79 | #ifndef ASN1_MAX_STRING_NEST | ||
80 | /* | ||
81 | * This determines how many levels of recursion are permitted in ASN.1 string | ||
82 | * types. If it is not limited stack overflows can occur. If set to zero no | ||
83 | * recursion is allowed at all. | ||
84 | */ | ||
85 | #define ASN1_MAX_STRING_NEST 5 | ||
86 | #endif | ||
87 | |||
88 | static int asn1_template_d2i(ASN1_VALUE **pval, CBS *cbs, | ||
89 | const ASN1_TEMPLATE *at, int optional, int depth); | ||
90 | |||
91 | static int | ||
92 | asn1_check_eoc(CBS *cbs) | ||
93 | { | ||
94 | uint16_t eoc; | ||
95 | |||
96 | if (!CBS_peek_u16(cbs, &eoc)) | ||
97 | return 0; | ||
98 | if (eoc != 0) | ||
99 | return 0; | ||
100 | |||
101 | return CBS_skip(cbs, 2); | ||
102 | } | ||
103 | |||
104 | static int | ||
105 | asn1_check_tag(CBS *cbs, size_t *out_len, int *out_tag, uint8_t *out_class, | ||
106 | int *out_indefinite, int *out_constructed, int expected_tag, | ||
107 | int expected_class, int optional) | ||
108 | { | ||
109 | int constructed, indefinite; | ||
110 | uint32_t tag_number; | ||
111 | uint8_t tag_class; | ||
112 | size_t length; | ||
113 | |||
114 | if (out_len != NULL) | ||
115 | *out_len = 0; | ||
116 | if (out_tag != NULL) | ||
117 | *out_tag = 0; | ||
118 | if (out_class != NULL) | ||
119 | *out_class = 0; | ||
120 | if (out_indefinite != NULL) | ||
121 | *out_indefinite = 0; | ||
122 | if (out_constructed != NULL) | ||
123 | *out_constructed = 0; | ||
124 | |||
125 | if (!asn1_get_identifier_cbs(cbs, 0, &tag_class, &constructed, | ||
126 | &tag_number)) { | ||
127 | ASN1error(ASN1_R_BAD_OBJECT_HEADER); | ||
128 | return 0; | ||
129 | } | ||
130 | if (expected_tag >= 0) { | ||
131 | if (expected_tag != tag_number || | ||
132 | expected_class != tag_class << 6) { | ||
133 | /* Indicate missing type if this is OPTIONAL. */ | ||
134 | if (optional) | ||
135 | return -1; | ||
136 | |||
137 | ASN1error(ASN1_R_WRONG_TAG); | ||
138 | return 0; | ||
139 | } | ||
140 | } | ||
141 | if (!asn1_get_length_cbs(cbs, 0, &indefinite, &length)) { | ||
142 | ASN1error(ASN1_R_BAD_OBJECT_HEADER); | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | /* Indefinite length can only be used with constructed encoding. */ | ||
147 | if (indefinite && !constructed) { | ||
148 | ASN1error(ASN1_R_BAD_OBJECT_HEADER); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | if (!indefinite && CBS_len(cbs) < length) { | ||
153 | ASN1error(ASN1_R_TOO_LONG); | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | if (tag_number > INT_MAX) { | ||
158 | ASN1error(ASN1_R_TOO_LONG); | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | if (indefinite) | ||
163 | length = CBS_len(cbs); | ||
164 | |||
165 | if (out_len != NULL) | ||
166 | *out_len = length; | ||
167 | if (out_tag != NULL) | ||
168 | *out_tag = tag_number; | ||
169 | if (out_class != NULL) | ||
170 | *out_class = tag_class << 6; | ||
171 | if (out_indefinite != NULL) | ||
172 | *out_indefinite = indefinite; | ||
173 | if (out_constructed != NULL) | ||
174 | *out_constructed = constructed; | ||
175 | |||
176 | return 1; | ||
177 | } | ||
178 | |||
179 | /* Collect the contents from a constructed ASN.1 object. */ | ||
180 | static int | ||
181 | asn1_collect(CBB *cbb, CBS *cbs, int indefinite, int expected_tag, | ||
182 | int expected_class, int depth) | ||
183 | { | ||
184 | int constructed; | ||
185 | size_t length; | ||
186 | CBS content; | ||
187 | int need_eoc; | ||
188 | |||
189 | if (depth > ASN1_MAX_STRING_NEST) { | ||
190 | ASN1error(ASN1_R_NESTED_ASN1_STRING); | ||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | need_eoc = indefinite; | ||
195 | |||
196 | while (CBS_len(cbs) > 0) { | ||
197 | if (asn1_check_eoc(cbs)) { | ||
198 | if (!need_eoc) { | ||
199 | ASN1error(ASN1_R_UNEXPECTED_EOC); | ||
200 | return 0; | ||
201 | } | ||
202 | return 1; | ||
203 | } | ||
204 | if (!asn1_check_tag(cbs, &length, NULL, NULL, &indefinite, | ||
205 | &constructed, expected_tag, expected_class, 0)) { | ||
206 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | if (constructed) { | ||
211 | if (!asn1_collect(cbb, cbs, indefinite, expected_tag, | ||
212 | expected_class, depth + 1)) | ||
213 | return 0; | ||
214 | continue; | ||
215 | } | ||
216 | |||
217 | if (!CBS_get_bytes(cbs, &content, length)) { | ||
218 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
219 | return 0; | ||
220 | } | ||
221 | if (!CBB_add_bytes(cbb, CBS_data(&content), CBS_len(&content))) | ||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | if (need_eoc) { | ||
226 | ASN1error(ASN1_R_MISSING_EOC); | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | return 1; | ||
231 | } | ||
232 | |||
233 | /* Find the end of an ASN.1 object. */ | ||
234 | static int | ||
235 | asn1_find_end(CBS *cbs, size_t length, int indefinite) | ||
236 | { | ||
237 | size_t eoc_count; | ||
238 | |||
239 | if (!indefinite) { | ||
240 | if (!CBS_skip(cbs, length)) { | ||
241 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
242 | return 0; | ||
243 | } | ||
244 | return 1; | ||
245 | } | ||
246 | |||
247 | eoc_count = 1; | ||
248 | |||
249 | while (CBS_len(cbs) > 0) { | ||
250 | if (asn1_check_eoc(cbs)) { | ||
251 | if (--eoc_count == 0) | ||
252 | break; | ||
253 | continue; | ||
254 | } | ||
255 | if (!asn1_check_tag(cbs, &length, NULL, NULL, | ||
256 | &indefinite, NULL, -1, 0, 0)) { | ||
257 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
258 | return 0; | ||
259 | } | ||
260 | if (indefinite) { | ||
261 | eoc_count++; | ||
262 | continue; | ||
263 | } | ||
264 | if (!CBS_skip(cbs, length)) | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | if (eoc_count > 0) { | ||
269 | ASN1error(ASN1_R_MISSING_EOC); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | return 1; | ||
274 | } | ||
275 | |||
276 | static int | ||
277 | asn1_c2i_primitive(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it) | ||
278 | { | ||
279 | ASN1_BOOLEAN *abool; | ||
280 | ASN1_STRING *astr; | ||
281 | uint8_t val; | ||
282 | int ret = 0; | ||
283 | |||
284 | if (it->funcs != NULL) | ||
285 | goto err; | ||
286 | |||
287 | if (CBS_len(content) > INT_MAX) | ||
288 | goto err; | ||
289 | |||
290 | switch (utype) { | ||
291 | case V_ASN1_OBJECT: | ||
292 | if (!c2i_ASN1_OBJECT_cbs((ASN1_OBJECT **)pval, content)) | ||
293 | goto err; | ||
294 | break; | ||
295 | |||
296 | case V_ASN1_NULL: | ||
297 | if (CBS_len(content) != 0) { | ||
298 | ASN1error(ASN1_R_NULL_IS_WRONG_LENGTH); | ||
299 | goto err; | ||
300 | } | ||
301 | *pval = (ASN1_VALUE *)1; | ||
302 | break; | ||
303 | |||
304 | case V_ASN1_BOOLEAN: | ||
305 | abool = (ASN1_BOOLEAN *)pval; | ||
306 | if (CBS_len(content) != 1) { | ||
307 | ASN1error(ASN1_R_BOOLEAN_IS_WRONG_LENGTH); | ||
308 | goto err; | ||
309 | } | ||
310 | if (!CBS_get_u8(content, &val)) | ||
311 | goto err; | ||
312 | *abool = val; | ||
313 | break; | ||
314 | |||
315 | case V_ASN1_BIT_STRING: | ||
316 | if (!c2i_ASN1_BIT_STRING_cbs((ASN1_BIT_STRING **)pval, content)) | ||
317 | goto err; | ||
318 | break; | ||
319 | |||
320 | case V_ASN1_ENUMERATED: | ||
321 | if (!c2i_ASN1_ENUMERATED_cbs((ASN1_ENUMERATED **)pval, content)) | ||
322 | goto err; | ||
323 | break; | ||
324 | |||
325 | case V_ASN1_INTEGER: | ||
326 | if (!c2i_ASN1_INTEGER_cbs((ASN1_INTEGER **)pval, content)) | ||
327 | goto err; | ||
328 | break; | ||
329 | |||
330 | case V_ASN1_OCTET_STRING: | ||
331 | case V_ASN1_NUMERICSTRING: | ||
332 | case V_ASN1_PRINTABLESTRING: | ||
333 | case V_ASN1_T61STRING: | ||
334 | case V_ASN1_VIDEOTEXSTRING: | ||
335 | case V_ASN1_IA5STRING: | ||
336 | case V_ASN1_UTCTIME: | ||
337 | case V_ASN1_GENERALIZEDTIME: | ||
338 | case V_ASN1_GRAPHICSTRING: | ||
339 | case V_ASN1_VISIBLESTRING: | ||
340 | case V_ASN1_GENERALSTRING: | ||
341 | case V_ASN1_UNIVERSALSTRING: | ||
342 | case V_ASN1_BMPSTRING: | ||
343 | case V_ASN1_UTF8STRING: | ||
344 | case V_ASN1_OTHER: | ||
345 | case V_ASN1_SET: | ||
346 | case V_ASN1_SEQUENCE: | ||
347 | default: | ||
348 | if (utype == V_ASN1_BMPSTRING && (CBS_len(content) & 1)) { | ||
349 | ASN1error(ASN1_R_BMPSTRING_IS_WRONG_LENGTH); | ||
350 | goto err; | ||
351 | } | ||
352 | if (utype == V_ASN1_UNIVERSALSTRING && (CBS_len(content) & 3)) { | ||
353 | ASN1error(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); | ||
354 | goto err; | ||
355 | } | ||
356 | if (utype == V_ASN1_UTCTIME || utype == V_ASN1_GENERALIZEDTIME) { | ||
357 | if (!asn1_time_parse_cbs(content, | ||
358 | utype == V_ASN1_GENERALIZEDTIME, NULL)) { | ||
359 | ASN1error(ASN1_R_INVALID_TIME_FORMAT); | ||
360 | goto err; | ||
361 | } | ||
362 | } | ||
363 | /* All based on ASN1_STRING and handled the same way. */ | ||
364 | if (*pval != NULL) { | ||
365 | ASN1_STRING_free((ASN1_STRING *)*pval); | ||
366 | *pval = NULL; | ||
367 | } | ||
368 | if ((astr = ASN1_STRING_type_new(utype)) == NULL) { | ||
369 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
370 | goto err; | ||
371 | } | ||
372 | if (!ASN1_STRING_set(astr, CBS_data(content), CBS_len(content))) { | ||
373 | ASN1_STRING_free(astr); | ||
374 | goto err; | ||
375 | } | ||
376 | *pval = (ASN1_VALUE *)astr; | ||
377 | break; | ||
378 | } | ||
379 | |||
380 | ret = 1; | ||
381 | |||
382 | err: | ||
383 | return ret; | ||
384 | } | ||
385 | |||
386 | static int | ||
387 | asn1_c2i_any(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it) | ||
388 | { | ||
389 | ASN1_TYPE *atype; | ||
390 | |||
391 | if (it->utype != V_ASN1_ANY || it->funcs != NULL) | ||
392 | return 0; | ||
393 | |||
394 | if (*pval != NULL) { | ||
395 | ASN1_TYPE_free((ASN1_TYPE *)*pval); | ||
396 | *pval = NULL; | ||
397 | } | ||
398 | |||
399 | if ((atype = ASN1_TYPE_new()) == NULL) | ||
400 | return 0; | ||
401 | |||
402 | if (!asn1_c2i_primitive(&atype->value.asn1_value, content, utype, it)) { | ||
403 | ASN1_TYPE_free(atype); | ||
404 | return 0; | ||
405 | } | ||
406 | atype->type = utype; | ||
407 | |||
408 | /* Fix up value for ASN.1 NULL. */ | ||
409 | if (atype->type == V_ASN1_NULL) | ||
410 | atype->value.ptr = NULL; | ||
411 | |||
412 | *pval = (ASN1_VALUE *)atype; | ||
413 | |||
414 | return 1; | ||
415 | } | ||
416 | |||
417 | static int | ||
418 | asn1_c2i(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it) | ||
419 | { | ||
420 | if (CBS_len(content) > INT_MAX) | ||
421 | return 0; | ||
422 | |||
423 | if (it->funcs != NULL) { | ||
424 | const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; | ||
425 | char free_content = 0; | ||
426 | |||
427 | if (pf->prim_c2i == NULL) | ||
428 | return 0; | ||
429 | |||
430 | return pf->prim_c2i(pval, CBS_data(content), CBS_len(content), | ||
431 | utype, &free_content, it); | ||
432 | } | ||
433 | |||
434 | if (it->utype == V_ASN1_ANY) | ||
435 | return asn1_c2i_any(pval, content, utype, it); | ||
436 | |||
437 | return asn1_c2i_primitive(pval, content, utype, it); | ||
438 | } | ||
439 | |||
440 | /* | ||
441 | * Decode ASN.1 content into a primitive type. There are three possible forms - | ||
442 | * a SEQUENCE/SET/OTHER that is stored verbatim (including the ASN.1 tag and | ||
443 | * length octets), constructed objects and non-constructed objects. In the | ||
444 | * first two cases indefinite length is permitted, which we may need to handle. | ||
445 | * When this function is called the *cbs should reference the start of the | ||
446 | * ASN.1 object (i.e. the tag/length header), while *cbs_object should | ||
447 | * reference the start of the object contents (i.e. after the tag/length | ||
448 | * header. Additionally, the *cbs_object offset should be relative to the | ||
449 | * ASN.1 object being parsed. On success the *cbs will point at the octet | ||
450 | * after the object. | ||
451 | */ | ||
452 | static int | ||
453 | asn1_d2i_primitive_content(ASN1_VALUE **pval, CBS *cbs, CBS *cbs_object, | ||
454 | int utype, int constructed, int indefinite, size_t length, | ||
455 | const ASN1_ITEM *it) | ||
456 | { | ||
457 | CBS cbs_content, cbs_initial; | ||
458 | uint8_t *data = NULL; | ||
459 | size_t data_len = 0; | ||
460 | CBB cbb; | ||
461 | int ret = 0; | ||
462 | |||
463 | memset(&cbb, 0, sizeof(cbb)); | ||
464 | |||
465 | CBS_dup(cbs, &cbs_initial); | ||
466 | CBS_init(&cbs_content, NULL, 0); | ||
467 | |||
468 | if (asn1_must_be_constructed(utype) && !constructed) { | ||
469 | ASN1error(ASN1_R_TYPE_NOT_CONSTRUCTED); | ||
470 | goto err; | ||
471 | } | ||
472 | if (asn1_must_be_primitive(utype) && constructed) { | ||
473 | ASN1error(ASN1_R_TYPE_NOT_PRIMITIVE); | ||
474 | goto err; | ||
475 | } | ||
476 | |||
477 | /* SEQUENCE, SET and "OTHER" are left in encoded form. */ | ||
478 | if (utype == V_ASN1_SEQUENCE || utype == V_ASN1_SET || | ||
479 | utype == V_ASN1_OTHER) { | ||
480 | if (!asn1_find_end(cbs_object, length, indefinite)) | ||
481 | goto err; | ||
482 | if (!CBS_get_bytes(&cbs_initial, &cbs_content, | ||
483 | CBS_offset(cbs_object))) | ||
484 | goto err; | ||
485 | } else if (constructed) { | ||
486 | /* | ||
487 | * Should really check the internal tags are correct but | ||
488 | * some things may get this wrong. The relevant specs | ||
489 | * say that constructed string types should be OCTET STRINGs | ||
490 | * internally irrespective of the type. So instead just check | ||
491 | * for UNIVERSAL class and ignore the tag. | ||
492 | */ | ||
493 | if (!CBB_init(&cbb, 0)) | ||
494 | goto err; | ||
495 | if (!asn1_collect(&cbb, cbs_object, indefinite, -1, | ||
496 | V_ASN1_UNIVERSAL, 0)) | ||
497 | goto err; | ||
498 | if (!CBB_finish(&cbb, &data, &data_len)) | ||
499 | goto err; | ||
500 | |||
501 | CBS_init(&cbs_content, data, data_len); | ||
502 | } else { | ||
503 | if (!CBS_get_bytes(cbs_object, &cbs_content, length)) | ||
504 | goto err; | ||
505 | } | ||
506 | |||
507 | if (!asn1_c2i(pval, &cbs_content, utype, it)) | ||
508 | goto err; | ||
509 | |||
510 | if (!CBS_skip(cbs, CBS_offset(cbs_object))) | ||
511 | goto err; | ||
512 | |||
513 | ret = 1; | ||
514 | |||
515 | err: | ||
516 | CBB_cleanup(&cbb); | ||
517 | freezero(data, data_len); | ||
518 | |||
519 | return ret; | ||
520 | } | ||
521 | |||
522 | static int | ||
523 | asn1_d2i_any(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, | ||
524 | int tag_number, int tag_class, int optional) | ||
525 | { | ||
526 | int constructed, indefinite; | ||
527 | uint8_t object_class; | ||
528 | int object_type; | ||
529 | CBS cbs_object; | ||
530 | size_t length; | ||
531 | |||
532 | CBS_init(&cbs_object, CBS_data(cbs), CBS_len(cbs)); | ||
533 | |||
534 | if (it->utype != V_ASN1_ANY) | ||
535 | return 0; | ||
536 | |||
537 | if (tag_number >= 0) { | ||
538 | ASN1error(ASN1_R_ILLEGAL_TAGGED_ANY); | ||
539 | return 0; | ||
540 | } | ||
541 | if (optional) { | ||
542 | ASN1error(ASN1_R_ILLEGAL_OPTIONAL_ANY); | ||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | /* Determine type from ASN.1 tag. */ | ||
547 | if (asn1_check_tag(&cbs_object, &length, &object_type, &object_class, | ||
548 | &indefinite, &constructed, -1, 0, 0) != 1) { | ||
549 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
550 | return 0; | ||
551 | } | ||
552 | if (object_class != V_ASN1_UNIVERSAL) | ||
553 | object_type = V_ASN1_OTHER; | ||
554 | |||
555 | return asn1_d2i_primitive_content(pval, cbs, &cbs_object, object_type, | ||
556 | constructed, indefinite, length, it); | ||
557 | } | ||
558 | |||
559 | static int | ||
560 | asn1_d2i_mstring(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, | ||
561 | int tag_number, int tag_class, int optional) | ||
562 | { | ||
563 | int constructed, indefinite; | ||
564 | uint8_t object_class; | ||
565 | int object_tag; | ||
566 | CBS cbs_object; | ||
567 | size_t length; | ||
568 | |||
569 | CBS_init(&cbs_object, CBS_data(cbs), CBS_len(cbs)); | ||
570 | |||
571 | /* | ||
572 | * It never makes sense for multi-strings to have implicit tagging, so | ||
573 | * if tag_number != -1, then this looks like an error in the template. | ||
574 | */ | ||
575 | if (tag_number != -1) { | ||
576 | ASN1error(ASN1_R_BAD_TEMPLATE); | ||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | if (asn1_check_tag(&cbs_object, &length, &object_tag, &object_class, | ||
581 | &indefinite, &constructed, -1, 0, 1) != 1) { | ||
582 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | /* Class must be UNIVERSAL. */ | ||
587 | if (object_class != V_ASN1_UNIVERSAL) { | ||
588 | if (optional) | ||
589 | return -1; | ||
590 | ASN1error(ASN1_R_MSTRING_NOT_UNIVERSAL); | ||
591 | return 0; | ||
592 | } | ||
593 | /* Check tag matches bit map. */ | ||
594 | if ((ASN1_tag2bit(object_tag) & it->utype) == 0) { | ||
595 | if (optional) | ||
596 | return -1; | ||
597 | ASN1error(ASN1_R_MSTRING_WRONG_TAG); | ||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | return asn1_d2i_primitive_content(pval, cbs, &cbs_object, | ||
602 | object_tag, constructed, indefinite, length, it); | ||
603 | } | ||
604 | |||
605 | static int | ||
606 | asn1_d2i_primitive(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, | ||
607 | int tag_number, int tag_class, int optional) | ||
608 | { | ||
609 | CBS cbs_object; | ||
610 | int constructed, indefinite; | ||
611 | int utype = it->utype; | ||
612 | size_t length; | ||
613 | int ret; | ||
614 | |||
615 | CBS_init(&cbs_object, CBS_data(cbs), CBS_len(cbs)); | ||
616 | |||
617 | if (it->itype == ASN1_ITYPE_MSTRING) | ||
618 | return 0; | ||
619 | |||
620 | if (it->utype == V_ASN1_ANY) | ||
621 | return asn1_d2i_any(pval, cbs, it, tag_number, tag_class, optional); | ||
622 | |||
623 | if (tag_number == -1) { | ||
624 | tag_number = it->utype; | ||
625 | tag_class = V_ASN1_UNIVERSAL; | ||
626 | } | ||
627 | |||
628 | ret = asn1_check_tag(&cbs_object, &length, NULL, NULL, &indefinite, | ||
629 | &constructed, tag_number, tag_class, optional); | ||
630 | if (ret == -1) | ||
631 | return -1; | ||
632 | if (ret != 1) { | ||
633 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | return asn1_d2i_primitive_content(pval, cbs, &cbs_object, utype, | ||
638 | constructed, indefinite, length, it); | ||
639 | } | ||
640 | |||
641 | static int | ||
642 | asn1_item_d2i_choice(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, | ||
643 | int tag_number, int tag_class, int optional, int depth) | ||
644 | { | ||
645 | const ASN1_TEMPLATE *at, *errat = NULL; | ||
646 | const ASN1_AUX *aux; | ||
647 | ASN1_aux_cb *asn1_cb = NULL; | ||
648 | ASN1_VALUE *achoice = NULL; | ||
649 | ASN1_VALUE **pchptr; | ||
650 | int i, ret; | ||
651 | |||
652 | if ((aux = it->funcs) != NULL) | ||
653 | asn1_cb = aux->asn1_cb; | ||
654 | |||
655 | if (it->itype != ASN1_ITYPE_CHOICE) | ||
656 | goto err; | ||
657 | |||
658 | /* | ||
659 | * It never makes sense for CHOICE types to have implicit tagging, so | ||
660 | * if tag_number != -1, then this looks like an error in the template. | ||
661 | */ | ||
662 | if (tag_number != -1) { | ||
663 | ASN1error(ASN1_R_BAD_TEMPLATE); | ||
664 | goto err; | ||
665 | } | ||
666 | |||
667 | if (*pval != NULL) { | ||
668 | ASN1_item_ex_free(pval, it); | ||
669 | *pval = NULL; | ||
670 | } | ||
671 | |||
672 | if (!ASN1_item_ex_new(&achoice, it)) { | ||
673 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
674 | goto err; | ||
675 | } | ||
676 | |||
677 | if (asn1_cb != NULL && !asn1_cb(ASN1_OP_D2I_PRE, &achoice, it, NULL)) { | ||
678 | ASN1error(ASN1_R_AUX_ERROR); | ||
679 | goto err; | ||
680 | } | ||
681 | |||
682 | /* Try each possible CHOICE in turn. */ | ||
683 | for (i = 0; i < it->tcount; i++) { | ||
684 | at = &it->templates[i]; | ||
685 | |||
686 | pchptr = asn1_get_field_ptr(&achoice, at); | ||
687 | |||
688 | /* Mark field as OPTIONAL so its absence can be identified. */ | ||
689 | ret = asn1_template_d2i(pchptr, cbs, at, 1, depth); | ||
690 | if (ret == -1) | ||
691 | continue; | ||
692 | if (ret != 1) { | ||
693 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
694 | errat = at; | ||
695 | goto err; | ||
696 | } | ||
697 | |||
698 | /* We've successfully decoded an ASN.1 object. */ | ||
699 | asn1_set_choice_selector(&achoice, i, it); | ||
700 | break; | ||
701 | } | ||
702 | |||
703 | /* Did we fall off the end without reading anything? */ | ||
704 | if (i == it->tcount) { | ||
705 | if (optional) { | ||
706 | ASN1_item_ex_free(&achoice, it); | ||
707 | return -1; | ||
708 | } | ||
709 | ASN1error(ASN1_R_NO_MATCHING_CHOICE_TYPE); | ||
710 | goto err; | ||
711 | } | ||
712 | |||
713 | if (asn1_cb != NULL && !asn1_cb(ASN1_OP_D2I_POST, &achoice, it, NULL)) { | ||
714 | ASN1error(ASN1_R_AUX_ERROR); | ||
715 | goto err; | ||
716 | } | ||
717 | |||
718 | *pval = achoice; | ||
719 | achoice = NULL; | ||
720 | |||
721 | return 1; | ||
722 | |||
723 | err: | ||
724 | ASN1_item_ex_free(&achoice, it); | ||
725 | |||
726 | if (errat != NULL) | ||
727 | ERR_asprintf_error_data("Field=%s, Type=%s", errat->field_name, | ||
728 | it->sname); | ||
729 | else | ||
730 | ERR_asprintf_error_data("Type=%s", it->sname); | ||
731 | |||
732 | return 0; | ||
733 | } | ||
734 | |||
735 | static int | ||
736 | asn1_item_d2i_sequence(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, | ||
737 | int tag_number, int tag_class, int optional, int depth) | ||
738 | { | ||
739 | CBS cbs_seq, cbs_seq_content, cbs_object; | ||
740 | int constructed, indefinite, optional_field; | ||
741 | const ASN1_TEMPLATE *errat = NULL; | ||
742 | const ASN1_TEMPLATE *seqat, *at; | ||
743 | ASN1_aux_cb *asn1_cb = NULL; | ||
744 | const ASN1_AUX *aux; | ||
745 | ASN1_VALUE *aseq = NULL; | ||
746 | ASN1_VALUE **pseqval; | ||
747 | int eoc_needed, i; | ||
748 | size_t length; | ||
749 | int ret = 0; | ||
750 | |||
751 | CBS_init(&cbs_seq, CBS_data(cbs), CBS_len(cbs)); | ||
752 | |||
753 | if ((aux = it->funcs) != NULL) | ||
754 | asn1_cb = aux->asn1_cb; | ||
755 | |||
756 | if (it->itype != ASN1_ITYPE_NDEF_SEQUENCE && | ||
757 | it->itype != ASN1_ITYPE_SEQUENCE) | ||
758 | goto err; | ||
759 | |||
760 | if (*pval != NULL) { | ||
761 | ASN1_item_ex_free(pval, it); | ||
762 | *pval = NULL; | ||
763 | } | ||
764 | |||
765 | /* If no IMPLICIT tagging use UNIVERSAL/SEQUENCE. */ | ||
766 | if (tag_number == -1) { | ||
767 | tag_class = V_ASN1_UNIVERSAL; | ||
768 | tag_number = V_ASN1_SEQUENCE; | ||
769 | } | ||
770 | |||
771 | /* Read ASN.1 SEQUENCE header. */ | ||
772 | ret = asn1_check_tag(&cbs_seq, &length, NULL, NULL, &indefinite, | ||
773 | &constructed, tag_number, tag_class, optional); | ||
774 | if (ret == -1) | ||
775 | return -1; | ||
776 | if (ret != 1) { | ||
777 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
778 | goto err; | ||
779 | } | ||
780 | |||
781 | if (!constructed) { | ||
782 | ASN1error(ASN1_R_SEQUENCE_NOT_CONSTRUCTED); | ||
783 | goto err; | ||
784 | } | ||
785 | |||
786 | if (indefinite) { | ||
787 | eoc_needed = 1; | ||
788 | CBS_init(&cbs_seq_content, CBS_data(&cbs_seq), CBS_len(&cbs_seq)); | ||
789 | } else { | ||
790 | eoc_needed = 0; | ||
791 | if (!CBS_get_bytes(&cbs_seq, &cbs_seq_content, length)) | ||
792 | goto err; | ||
793 | } | ||
794 | |||
795 | if (!ASN1_item_ex_new(&aseq, it)) { | ||
796 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
797 | goto err; | ||
798 | } | ||
799 | |||
800 | if (asn1_cb != NULL && !asn1_cb(ASN1_OP_D2I_PRE, &aseq, it, NULL)) { | ||
801 | ASN1error(ASN1_R_AUX_ERROR); | ||
802 | goto err; | ||
803 | } | ||
804 | |||
805 | for (i = 0; i < it->tcount; i++) { | ||
806 | at = &it->templates[i]; | ||
807 | |||
808 | if (asn1_check_eoc(&cbs_seq_content)) { | ||
809 | if (!indefinite) { | ||
810 | ASN1error(ASN1_R_UNEXPECTED_EOC); | ||
811 | goto err; | ||
812 | } | ||
813 | eoc_needed = 0; | ||
814 | break; | ||
815 | } | ||
816 | if (CBS_len(&cbs_seq_content) == 0) | ||
817 | break; | ||
818 | |||
819 | if ((seqat = asn1_do_adb(&aseq, at, 1)) == NULL) | ||
820 | goto err; | ||
821 | |||
822 | pseqval = asn1_get_field_ptr(&aseq, seqat); | ||
823 | |||
824 | /* | ||
825 | * This was originally implemented to "increase efficiency", | ||
826 | * however it currently needs to remain since it papers over | ||
827 | * the use of ASN.1 ANY with OPTIONAL in SEQUENCEs (which | ||
828 | * asn1_d2i_primitive() currently rejects). | ||
829 | */ | ||
830 | optional_field = (seqat->flags & ASN1_TFLG_OPTIONAL) != 0; | ||
831 | if (i == it->tcount - 1) | ||
832 | optional_field = 0; | ||
833 | |||
834 | ret = asn1_template_d2i(pseqval, &cbs_seq_content, | ||
835 | seqat, optional_field, depth); | ||
836 | if (ret == -1) { | ||
837 | /* Absent OPTIONAL component. */ | ||
838 | ASN1_template_free(pseqval, seqat); | ||
839 | continue; | ||
840 | } | ||
841 | if (ret != 1) { | ||
842 | errat = seqat; | ||
843 | goto err; | ||
844 | } | ||
845 | } | ||
846 | |||
847 | if (eoc_needed && !asn1_check_eoc(&cbs_seq_content)) { | ||
848 | ASN1error(ASN1_R_MISSING_EOC); | ||
849 | goto err; | ||
850 | } | ||
851 | |||
852 | if (indefinite) { | ||
853 | if (!CBS_skip(&cbs_seq, CBS_offset(&cbs_seq_content))) | ||
854 | goto err; | ||
855 | } else if (CBS_len(&cbs_seq_content) != 0) { | ||
856 | ASN1error(ASN1_R_SEQUENCE_LENGTH_MISMATCH); | ||
857 | goto err; | ||
858 | } | ||
859 | |||
860 | /* | ||
861 | * There is no more data in the ASN.1 SEQUENCE, however we may not have | ||
862 | * populated all fields - check that any remaining are OPTIONAL. | ||
863 | */ | ||
864 | for (; i < it->tcount; i++) { | ||
865 | at = &it->templates[i]; | ||
866 | |||
867 | if ((seqat = asn1_do_adb(&aseq, at, 1)) == NULL) | ||
868 | goto err; | ||
869 | |||
870 | if ((seqat->flags & ASN1_TFLG_OPTIONAL) == 0) { | ||
871 | ASN1error(ASN1_R_FIELD_MISSING); | ||
872 | errat = seqat; | ||
873 | goto err; | ||
874 | } | ||
875 | |||
876 | /* XXX - this is probably unnecessary with earlier free. */ | ||
877 | pseqval = asn1_get_field_ptr(&aseq, seqat); | ||
878 | ASN1_template_free(pseqval, seqat); | ||
879 | } | ||
880 | |||
881 | if (!CBS_get_bytes(cbs, &cbs_object, CBS_offset(&cbs_seq))) | ||
882 | goto err; | ||
883 | |||
884 | if (!asn1_enc_save(&aseq, &cbs_object, it)) { | ||
885 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
886 | goto err; | ||
887 | } | ||
888 | |||
889 | if (asn1_cb != NULL && !asn1_cb(ASN1_OP_D2I_POST, &aseq, it, NULL)) { | ||
890 | ASN1error(ASN1_R_AUX_ERROR); | ||
891 | goto err; | ||
892 | } | ||
893 | |||
894 | *pval = aseq; | ||
895 | aseq = NULL; | ||
896 | |||
897 | return 1; | ||
898 | |||
899 | err: | ||
900 | ASN1_item_ex_free(&aseq, it); | ||
901 | |||
902 | if (errat != NULL) | ||
903 | ERR_asprintf_error_data("Field=%s, Type=%s", errat->field_name, | ||
904 | it->sname); | ||
905 | else | ||
906 | ERR_asprintf_error_data("Type=%s", it->sname); | ||
907 | |||
908 | return 0; | ||
909 | } | ||
910 | |||
911 | static int | ||
912 | asn1_item_d2i_extern(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, | ||
913 | int tag_number, int tag_class, int optional) | ||
914 | { | ||
915 | const ASN1_EXTERN_FUNCS *ef = it->funcs; | ||
916 | const unsigned char *p = NULL; | ||
917 | ASN1_TLC ctx = { 0 }; | ||
918 | int ret = 0; | ||
919 | |||
920 | if (CBS_len(cbs) > LONG_MAX) | ||
921 | return 0; | ||
922 | |||
923 | p = CBS_data(cbs); | ||
924 | |||
925 | if ((ret = ef->asn1_ex_d2i(pval, &p, (long)CBS_len(cbs), it, | ||
926 | tag_number, tag_class, optional, &ctx)) == 1) { | ||
927 | if (!CBS_skip(cbs, p - CBS_data(cbs))) | ||
928 | goto err; | ||
929 | } | ||
930 | return ret; | ||
931 | |||
932 | err: | ||
933 | ASN1_item_ex_free(pval, it); | ||
934 | |||
935 | ERR_asprintf_error_data("Type=%s", it->sname); | ||
936 | |||
937 | return 0; | ||
938 | } | ||
939 | |||
940 | static int | ||
941 | asn1_item_d2i(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, | ||
942 | int tag_number, int tag_class, int optional, int depth) | ||
943 | { | ||
944 | if (pval == NULL) | ||
945 | return 0; | ||
946 | |||
947 | if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { | ||
948 | ASN1error(ASN1_R_NESTED_TOO_DEEP); | ||
949 | goto err; | ||
950 | } | ||
951 | |||
952 | switch (it->itype) { | ||
953 | case ASN1_ITYPE_PRIMITIVE: | ||
954 | if (it->templates != NULL) { | ||
955 | /* | ||
956 | * Tagging or OPTIONAL is currently illegal on an item | ||
957 | * template because the flags can't get passed down. | ||
958 | * In practice this isn't a problem: we include the | ||
959 | * relevant flags from the item template in the | ||
960 | * template itself. | ||
961 | */ | ||
962 | if (tag_number != -1 || optional) { | ||
963 | ASN1error(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); | ||
964 | goto err; | ||
965 | } | ||
966 | return asn1_template_d2i(pval, cbs, it->templates, | ||
967 | optional, depth); | ||
968 | } | ||
969 | return asn1_d2i_primitive(pval, cbs, it, tag_number, tag_class, | ||
970 | optional); | ||
971 | |||
972 | case ASN1_ITYPE_MSTRING: | ||
973 | return asn1_d2i_mstring(pval, cbs, it, tag_number, tag_class, | ||
974 | optional); | ||
975 | |||
976 | case ASN1_ITYPE_EXTERN: | ||
977 | return asn1_item_d2i_extern(pval, cbs, it, tag_number, | ||
978 | tag_class, optional); | ||
979 | |||
980 | case ASN1_ITYPE_CHOICE: | ||
981 | return asn1_item_d2i_choice(pval, cbs, it, tag_number, | ||
982 | tag_class, optional, depth); | ||
983 | |||
984 | case ASN1_ITYPE_NDEF_SEQUENCE: | ||
985 | case ASN1_ITYPE_SEQUENCE: | ||
986 | return asn1_item_d2i_sequence(pval, cbs, it, tag_number, | ||
987 | tag_class, optional, depth); | ||
988 | |||
989 | default: | ||
990 | return 0; | ||
991 | } | ||
992 | |||
993 | err: | ||
994 | ASN1_item_ex_free(pval, it); | ||
995 | |||
996 | ERR_asprintf_error_data("Type=%s", it->sname); | ||
997 | |||
998 | return 0; | ||
999 | } | ||
1000 | |||
1001 | static void | ||
1002 | asn1_template_stack_of_free(STACK_OF(ASN1_VALUE) *avals, | ||
1003 | const ASN1_TEMPLATE *at) | ||
1004 | { | ||
1005 | ASN1_VALUE *aval; | ||
1006 | |||
1007 | if (avals == NULL) | ||
1008 | return; | ||
1009 | |||
1010 | while (sk_ASN1_VALUE_num(avals) > 0) { | ||
1011 | aval = sk_ASN1_VALUE_pop(avals); | ||
1012 | ASN1_item_ex_free(&aval, at->item); | ||
1013 | } | ||
1014 | sk_ASN1_VALUE_free(avals); | ||
1015 | } | ||
1016 | |||
1017 | static int | ||
1018 | asn1_template_stack_of_d2i(ASN1_VALUE **pval, CBS *cbs, const ASN1_TEMPLATE *at, | ||
1019 | int optional, int depth) | ||
1020 | { | ||
1021 | CBS cbs_object, cbs_object_content; | ||
1022 | STACK_OF(ASN1_VALUE) *avals = NULL; | ||
1023 | ASN1_VALUE *aval = NULL; | ||
1024 | int tag_number, tag_class; | ||
1025 | int eoc_needed; | ||
1026 | int indefinite; | ||
1027 | size_t length; | ||
1028 | int ret; | ||
1029 | |||
1030 | CBS_init(&cbs_object, CBS_data(cbs), CBS_len(cbs)); | ||
1031 | |||
1032 | if (pval == NULL) | ||
1033 | return 0; | ||
1034 | |||
1035 | asn1_template_stack_of_free((STACK_OF(ASN1_VALUE) *)*pval, at); | ||
1036 | *pval = NULL; | ||
1037 | |||
1038 | tag_number = at->tag; | ||
1039 | tag_class = at->flags & ASN1_TFLG_TAG_CLASS; | ||
1040 | |||
1041 | /* Determine the inner tag value for SET OF or SEQUENCE OF. */ | ||
1042 | if ((at->flags & ASN1_TFLG_IMPTAG) == 0) { | ||
1043 | tag_number = V_ASN1_SEQUENCE; | ||
1044 | tag_class = V_ASN1_UNIVERSAL; | ||
1045 | if ((at->flags & ASN1_TFLG_SET_OF) != 0) | ||
1046 | tag_number = V_ASN1_SET; | ||
1047 | } | ||
1048 | |||
1049 | ret = asn1_check_tag(&cbs_object, &length, NULL, NULL, &indefinite, | ||
1050 | NULL, tag_number, tag_class, optional); | ||
1051 | if (ret == -1) | ||
1052 | return -1; | ||
1053 | if (ret != 1) { | ||
1054 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
1055 | return 0; | ||
1056 | } | ||
1057 | |||
1058 | if (indefinite) { | ||
1059 | eoc_needed = 1; | ||
1060 | CBS_init(&cbs_object_content, CBS_data(&cbs_object), | ||
1061 | CBS_len(&cbs_object)); | ||
1062 | } else { | ||
1063 | eoc_needed = 0; | ||
1064 | if (!CBS_get_bytes(&cbs_object, &cbs_object_content, | ||
1065 | length)) | ||
1066 | goto err; | ||
1067 | } | ||
1068 | |||
1069 | if ((avals = sk_ASN1_VALUE_new_null()) == NULL) { | ||
1070 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
1071 | goto err; | ||
1072 | } | ||
1073 | |||
1074 | /* Read as many items as possible. */ | ||
1075 | while (CBS_len(&cbs_object_content) > 0) { | ||
1076 | if (asn1_check_eoc(&cbs_object_content)) { | ||
1077 | if (!eoc_needed) { | ||
1078 | ASN1error(ASN1_R_UNEXPECTED_EOC); | ||
1079 | goto err; | ||
1080 | } | ||
1081 | eoc_needed = 0; | ||
1082 | break; | ||
1083 | } | ||
1084 | if (!asn1_item_d2i(&aval, &cbs_object_content, at->item, -1, 0, | ||
1085 | 0, depth)) { | ||
1086 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
1087 | goto err; | ||
1088 | } | ||
1089 | if (!sk_ASN1_VALUE_push(avals, aval)) { | ||
1090 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
1091 | goto err; | ||
1092 | } | ||
1093 | aval = NULL; | ||
1094 | } | ||
1095 | if (eoc_needed) { | ||
1096 | ASN1error(ASN1_R_MISSING_EOC); | ||
1097 | goto err; | ||
1098 | } | ||
1099 | |||
1100 | if (indefinite) { | ||
1101 | if (!CBS_skip(&cbs_object, CBS_offset(&cbs_object_content))) | ||
1102 | goto err; | ||
1103 | } | ||
1104 | |||
1105 | if (!CBS_skip(cbs, CBS_offset(&cbs_object))) | ||
1106 | goto err; | ||
1107 | |||
1108 | *pval = (ASN1_VALUE *)avals; | ||
1109 | avals = NULL; | ||
1110 | |||
1111 | return 1; | ||
1112 | |||
1113 | err: | ||
1114 | asn1_template_stack_of_free(avals, at); | ||
1115 | ASN1_item_ex_free(&aval, at->item); | ||
1116 | |||
1117 | return 0; | ||
1118 | } | ||
1119 | |||
1120 | static int | ||
1121 | asn1_template_noexp_d2i(ASN1_VALUE **pval, CBS *cbs, const ASN1_TEMPLATE *at, | ||
1122 | int optional, int depth) | ||
1123 | { | ||
1124 | int tag_number, tag_class; | ||
1125 | int ret; | ||
1126 | |||
1127 | if (pval == NULL) | ||
1128 | return 0; | ||
1129 | |||
1130 | if ((at->flags & ASN1_TFLG_SK_MASK) != 0) | ||
1131 | return asn1_template_stack_of_d2i(pval, cbs, at, optional, depth); | ||
1132 | |||
1133 | tag_number = -1; | ||
1134 | tag_class = V_ASN1_UNIVERSAL; | ||
1135 | |||
1136 | /* See if we need to use IMPLICIT tagging. */ | ||
1137 | if ((at->flags & ASN1_TFLG_IMPTAG) != 0) { | ||
1138 | tag_number = at->tag; | ||
1139 | tag_class = at->flags & ASN1_TFLG_TAG_CLASS; | ||
1140 | } | ||
1141 | |||
1142 | ret = asn1_item_d2i(pval, cbs, at->item, tag_number, tag_class, | ||
1143 | optional, depth); | ||
1144 | if (ret == -1) | ||
1145 | return -1; | ||
1146 | if (ret != 1) { | ||
1147 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
1148 | goto err; | ||
1149 | } | ||
1150 | |||
1151 | return 1; | ||
1152 | |||
1153 | err: | ||
1154 | /* XXX - The called function should have freed already. */ | ||
1155 | ASN1_template_free(pval, at); | ||
1156 | return 0; | ||
1157 | } | ||
1158 | |||
1159 | static int | ||
1160 | asn1_template_d2i(ASN1_VALUE **pval, CBS *cbs, const ASN1_TEMPLATE *at, | ||
1161 | int optional, int depth) | ||
1162 | { | ||
1163 | CBS cbs_exp, cbs_exp_content; | ||
1164 | int constructed, indefinite; | ||
1165 | size_t length; | ||
1166 | int ret; | ||
1167 | |||
1168 | if (pval == NULL) | ||
1169 | return 0; | ||
1170 | |||
1171 | /* Check if EXPLICIT tag is expected. */ | ||
1172 | if ((at->flags & ASN1_TFLG_EXPTAG) == 0) | ||
1173 | return asn1_template_noexp_d2i(pval, cbs, at, optional, depth); | ||
1174 | |||
1175 | CBS_init(&cbs_exp, CBS_data(cbs), CBS_len(cbs)); | ||
1176 | |||
1177 | /* Read ASN.1 header for EXPLICIT tagged object. */ | ||
1178 | ret = asn1_check_tag(&cbs_exp, &length, NULL, NULL, &indefinite, | ||
1179 | &constructed, at->tag, at->flags & ASN1_TFLG_TAG_CLASS, optional); | ||
1180 | if (ret == -1) | ||
1181 | return -1; | ||
1182 | if (ret != 1) { | ||
1183 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
1184 | return 0; | ||
1185 | } | ||
1186 | |||
1187 | if (!constructed) { | ||
1188 | ASN1error(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); | ||
1189 | return 0; | ||
1190 | } | ||
1191 | |||
1192 | if (indefinite) { | ||
1193 | CBS_init(&cbs_exp_content, CBS_data(&cbs_exp), CBS_len(&cbs_exp)); | ||
1194 | } else { | ||
1195 | if (!CBS_get_bytes(&cbs_exp, &cbs_exp_content, length)) | ||
1196 | goto err; | ||
1197 | } | ||
1198 | |||
1199 | if ((ret = asn1_template_noexp_d2i(pval, &cbs_exp_content, at, 0, | ||
1200 | depth)) != 1) { | ||
1201 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
1202 | return 0; | ||
1203 | } | ||
1204 | |||
1205 | if (indefinite) { | ||
1206 | if (!asn1_check_eoc(&cbs_exp_content)) { | ||
1207 | ASN1error(ASN1_R_MISSING_EOC); | ||
1208 | goto err; | ||
1209 | } | ||
1210 | if (!CBS_skip(&cbs_exp, CBS_offset(&cbs_exp_content))) | ||
1211 | goto err; | ||
1212 | } else if (CBS_len(&cbs_exp_content) != 0) { | ||
1213 | ASN1error(ASN1_R_SEQUENCE_LENGTH_MISMATCH); | ||
1214 | goto err; | ||
1215 | } | ||
1216 | |||
1217 | if (!CBS_skip(cbs, CBS_offset(&cbs_exp))) | ||
1218 | goto err; | ||
1219 | |||
1220 | return 1; | ||
1221 | |||
1222 | err: | ||
1223 | ASN1_template_free(pval, at); | ||
1224 | return 0; | ||
1225 | } | ||
1226 | |||
1227 | ASN1_VALUE * | ||
1228 | ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long inlen, | ||
1229 | const ASN1_ITEM *it) | ||
1230 | { | ||
1231 | ASN1_VALUE *ptmpval = NULL; | ||
1232 | |||
1233 | if (pval == NULL) | ||
1234 | pval = &ptmpval; | ||
1235 | if (ASN1_item_ex_d2i(pval, in, inlen, it, -1, 0, 0, NULL) <= 0) | ||
1236 | return NULL; | ||
1237 | |||
1238 | return *pval; | ||
1239 | } | ||
1240 | LCRYPTO_ALIAS(ASN1_item_d2i); | ||
1241 | |||
1242 | int | ||
1243 | ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long inlen, | ||
1244 | const ASN1_ITEM *it, int tag_number, int tag_class, char optional, | ||
1245 | ASN1_TLC *ctx) | ||
1246 | { | ||
1247 | CBS cbs; | ||
1248 | int ret; | ||
1249 | |||
1250 | if (inlen < 0) | ||
1251 | return 0; | ||
1252 | |||
1253 | CBS_init(&cbs, *in, inlen); | ||
1254 | if ((ret = asn1_item_d2i(pval, &cbs, it, tag_number, tag_class, | ||
1255 | (int)optional, 0)) == 1) | ||
1256 | *in = CBS_data(&cbs); | ||
1257 | |||
1258 | return ret; | ||
1259 | } | ||
1260 | LCRYPTO_ALIAS(ASN1_item_ex_d2i); | ||