1*c9ae38aaStb /* $OpenBSD: tasn_dec.c,v 1.88 2023/07/28 10:00:10 tb Exp $ */
2e6841c1dSdjm /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3da347917Sbeck * project 2000.
4da347917Sbeck */
5da347917Sbeck /* ====================================================================
64fcf65c5Sdjm * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
7da347917Sbeck *
8da347917Sbeck * Redistribution and use in source and binary forms, with or without
9da347917Sbeck * modification, are permitted provided that the following conditions
10da347917Sbeck * are met:
11da347917Sbeck *
12da347917Sbeck * 1. Redistributions of source code must retain the above copyright
13da347917Sbeck * notice, this list of conditions and the following disclaimer.
14da347917Sbeck *
15da347917Sbeck * 2. Redistributions in binary form must reproduce the above copyright
16da347917Sbeck * notice, this list of conditions and the following disclaimer in
17da347917Sbeck * the documentation and/or other materials provided with the
18da347917Sbeck * distribution.
19da347917Sbeck *
20da347917Sbeck * 3. All advertising materials mentioning features or use of this
21da347917Sbeck * software must display the following acknowledgment:
22da347917Sbeck * "This product includes software developed by the OpenSSL Project
23da347917Sbeck * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24da347917Sbeck *
25da347917Sbeck * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26da347917Sbeck * endorse or promote products derived from this software without
27da347917Sbeck * prior written permission. For written permission, please contact
28da347917Sbeck * licensing@OpenSSL.org.
29da347917Sbeck *
30da347917Sbeck * 5. Products derived from this software may not be called "OpenSSL"
31da347917Sbeck * nor may "OpenSSL" appear in their names without prior written
32da347917Sbeck * permission of the OpenSSL Project.
33da347917Sbeck *
34da347917Sbeck * 6. Redistributions of any form whatsoever must retain the following
35da347917Sbeck * acknowledgment:
36da347917Sbeck * "This product includes software developed by the OpenSSL Project
37da347917Sbeck * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38da347917Sbeck *
39da347917Sbeck * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40da347917Sbeck * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41da347917Sbeck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42da347917Sbeck * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43da347917Sbeck * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44da347917Sbeck * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45da347917Sbeck * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46da347917Sbeck * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47da347917Sbeck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48da347917Sbeck * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49da347917Sbeck * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50da347917Sbeck * OF THE POSSIBILITY OF SUCH DAMAGE.
51da347917Sbeck * ====================================================================
52da347917Sbeck *
53da347917Sbeck * This product includes cryptographic software written by Eric Young
54da347917Sbeck * (eay@cryptsoft.com). This product includes software written by Tim
55da347917Sbeck * Hudson (tjh@cryptsoft.com).
56da347917Sbeck *
57da347917Sbeck */
58da347917Sbeck
593f2eca84Sjsing #include <limits.h>
60da347917Sbeck #include <stddef.h>
61da347917Sbeck #include <string.h>
629014c085Sjsing
63da347917Sbeck #include <openssl/asn1.h>
64da347917Sbeck #include <openssl/asn1t.h>
65da347917Sbeck #include <openssl/buffer.h>
66da347917Sbeck #include <openssl/err.h>
679014c085Sjsing #include <openssl/objects.h>
68da347917Sbeck
69c9675a23Stb #include "asn1_local.h"
703f2eca84Sjsing #include "bytestring.h"
713f2eca84Sjsing
72d5028891Sjsing /*
73d5028891Sjsing * Constructed types with a recursive definition (such as can be found in PKCS7)
7455f5b47bSinoguchi * could eventually exceed the stack given malicious input with excessive
7555f5b47bSinoguchi * recursion. Therefore we limit the stack depth.
7655f5b47bSinoguchi */
7755f5b47bSinoguchi #define ASN1_MAX_CONSTRUCTED_NEST 30
7855f5b47bSinoguchi
79d5028891Sjsing #ifndef ASN1_MAX_STRING_NEST
80d5028891Sjsing /*
81d5028891Sjsing * This determines how many levels of recursion are permitted in ASN.1 string
82d5028891Sjsing * types. If it is not limited stack overflows can occur. If set to zero no
83884131c6Sjsing * recursion is allowed at all.
84d5028891Sjsing */
85d5028891Sjsing #define ASN1_MAX_STRING_NEST 5
86d5028891Sjsing #endif
874fcf65c5Sdjm
886db14da9Sjsing static int asn1_template_d2i(ASN1_VALUE **pval, CBS *cbs,
8996ded9f8Sjsing const ASN1_TEMPLATE *at, int optional, int depth);
90da347917Sbeck
91d5028891Sjsing static int
asn1_check_eoc(CBS * cbs)92d5028891Sjsing asn1_check_eoc(CBS *cbs)
93da347917Sbeck {
94d5028891Sjsing uint16_t eoc;
95f9c88cf6Sjsing
96d5028891Sjsing if (!CBS_peek_u16(cbs, &eoc))
97d5028891Sjsing return 0;
98d5028891Sjsing if (eoc != 0)
99ecad301fSjsing return 0;
100ecad301fSjsing
101d5028891Sjsing return CBS_skip(cbs, 2);
102d5028891Sjsing }
103d5028891Sjsing
104d5028891Sjsing static int
asn1_check_tag(CBS * cbs,size_t * out_len,int * out_tag,uint8_t * out_class,int * out_indefinite,int * out_constructed,int expected_tag,int expected_class,int optional)105d5028891Sjsing asn1_check_tag(CBS *cbs, size_t *out_len, int *out_tag, uint8_t *out_class,
10696ded9f8Sjsing int *out_indefinite, int *out_constructed, int expected_tag,
10796ded9f8Sjsing int expected_class, int optional)
108d5028891Sjsing {
109d5028891Sjsing int constructed, indefinite;
110d5028891Sjsing uint32_t tag_number;
111d5028891Sjsing uint8_t tag_class;
112d5028891Sjsing size_t length;
113d5028891Sjsing
114d5028891Sjsing if (out_len != NULL)
115d5028891Sjsing *out_len = 0;
116d5028891Sjsing if (out_tag != NULL)
117d5028891Sjsing *out_tag = 0;
118d5028891Sjsing if (out_class != NULL)
119d5028891Sjsing *out_class = 0;
120d5028891Sjsing if (out_indefinite != NULL)
121d5028891Sjsing *out_indefinite = 0;
122d5028891Sjsing if (out_constructed != NULL)
123d5028891Sjsing *out_constructed = 0;
124d5028891Sjsing
125d5028891Sjsing if (!asn1_get_identifier_cbs(cbs, 0, &tag_class, &constructed,
126d5028891Sjsing &tag_number)) {
127d5028891Sjsing ASN1error(ASN1_R_BAD_OBJECT_HEADER);
128d5028891Sjsing return 0;
129d5028891Sjsing }
130d5028891Sjsing if (expected_tag >= 0) {
131d5028891Sjsing if (expected_tag != tag_number ||
132d5028891Sjsing expected_class != tag_class << 6) {
133d5028891Sjsing /* Indicate missing type if this is OPTIONAL. */
134d5028891Sjsing if (optional)
135d5028891Sjsing return -1;
136d5028891Sjsing
137d5028891Sjsing ASN1error(ASN1_R_WRONG_TAG);
138d5028891Sjsing return 0;
139d5028891Sjsing }
140d5028891Sjsing }
141d5028891Sjsing if (!asn1_get_length_cbs(cbs, 0, &indefinite, &length)) {
142d5028891Sjsing ASN1error(ASN1_R_BAD_OBJECT_HEADER);
143d5028891Sjsing return 0;
144d5028891Sjsing }
145d5028891Sjsing
146d5028891Sjsing /* Indefinite length can only be used with constructed encoding. */
147d5028891Sjsing if (indefinite && !constructed) {
148d5028891Sjsing ASN1error(ASN1_R_BAD_OBJECT_HEADER);
149d5028891Sjsing return 0;
150d5028891Sjsing }
151d5028891Sjsing
152d5028891Sjsing if (!indefinite && CBS_len(cbs) < length) {
153d5028891Sjsing ASN1error(ASN1_R_TOO_LONG);
154d5028891Sjsing return 0;
155d5028891Sjsing }
156d5028891Sjsing
157d5028891Sjsing if (tag_number > INT_MAX) {
158d5028891Sjsing ASN1error(ASN1_R_TOO_LONG);
159d5028891Sjsing return 0;
160d5028891Sjsing }
161d5028891Sjsing
162d5028891Sjsing if (indefinite)
163d5028891Sjsing length = CBS_len(cbs);
164d5028891Sjsing
165d5028891Sjsing if (out_len != NULL)
166d5028891Sjsing *out_len = length;
167d5028891Sjsing if (out_tag != NULL)
168d5028891Sjsing *out_tag = tag_number;
169d5028891Sjsing if (out_class != NULL)
170d5028891Sjsing *out_class = tag_class << 6;
17196ded9f8Sjsing if (out_indefinite != NULL)
17296ded9f8Sjsing *out_indefinite = indefinite;
17396ded9f8Sjsing if (out_constructed != NULL)
17496ded9f8Sjsing *out_constructed = constructed;
175d5028891Sjsing
176d5028891Sjsing return 1;
177d5028891Sjsing }
178d5028891Sjsing
179d5028891Sjsing /* Collect the contents from a constructed ASN.1 object. */
180d5028891Sjsing static int
asn1_collect(CBB * cbb,CBS * cbs,int indefinite,int expected_tag,int expected_class,int depth)18196ded9f8Sjsing asn1_collect(CBB *cbb, CBS *cbs, int indefinite, int expected_tag,
182d5028891Sjsing int expected_class, int depth)
183d5028891Sjsing {
18496ded9f8Sjsing int constructed;
185d5028891Sjsing size_t length;
186d5028891Sjsing CBS content;
187d5028891Sjsing int need_eoc;
188d5028891Sjsing
189d5028891Sjsing if (depth > ASN1_MAX_STRING_NEST) {
190d5028891Sjsing ASN1error(ASN1_R_NESTED_ASN1_STRING);
191d5028891Sjsing return 0;
192d5028891Sjsing }
193d5028891Sjsing
194d5028891Sjsing need_eoc = indefinite;
195d5028891Sjsing
196d5028891Sjsing while (CBS_len(cbs) > 0) {
197d5028891Sjsing if (asn1_check_eoc(cbs)) {
198d5028891Sjsing if (!need_eoc) {
199d5028891Sjsing ASN1error(ASN1_R_UNEXPECTED_EOC);
200d5028891Sjsing return 0;
201d5028891Sjsing }
202d5028891Sjsing return 1;
203d5028891Sjsing }
204d5028891Sjsing if (!asn1_check_tag(cbs, &length, NULL, NULL, &indefinite,
205d5028891Sjsing &constructed, expected_tag, expected_class, 0)) {
206d5028891Sjsing ASN1error(ERR_R_NESTED_ASN1_ERROR);
207d5028891Sjsing return 0;
208d5028891Sjsing }
209d5028891Sjsing
210d5028891Sjsing if (constructed) {
211d5028891Sjsing if (!asn1_collect(cbb, cbs, indefinite, expected_tag,
212d5028891Sjsing expected_class, depth + 1))
213d5028891Sjsing return 0;
214d5028891Sjsing continue;
215d5028891Sjsing }
216d5028891Sjsing
217d5028891Sjsing if (!CBS_get_bytes(cbs, &content, length)) {
218d5028891Sjsing ASN1error(ERR_R_NESTED_ASN1_ERROR);
219d5028891Sjsing return 0;
220d5028891Sjsing }
221d5028891Sjsing if (!CBB_add_bytes(cbb, CBS_data(&content), CBS_len(&content)))
222d5028891Sjsing return 0;
223d5028891Sjsing }
224d5028891Sjsing
225d5028891Sjsing if (need_eoc) {
226d5028891Sjsing ASN1error(ASN1_R_MISSING_EOC);
227d5028891Sjsing return 0;
228d5028891Sjsing }
229d5028891Sjsing
230d5028891Sjsing return 1;
231d5028891Sjsing }
232d5028891Sjsing
233d5028891Sjsing /* Find the end of an ASN.1 object. */
234d5028891Sjsing static int
asn1_find_end(CBS * cbs,size_t length,int indefinite)23596ded9f8Sjsing asn1_find_end(CBS *cbs, size_t length, int indefinite)
236d5028891Sjsing {
237d5028891Sjsing size_t eoc_count;
238d5028891Sjsing
239d5028891Sjsing if (!indefinite) {
240d5028891Sjsing if (!CBS_skip(cbs, length)) {
241d5028891Sjsing ASN1error(ERR_R_NESTED_ASN1_ERROR);
242d5028891Sjsing return 0;
243d5028891Sjsing }
244d5028891Sjsing return 1;
245d5028891Sjsing }
246d5028891Sjsing
247d5028891Sjsing eoc_count = 1;
248d5028891Sjsing
249d5028891Sjsing while (CBS_len(cbs) > 0) {
250d5028891Sjsing if (asn1_check_eoc(cbs)) {
251d5028891Sjsing if (--eoc_count == 0)
252d5028891Sjsing break;
253d5028891Sjsing continue;
254d5028891Sjsing }
255d5028891Sjsing if (!asn1_check_tag(cbs, &length, NULL, NULL,
256d5028891Sjsing &indefinite, NULL, -1, 0, 0)) {
257d5028891Sjsing ASN1error(ERR_R_NESTED_ASN1_ERROR);
258d5028891Sjsing return 0;
259d5028891Sjsing }
260d5028891Sjsing if (indefinite) {
261d5028891Sjsing eoc_count++;
262d5028891Sjsing continue;
263d5028891Sjsing }
264d5028891Sjsing if (!CBS_skip(cbs, length))
265d5028891Sjsing return 0;
266d5028891Sjsing }
267d5028891Sjsing
268d5028891Sjsing if (eoc_count > 0) {
269d5028891Sjsing ASN1error(ASN1_R_MISSING_EOC);
270d5028891Sjsing return 0;
271d5028891Sjsing }
272d5028891Sjsing
273d5028891Sjsing return 1;
274d5028891Sjsing }
275d5028891Sjsing
276d5028891Sjsing static int
asn1_c2i_primitive(ASN1_VALUE ** pval,CBS * content,int utype,const ASN1_ITEM * it)2776db14da9Sjsing asn1_c2i_primitive(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it)
278d5028891Sjsing {
279e0dfe61bSjsing ASN1_BOOLEAN *abool;
280bf2d4bd9Sjsing ASN1_STRING *astr;
281e0dfe61bSjsing uint8_t val;
282d5028891Sjsing int ret = 0;
283d5028891Sjsing
284d5028891Sjsing if (it->funcs != NULL)
285e0dfe61bSjsing goto err;
286d5028891Sjsing
287d5028891Sjsing if (CBS_len(content) > INT_MAX)
288e0dfe61bSjsing goto err;
289d5028891Sjsing
290d5028891Sjsing switch (utype) {
291d5028891Sjsing case V_ASN1_OBJECT:
292d5028891Sjsing if (!c2i_ASN1_OBJECT_cbs((ASN1_OBJECT **)pval, content))
293d5028891Sjsing goto err;
294d5028891Sjsing break;
295d5028891Sjsing
296d5028891Sjsing case V_ASN1_NULL:
297d5028891Sjsing if (CBS_len(content) != 0) {
298d5028891Sjsing ASN1error(ASN1_R_NULL_IS_WRONG_LENGTH);
299d5028891Sjsing goto err;
300d5028891Sjsing }
301d5028891Sjsing *pval = (ASN1_VALUE *)1;
302d5028891Sjsing break;
303d5028891Sjsing
304d5028891Sjsing case V_ASN1_BOOLEAN:
305e0dfe61bSjsing abool = (ASN1_BOOLEAN *)pval;
306d5028891Sjsing if (CBS_len(content) != 1) {
307d5028891Sjsing ASN1error(ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
308d5028891Sjsing goto err;
309d5028891Sjsing }
310e0dfe61bSjsing if (!CBS_get_u8(content, &val))
311d5028891Sjsing goto err;
312e0dfe61bSjsing *abool = val;
313d5028891Sjsing break;
314d5028891Sjsing
315d5028891Sjsing case V_ASN1_BIT_STRING:
316d5028891Sjsing if (!c2i_ASN1_BIT_STRING_cbs((ASN1_BIT_STRING **)pval, content))
317d5028891Sjsing goto err;
318d5028891Sjsing break;
319d5028891Sjsing
320d5028891Sjsing case V_ASN1_ENUMERATED:
3213664b3a8Sjsing if (!c2i_ASN1_ENUMERATED_cbs((ASN1_ENUMERATED **)pval, content))
322d5028891Sjsing goto err;
3233664b3a8Sjsing break;
3243664b3a8Sjsing
3253664b3a8Sjsing case V_ASN1_INTEGER:
3263664b3a8Sjsing if (!c2i_ASN1_INTEGER_cbs((ASN1_INTEGER **)pval, content))
3273664b3a8Sjsing goto err;
328d5028891Sjsing break;
329d5028891Sjsing
330d5028891Sjsing case V_ASN1_OCTET_STRING:
331d5028891Sjsing case V_ASN1_NUMERICSTRING:
332d5028891Sjsing case V_ASN1_PRINTABLESTRING:
333d5028891Sjsing case V_ASN1_T61STRING:
334d5028891Sjsing case V_ASN1_VIDEOTEXSTRING:
335d5028891Sjsing case V_ASN1_IA5STRING:
336d5028891Sjsing case V_ASN1_UTCTIME:
337d5028891Sjsing case V_ASN1_GENERALIZEDTIME:
338d5028891Sjsing case V_ASN1_GRAPHICSTRING:
339d5028891Sjsing case V_ASN1_VISIBLESTRING:
340d5028891Sjsing case V_ASN1_GENERALSTRING:
341d5028891Sjsing case V_ASN1_UNIVERSALSTRING:
342d5028891Sjsing case V_ASN1_BMPSTRING:
343d5028891Sjsing case V_ASN1_UTF8STRING:
344d5028891Sjsing case V_ASN1_OTHER:
345d5028891Sjsing case V_ASN1_SET:
346d5028891Sjsing case V_ASN1_SEQUENCE:
347d5028891Sjsing default:
348d5028891Sjsing if (utype == V_ASN1_BMPSTRING && (CBS_len(content) & 1)) {
349d5028891Sjsing ASN1error(ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
350d5028891Sjsing goto err;
351d5028891Sjsing }
352d5028891Sjsing if (utype == V_ASN1_UNIVERSALSTRING && (CBS_len(content) & 3)) {
353d5028891Sjsing ASN1error(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
354d5028891Sjsing goto err;
355d5028891Sjsing }
35602ba34f9Sbeck if (utype == V_ASN1_UTCTIME || utype == V_ASN1_GENERALIZEDTIME) {
35702ba34f9Sbeck if (!asn1_time_parse_cbs(content,
35802ba34f9Sbeck utype == V_ASN1_GENERALIZEDTIME, NULL)) {
35902ba34f9Sbeck ASN1error(ASN1_R_INVALID_TIME_FORMAT);
36002ba34f9Sbeck goto err;
36102ba34f9Sbeck }
36202ba34f9Sbeck }
363d5028891Sjsing /* All based on ASN1_STRING and handled the same way. */
364bf2d4bd9Sjsing if (*pval != NULL) {
365bf2d4bd9Sjsing ASN1_STRING_free((ASN1_STRING *)*pval);
366bf2d4bd9Sjsing *pval = NULL;
367bf2d4bd9Sjsing }
368bf2d4bd9Sjsing if ((astr = ASN1_STRING_type_new(utype)) == NULL) {
369d5028891Sjsing ASN1error(ERR_R_MALLOC_FAILURE);
370d5028891Sjsing goto err;
371d5028891Sjsing }
372bf2d4bd9Sjsing if (!ASN1_STRING_set(astr, CBS_data(content), CBS_len(content))) {
373bf2d4bd9Sjsing ASN1_STRING_free(astr);
374d5028891Sjsing goto err;
375d5028891Sjsing }
376bf2d4bd9Sjsing *pval = (ASN1_VALUE *)astr;
377d5028891Sjsing break;
378d5028891Sjsing }
379d5028891Sjsing
380d5028891Sjsing ret = 1;
381d5028891Sjsing
382d5028891Sjsing err:
383d5028891Sjsing return ret;
384d5028891Sjsing }
385d5028891Sjsing
386d5028891Sjsing static int
asn1_c2i_any(ASN1_VALUE ** pval,CBS * content,int utype,const ASN1_ITEM * it)3876db14da9Sjsing asn1_c2i_any(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it)
388d5028891Sjsing {
389d5028891Sjsing ASN1_TYPE *atype;
390d5028891Sjsing
391d5028891Sjsing if (it->utype != V_ASN1_ANY || it->funcs != NULL)
392d5028891Sjsing return 0;
393d5028891Sjsing
394d5028891Sjsing if (*pval != NULL) {
395d5028891Sjsing ASN1_TYPE_free((ASN1_TYPE *)*pval);
396d5028891Sjsing *pval = NULL;
397d5028891Sjsing }
398d5028891Sjsing
399d5028891Sjsing if ((atype = ASN1_TYPE_new()) == NULL)
400d5028891Sjsing return 0;
401d5028891Sjsing
4026db14da9Sjsing if (!asn1_c2i_primitive(&atype->value.asn1_value, content, utype, it)) {
403d5028891Sjsing ASN1_TYPE_free(atype);
404d5028891Sjsing return 0;
405d5028891Sjsing }
406d5028891Sjsing atype->type = utype;
407d5028891Sjsing
408d5028891Sjsing /* Fix up value for ASN.1 NULL. */
409d5028891Sjsing if (atype->type == V_ASN1_NULL)
410d5028891Sjsing atype->value.ptr = NULL;
411d5028891Sjsing
412d5028891Sjsing *pval = (ASN1_VALUE *)atype;
413d5028891Sjsing
414d5028891Sjsing return 1;
415d5028891Sjsing }
416d5028891Sjsing
417d5028891Sjsing static int
asn1_c2i(ASN1_VALUE ** pval,CBS * content,int utype,const ASN1_ITEM * it)4186db14da9Sjsing asn1_c2i(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it)
419d5028891Sjsing {
420d5028891Sjsing if (CBS_len(content) > INT_MAX)
421d5028891Sjsing return 0;
422d5028891Sjsing
423d5028891Sjsing if (it->funcs != NULL) {
424d5028891Sjsing const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
425d5028891Sjsing char free_content = 0;
426d5028891Sjsing
427d5028891Sjsing if (pf->prim_c2i == NULL)
428d5028891Sjsing return 0;
429d5028891Sjsing
430d5028891Sjsing return pf->prim_c2i(pval, CBS_data(content), CBS_len(content),
431d5028891Sjsing utype, &free_content, it);
432d5028891Sjsing }
433d5028891Sjsing
434d5028891Sjsing if (it->utype == V_ASN1_ANY)
4356db14da9Sjsing return asn1_c2i_any(pval, content, utype, it);
436d5028891Sjsing
4376db14da9Sjsing return asn1_c2i_primitive(pval, content, utype, it);
438d5028891Sjsing }
439d5028891Sjsing
440d5028891Sjsing /*
441d5028891Sjsing * Decode ASN.1 content into a primitive type. There are three possible forms -
442d5028891Sjsing * a SEQUENCE/SET/OTHER that is stored verbatim (including the ASN.1 tag and
443d5028891Sjsing * length octets), constructed objects and non-constructed objects. In the
444d5028891Sjsing * first two cases indefinite length is permitted, which we may need to handle.
445d5028891Sjsing * When this function is called the *cbs should reference the start of the
446d5028891Sjsing * ASN.1 object (i.e. the tag/length header), while *cbs_object should
447d5028891Sjsing * reference the start of the object contents (i.e. after the tag/length
448d5028891Sjsing * header. Additionally, the *cbs_object offset should be relative to the
449d5028891Sjsing * ASN.1 object being parsed. On success the *cbs will point at the octet
450d5028891Sjsing * after the object.
451d5028891Sjsing */
452d5028891Sjsing static int
asn1_d2i_primitive_content(ASN1_VALUE ** pval,CBS * cbs,CBS * cbs_object,int utype,int constructed,int indefinite,size_t length,const ASN1_ITEM * it)4536db14da9Sjsing asn1_d2i_primitive_content(ASN1_VALUE **pval, CBS *cbs, CBS *cbs_object,
45496ded9f8Sjsing int utype, int constructed, int indefinite, size_t length,
455d5028891Sjsing const ASN1_ITEM *it)
456d5028891Sjsing {
457d5028891Sjsing CBS cbs_content, cbs_initial;
458d5028891Sjsing uint8_t *data = NULL;
459d5028891Sjsing size_t data_len = 0;
460d5028891Sjsing CBB cbb;
461d5028891Sjsing int ret = 0;
462d5028891Sjsing
463d5028891Sjsing memset(&cbb, 0, sizeof(cbb));
464d5028891Sjsing
465d5028891Sjsing CBS_dup(cbs, &cbs_initial);
466d5028891Sjsing CBS_init(&cbs_content, NULL, 0);
467d5028891Sjsing
46898a0616aSjsing if (asn1_must_be_constructed(utype) && !constructed) {
469d5028891Sjsing ASN1error(ASN1_R_TYPE_NOT_CONSTRUCTED);
470d5028891Sjsing goto err;
471d5028891Sjsing }
47298a0616aSjsing if (asn1_must_be_primitive(utype) && constructed) {
47398a0616aSjsing ASN1error(ASN1_R_TYPE_NOT_PRIMITIVE);
47498a0616aSjsing goto err;
47598a0616aSjsing }
476d5028891Sjsing
477d5028891Sjsing /* SEQUENCE, SET and "OTHER" are left in encoded form. */
478d5028891Sjsing if (utype == V_ASN1_SEQUENCE || utype == V_ASN1_SET ||
479d5028891Sjsing utype == V_ASN1_OTHER) {
480d5028891Sjsing if (!asn1_find_end(cbs_object, length, indefinite))
481d5028891Sjsing goto err;
482d5028891Sjsing if (!CBS_get_bytes(&cbs_initial, &cbs_content,
483d5028891Sjsing CBS_offset(cbs_object)))
484d5028891Sjsing goto err;
485d5028891Sjsing } else if (constructed) {
486d5028891Sjsing /*
487d5028891Sjsing * Should really check the internal tags are correct but
488d5028891Sjsing * some things may get this wrong. The relevant specs
489d5028891Sjsing * say that constructed string types should be OCTET STRINGs
490d5028891Sjsing * internally irrespective of the type. So instead just check
491d5028891Sjsing * for UNIVERSAL class and ignore the tag.
492d5028891Sjsing */
493d5028891Sjsing if (!CBB_init(&cbb, 0))
494d5028891Sjsing goto err;
495d5028891Sjsing if (!asn1_collect(&cbb, cbs_object, indefinite, -1,
496d5028891Sjsing V_ASN1_UNIVERSAL, 0))
497d5028891Sjsing goto err;
498d5028891Sjsing if (!CBB_finish(&cbb, &data, &data_len))
499d5028891Sjsing goto err;
500d5028891Sjsing
501d5028891Sjsing CBS_init(&cbs_content, data, data_len);
502d5028891Sjsing } else {
503d5028891Sjsing if (!CBS_get_bytes(cbs_object, &cbs_content, length))
504d5028891Sjsing goto err;
505d5028891Sjsing }
506d5028891Sjsing
5076db14da9Sjsing if (!asn1_c2i(pval, &cbs_content, utype, it))
508d5028891Sjsing goto err;
509d5028891Sjsing
510d5028891Sjsing if (!CBS_skip(cbs, CBS_offset(cbs_object)))
511d5028891Sjsing goto err;
512d5028891Sjsing
513d5028891Sjsing ret = 1;
514d5028891Sjsing
515d5028891Sjsing err:
516d5028891Sjsing CBB_cleanup(&cbb);
517d5028891Sjsing freezero(data, data_len);
518ecad301fSjsing
519ecad301fSjsing return ret;
520da347917Sbeck }
521da347917Sbeck
52255f5b47bSinoguchi static int
asn1_d2i_any(ASN1_VALUE ** pval,CBS * cbs,const ASN1_ITEM * it,int tag_number,int tag_class,int optional)5236db14da9Sjsing asn1_d2i_any(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it,
52496ded9f8Sjsing int tag_number, int tag_class, int optional)
525d5028891Sjsing {
52696ded9f8Sjsing int constructed, indefinite;
52796ded9f8Sjsing uint8_t object_class;
528d5028891Sjsing int object_type;
529d5028891Sjsing CBS cbs_object;
530d5028891Sjsing size_t length;
531d5028891Sjsing
532d5028891Sjsing CBS_init(&cbs_object, CBS_data(cbs), CBS_len(cbs));
533d5028891Sjsing
534d5028891Sjsing if (it->utype != V_ASN1_ANY)
535d5028891Sjsing return 0;
536d5028891Sjsing
537d5028891Sjsing if (tag_number >= 0) {
538d5028891Sjsing ASN1error(ASN1_R_ILLEGAL_TAGGED_ANY);
539d5028891Sjsing return 0;
540d5028891Sjsing }
541d5028891Sjsing if (optional) {
542d5028891Sjsing ASN1error(ASN1_R_ILLEGAL_OPTIONAL_ANY);
543d5028891Sjsing return 0;
544d5028891Sjsing }
545d5028891Sjsing
546d5028891Sjsing /* Determine type from ASN.1 tag. */
547d5028891Sjsing if (asn1_check_tag(&cbs_object, &length, &object_type, &object_class,
548d5028891Sjsing &indefinite, &constructed, -1, 0, 0) != 1) {
549d5028891Sjsing ASN1error(ERR_R_NESTED_ASN1_ERROR);
550d5028891Sjsing return 0;
551d5028891Sjsing }
552d5028891Sjsing if (object_class != V_ASN1_UNIVERSAL)
553d5028891Sjsing object_type = V_ASN1_OTHER;
554d5028891Sjsing
5556db14da9Sjsing return asn1_d2i_primitive_content(pval, cbs, &cbs_object, object_type,
556d5028891Sjsing constructed, indefinite, length, it);
557d5028891Sjsing }
558d5028891Sjsing
559d5028891Sjsing static int
asn1_d2i_mstring(ASN1_VALUE ** pval,CBS * cbs,const ASN1_ITEM * it,int tag_number,int tag_class,int optional)5606db14da9Sjsing asn1_d2i_mstring(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it,
56196ded9f8Sjsing int tag_number, int tag_class, int optional)
562d5028891Sjsing {
56396ded9f8Sjsing int constructed, indefinite;
56496ded9f8Sjsing uint8_t object_class;
565d5028891Sjsing int object_tag;
566d5028891Sjsing CBS cbs_object;
567d5028891Sjsing size_t length;
568d5028891Sjsing
569d5028891Sjsing CBS_init(&cbs_object, CBS_data(cbs), CBS_len(cbs));
570d5028891Sjsing
571d5028891Sjsing /*
572d5028891Sjsing * It never makes sense for multi-strings to have implicit tagging, so
573d5028891Sjsing * if tag_number != -1, then this looks like an error in the template.
574d5028891Sjsing */
575d5028891Sjsing if (tag_number != -1) {
576d5028891Sjsing ASN1error(ASN1_R_BAD_TEMPLATE);
577d5028891Sjsing return 0;
578d5028891Sjsing }
579d5028891Sjsing
580d5028891Sjsing if (asn1_check_tag(&cbs_object, &length, &object_tag, &object_class,
581d5028891Sjsing &indefinite, &constructed, -1, 0, 1) != 1) {
582d5028891Sjsing ASN1error(ERR_R_NESTED_ASN1_ERROR);
583d5028891Sjsing return 0;
584d5028891Sjsing }
585d5028891Sjsing
586d5028891Sjsing /* Class must be UNIVERSAL. */
587d5028891Sjsing if (object_class != V_ASN1_UNIVERSAL) {
588d5028891Sjsing if (optional)
589d5028891Sjsing return -1;
590d5028891Sjsing ASN1error(ASN1_R_MSTRING_NOT_UNIVERSAL);
591d5028891Sjsing return 0;
592d5028891Sjsing }
593d5028891Sjsing /* Check tag matches bit map. */
594d5028891Sjsing if ((ASN1_tag2bit(object_tag) & it->utype) == 0) {
595d5028891Sjsing if (optional)
596d5028891Sjsing return -1;
597d5028891Sjsing ASN1error(ASN1_R_MSTRING_WRONG_TAG);
598d5028891Sjsing return 0;
599d5028891Sjsing }
600d5028891Sjsing
6016db14da9Sjsing return asn1_d2i_primitive_content(pval, cbs, &cbs_object,
602d5028891Sjsing object_tag, constructed, indefinite, length, it);
603d5028891Sjsing }
604d5028891Sjsing
605d5028891Sjsing static int
asn1_d2i_primitive(ASN1_VALUE ** pval,CBS * cbs,const ASN1_ITEM * it,int tag_number,int tag_class,int optional)6066db14da9Sjsing asn1_d2i_primitive(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it,
60796ded9f8Sjsing int tag_number, int tag_class, int optional)
608d5028891Sjsing {
609d5028891Sjsing CBS cbs_object;
61096ded9f8Sjsing int constructed, indefinite;
611d5028891Sjsing int utype = it->utype;
612d5028891Sjsing size_t length;
613d5028891Sjsing int ret;
614d5028891Sjsing
615d5028891Sjsing CBS_init(&cbs_object, CBS_data(cbs), CBS_len(cbs));
616d5028891Sjsing
617d5028891Sjsing if (it->itype == ASN1_ITYPE_MSTRING)
618d5028891Sjsing return 0;
619d5028891Sjsing
620d5028891Sjsing if (it->utype == V_ASN1_ANY)
6216db14da9Sjsing return asn1_d2i_any(pval, cbs, it, tag_number, tag_class, optional);
622d5028891Sjsing
623d5028891Sjsing if (tag_number == -1) {
624d5028891Sjsing tag_number = it->utype;
625d5028891Sjsing tag_class = V_ASN1_UNIVERSAL;
626d5028891Sjsing }
627d5028891Sjsing
628d5028891Sjsing ret = asn1_check_tag(&cbs_object, &length, NULL, NULL, &indefinite,
629d5028891Sjsing &constructed, tag_number, tag_class, optional);
630d5028891Sjsing if (ret == -1)
631d5028891Sjsing return -1;
632d5028891Sjsing if (ret != 1) {
633d5028891Sjsing ASN1error(ERR_R_NESTED_ASN1_ERROR);
634d5028891Sjsing return 0;
635d5028891Sjsing }
636d5028891Sjsing
6376db14da9Sjsing return asn1_d2i_primitive_content(pval, cbs, &cbs_object, utype,
638d5028891Sjsing constructed, indefinite, length, it);
639d5028891Sjsing }
640d5028891Sjsing
641d5028891Sjsing static int
asn1_item_d2i_choice(ASN1_VALUE ** pval,CBS * cbs,const ASN1_ITEM * it,int tag_number,int tag_class,int optional,int depth)6426db14da9Sjsing asn1_item_d2i_choice(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it,
64396ded9f8Sjsing int tag_number, int tag_class, int optional, int depth)
644da347917Sbeck {
64596903d9fSjsing const ASN1_TEMPLATE *at, *errat = NULL;
6469d9e8f70Sjsing const ASN1_AUX *aux;
6472dd6aa12Stb ASN1_aux_cb *asn1_cb = NULL;
648b4cd7288Sjsing ASN1_VALUE *achoice = NULL;
6494f242a39Smiod ASN1_VALUE **pchptr;
650b4cd7288Sjsing int i, ret;
651dcf2ad1cStedu
6529d9e8f70Sjsing if ((aux = it->funcs) != NULL)
6532960f0cdSjsing asn1_cb = aux->asn1_cb;
6542960f0cdSjsing
655444ada83Sjsing if (it->itype != ASN1_ITYPE_CHOICE)
656444ada83Sjsing goto err;
6575673d407Stedu
658bb15212cStb /*
659b4cd7288Sjsing * It never makes sense for CHOICE types to have implicit tagging, so
660b4cd7288Sjsing * if tag_number != -1, then this looks like an error in the template.
661bb15212cStb */
662b4cd7288Sjsing if (tag_number != -1) {
663bb15212cStb ASN1error(ASN1_R_BAD_TEMPLATE);
664bb15212cStb goto err;
665bb15212cStb }
666bb15212cStb
667b4cd7288Sjsing if (*pval != NULL) {
668b4cd7288Sjsing ASN1_item_ex_free(pval, it);
669b4cd7288Sjsing *pval = NULL;
6703e1f01a5Stedu }
671b4cd7288Sjsing
672b4cd7288Sjsing if (!ASN1_item_ex_new(&achoice, it)) {
6735067ae9fSbeck ASN1error(ERR_R_NESTED_ASN1_ERROR);
674da347917Sbeck goto err;
675da347917Sbeck }
6762960f0cdSjsing
6772960f0cdSjsing if (asn1_cb != NULL && !asn1_cb(ASN1_OP_D2I_PRE, &achoice, it, NULL)) {
6782960f0cdSjsing ASN1error(ASN1_R_AUX_ERROR);
6792960f0cdSjsing goto err;
680b4cd7288Sjsing }
681b4cd7288Sjsing
682b4cd7288Sjsing /* Try each possible CHOICE in turn. */
68396903d9fSjsing for (i = 0; i < it->tcount; i++) {
68496903d9fSjsing at = &it->templates[i];
68596903d9fSjsing
68696903d9fSjsing pchptr = asn1_get_field_ptr(&achoice, at);
687b4cd7288Sjsing
688b4cd7288Sjsing /* Mark field as OPTIONAL so its absence can be identified. */
68996903d9fSjsing ret = asn1_template_d2i(pchptr, cbs, at, 1, depth);
6904fcf65c5Sdjm if (ret == -1)
6914fcf65c5Sdjm continue;
692b4cd7288Sjsing if (ret != 1) {
6935067ae9fSbeck ASN1error(ERR_R_NESTED_ASN1_ERROR);
69496903d9fSjsing errat = at;
695da347917Sbeck goto err;
696da347917Sbeck }
6974fcf65c5Sdjm
698b4cd7288Sjsing /* We've successfully decoded an ASN.1 object. */
699b4cd7288Sjsing asn1_set_choice_selector(&achoice, i, it);
700b4cd7288Sjsing break;
701b4cd7288Sjsing }
702b4cd7288Sjsing
703da347917Sbeck /* Did we fall off the end without reading anything? */
704cc777fd4Stedu if (i == it->tcount) {
705b4cd7288Sjsing if (optional) {
706b4cd7288Sjsing ASN1_item_ex_free(&achoice, it);
707da347917Sbeck return -1;
708da347917Sbeck }
7095067ae9fSbeck ASN1error(ASN1_R_NO_MATCHING_CHOICE_TYPE);
710da347917Sbeck goto err;
711da347917Sbeck }
7124fcf65c5Sdjm
713b4cd7288Sjsing if (asn1_cb != NULL && !asn1_cb(ASN1_OP_D2I_POST, &achoice, it, NULL)) {
714b4cd7288Sjsing ASN1error(ASN1_R_AUX_ERROR);
715b4cd7288Sjsing goto err;
716b4cd7288Sjsing }
717b4cd7288Sjsing
718b4cd7288Sjsing *pval = achoice;
719b4cd7288Sjsing achoice = NULL;
720b4cd7288Sjsing
721da347917Sbeck return 1;
722da347917Sbeck
723444ada83Sjsing err:
724b4cd7288Sjsing ASN1_item_ex_free(&achoice, it);
7255a79a2abSjsing
72696903d9fSjsing if (errat != NULL)
72796903d9fSjsing ERR_asprintf_error_data("Field=%s, Type=%s", errat->field_name,
728444ada83Sjsing it->sname);
729444ada83Sjsing else
730444ada83Sjsing ERR_asprintf_error_data("Type=%s", it->sname);
731444ada83Sjsing
73269e6d811Sjsing return 0;
73369e6d811Sjsing }
73469e6d811Sjsing
73569e6d811Sjsing static int
asn1_item_d2i_sequence(ASN1_VALUE ** pval,CBS * cbs,const ASN1_ITEM * it,int tag_number,int tag_class,int optional,int depth)7366db14da9Sjsing asn1_item_d2i_sequence(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it,
73796ded9f8Sjsing int tag_number, int tag_class, int optional, int depth)
738444ada83Sjsing {
7395ace30b5Sjob CBS cbs_seq, cbs_seq_content, cbs_object;
74096ded9f8Sjsing int constructed, indefinite, optional_field;
74196903d9fSjsing const ASN1_TEMPLATE *errat = NULL;
74296903d9fSjsing const ASN1_TEMPLATE *seqat, *at;
743444ada83Sjsing ASN1_aux_cb *asn1_cb = NULL;
7449d9e8f70Sjsing const ASN1_AUX *aux;
7459d9e8f70Sjsing ASN1_VALUE *aseq = NULL;
7469d9e8f70Sjsing ASN1_VALUE **pseqval;
7479d9e8f70Sjsing int eoc_needed, i;
7489d9e8f70Sjsing size_t length;
749444ada83Sjsing int ret = 0;
750444ada83Sjsing
7519d9e8f70Sjsing CBS_init(&cbs_seq, CBS_data(cbs), CBS_len(cbs));
7529d9e8f70Sjsing
7539d9e8f70Sjsing if ((aux = it->funcs) != NULL)
7549d9e8f70Sjsing asn1_cb = aux->asn1_cb;
7559d9e8f70Sjsing
756444ada83Sjsing if (it->itype != ASN1_ITYPE_NDEF_SEQUENCE &&
757444ada83Sjsing it->itype != ASN1_ITYPE_SEQUENCE)
758444ada83Sjsing goto err;
759444ada83Sjsing
7609d9e8f70Sjsing if (*pval != NULL) {
7619d9e8f70Sjsing ASN1_item_ex_free(pval, it);
7629d9e8f70Sjsing *pval = NULL;
763da347917Sbeck }
7649d9e8f70Sjsing
7659d9e8f70Sjsing /* If no IMPLICIT tagging use UNIVERSAL/SEQUENCE. */
7669d9e8f70Sjsing if (tag_number == -1) {
7679d9e8f70Sjsing tag_class = V_ASN1_UNIVERSAL;
7689d9e8f70Sjsing tag_number = V_ASN1_SEQUENCE;
7699d9e8f70Sjsing }
7709d9e8f70Sjsing
7719d9e8f70Sjsing /* Read ASN.1 SEQUENCE header. */
772ecad301fSjsing ret = asn1_check_tag(&cbs_seq, &length, NULL, NULL, &indefinite,
7739d9e8f70Sjsing &constructed, tag_number, tag_class, optional);
7749d9e8f70Sjsing if (ret == -1)
7759d9e8f70Sjsing return -1;
7769d9e8f70Sjsing if (ret != 1) {
7775067ae9fSbeck ASN1error(ERR_R_NESTED_ASN1_ERROR);
778da347917Sbeck goto err;
7799d9e8f70Sjsing }
7809d9e8f70Sjsing
7819d9e8f70Sjsing if (!constructed) {
7825067ae9fSbeck ASN1error(ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
783da347917Sbeck goto err;
784da347917Sbeck }
785da347917Sbeck
7869d9e8f70Sjsing if (indefinite) {
7879d9e8f70Sjsing eoc_needed = 1;
7889d9e8f70Sjsing CBS_init(&cbs_seq_content, CBS_data(&cbs_seq), CBS_len(&cbs_seq));
7899d9e8f70Sjsing } else {
7909d9e8f70Sjsing eoc_needed = 0;
7919d9e8f70Sjsing if (!CBS_get_bytes(&cbs_seq, &cbs_seq_content, length))
7929d9e8f70Sjsing goto err;
7939d9e8f70Sjsing }
7949d9e8f70Sjsing
7959d9e8f70Sjsing if (!ASN1_item_ex_new(&aseq, it)) {
7965067ae9fSbeck ASN1error(ERR_R_NESTED_ASN1_ERROR);
797da347917Sbeck goto err;
798da347917Sbeck }
7994fcf65c5Sdjm
8009d9e8f70Sjsing if (asn1_cb != NULL && !asn1_cb(ASN1_OP_D2I_PRE, &aseq, it, NULL)) {
8019d9e8f70Sjsing ASN1error(ASN1_R_AUX_ERROR);
8023e1f01a5Stedu goto err;
8033e1f01a5Stedu }
8043e1f01a5Stedu
80596903d9fSjsing for (i = 0; i < it->tcount; i++) {
80696903d9fSjsing at = &it->templates[i];
80796903d9fSjsing
808ecad301fSjsing if (asn1_check_eoc(&cbs_seq_content)) {
8099d9e8f70Sjsing if (!indefinite) {
8105067ae9fSbeck ASN1error(ASN1_R_UNEXPECTED_EOC);
811da347917Sbeck goto err;
812da347917Sbeck }
8139d9e8f70Sjsing eoc_needed = 0;
814da347917Sbeck break;
815da347917Sbeck }
8169d9e8f70Sjsing if (CBS_len(&cbs_seq_content) == 0)
8179d9e8f70Sjsing break;
8184fcf65c5Sdjm
81996903d9fSjsing if ((seqat = asn1_do_adb(&aseq, at, 1)) == NULL)
820da347917Sbeck goto err;
8219d9e8f70Sjsing
82296903d9fSjsing pseqval = asn1_get_field_ptr(&aseq, seqat);
8239d9e8f70Sjsing
8249d9e8f70Sjsing /*
8259d9e8f70Sjsing * This was originally implemented to "increase efficiency",
8269d9e8f70Sjsing * however it currently needs to remain since it papers over
8279d9e8f70Sjsing * the use of ASN.1 ANY with OPTIONAL in SEQUENCEs (which
8286db14da9Sjsing * asn1_d2i_primitive() currently rejects).
829da347917Sbeck */
83096903d9fSjsing optional_field = (seqat->flags & ASN1_TFLG_OPTIONAL) != 0;
8319d9e8f70Sjsing if (i == it->tcount - 1)
8329d9e8f70Sjsing optional_field = 0;
8339d9e8f70Sjsing
8346db14da9Sjsing ret = asn1_template_d2i(pseqval, &cbs_seq_content,
83596903d9fSjsing seqat, optional_field, depth);
8369d9e8f70Sjsing if (ret == -1) {
8379d9e8f70Sjsing /* Absent OPTIONAL component. */
83896903d9fSjsing ASN1_template_free(pseqval, seqat);
839da347917Sbeck continue;
840da347917Sbeck }
8419d9e8f70Sjsing if (ret != 1) {
84296903d9fSjsing errat = seqat;
8439d9e8f70Sjsing goto err;
8449d9e8f70Sjsing }
845da347917Sbeck }
8464fcf65c5Sdjm
847ecad301fSjsing if (eoc_needed && !asn1_check_eoc(&cbs_seq_content)) {
8485067ae9fSbeck ASN1error(ASN1_R_MISSING_EOC);
849da347917Sbeck goto err;
850da347917Sbeck }
8519d9e8f70Sjsing
8529d9e8f70Sjsing if (indefinite) {
8539d9e8f70Sjsing if (!CBS_skip(&cbs_seq, CBS_offset(&cbs_seq_content)))
8549d9e8f70Sjsing goto err;
8559d9e8f70Sjsing } else if (CBS_len(&cbs_seq_content) != 0) {
8565067ae9fSbeck ASN1error(ASN1_R_SEQUENCE_LENGTH_MISMATCH);
857da347917Sbeck goto err;
858da347917Sbeck }
859da347917Sbeck
8609d9e8f70Sjsing /*
8619d9e8f70Sjsing * There is no more data in the ASN.1 SEQUENCE, however we may not have
8629d9e8f70Sjsing * populated all fields - check that any remaining are OPTIONAL.
863da347917Sbeck */
86496903d9fSjsing for (; i < it->tcount; i++) {
86596903d9fSjsing at = &it->templates[i];
86696903d9fSjsing
86796903d9fSjsing if ((seqat = asn1_do_adb(&aseq, at, 1)) == NULL)
8684fcf65c5Sdjm goto err;
8699d9e8f70Sjsing
87096903d9fSjsing if ((seqat->flags & ASN1_TFLG_OPTIONAL) == 0) {
8715067ae9fSbeck ASN1error(ASN1_R_FIELD_MISSING);
87296903d9fSjsing errat = seqat;
873da347917Sbeck goto err;
874da347917Sbeck }
8759d9e8f70Sjsing
8769d9e8f70Sjsing /* XXX - this is probably unnecessary with earlier free. */
87796903d9fSjsing pseqval = asn1_get_field_ptr(&aseq, seqat);
87896903d9fSjsing ASN1_template_free(pseqval, seqat);
879da347917Sbeck }
8809d9e8f70Sjsing
8815ace30b5Sjob if (!CBS_get_bytes(cbs, &cbs_object, CBS_offset(&cbs_seq)))
8829d9e8f70Sjsing goto err;
8839d9e8f70Sjsing
8845ace30b5Sjob if (!asn1_enc_save(&aseq, &cbs_object, it)) {
8855ace30b5Sjob ASN1error(ERR_R_MALLOC_FAILURE);
8865ace30b5Sjob goto err;
8875ace30b5Sjob }
8885ace30b5Sjob
8899d9e8f70Sjsing if (asn1_cb != NULL && !asn1_cb(ASN1_OP_D2I_POST, &aseq, it, NULL)) {
8909d9e8f70Sjsing ASN1error(ASN1_R_AUX_ERROR);
8919d9e8f70Sjsing goto err;
8929d9e8f70Sjsing }
8939d9e8f70Sjsing
8949d9e8f70Sjsing *pval = aseq;
8959d9e8f70Sjsing aseq = NULL;
8969d9e8f70Sjsing
897da347917Sbeck return 1;
898da347917Sbeck
899da347917Sbeck err:
9009d9e8f70Sjsing ASN1_item_ex_free(&aseq, it);
9015a79a2abSjsing
90296903d9fSjsing if (errat != NULL)
90396903d9fSjsing ERR_asprintf_error_data("Field=%s, Type=%s", errat->field_name,
9040f637b92Sbeck it->sname);
9054fcf65c5Sdjm else
9060f637b92Sbeck ERR_asprintf_error_data("Type=%s", it->sname);
907da347917Sbeck
90869e6d811Sjsing return 0;
90969e6d811Sjsing }
91069e6d811Sjsing
911892fb814Sjsing static int
asn1_item_d2i_extern(ASN1_VALUE ** pval,CBS * cbs,const ASN1_ITEM * it,int tag_number,int tag_class,int optional)912892fb814Sjsing asn1_item_d2i_extern(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it,
91396ded9f8Sjsing int tag_number, int tag_class, int optional)
914892fb814Sjsing {
915892fb814Sjsing const ASN1_EXTERN_FUNCS *ef = it->funcs;
916892fb814Sjsing const unsigned char *p = NULL;
917892fb814Sjsing ASN1_TLC ctx = { 0 };
918892fb814Sjsing int ret = 0;
919892fb814Sjsing
920892fb814Sjsing if (CBS_len(cbs) > LONG_MAX)
921892fb814Sjsing return 0;
922892fb814Sjsing
923892fb814Sjsing p = CBS_data(cbs);
924892fb814Sjsing
925892fb814Sjsing if ((ret = ef->asn1_ex_d2i(pval, &p, (long)CBS_len(cbs), it,
926892fb814Sjsing tag_number, tag_class, optional, &ctx)) == 1) {
927892fb814Sjsing if (!CBS_skip(cbs, p - CBS_data(cbs)))
928892fb814Sjsing goto err;
929892fb814Sjsing }
930892fb814Sjsing return ret;
931892fb814Sjsing
932892fb814Sjsing err:
933892fb814Sjsing ASN1_item_ex_free(pval, it);
934892fb814Sjsing
935892fb814Sjsing ERR_asprintf_error_data("Type=%s", it->sname);
936892fb814Sjsing
937892fb814Sjsing return 0;
938892fb814Sjsing }
939892fb814Sjsing
940444ada83Sjsing static int
asn1_item_d2i(ASN1_VALUE ** pval,CBS * cbs,const ASN1_ITEM * it,int tag_number,int tag_class,int optional,int depth)9416db14da9Sjsing asn1_item_d2i(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it,
94296ded9f8Sjsing int tag_number, int tag_class, int optional, int depth)
943444ada83Sjsing {
94469e6d811Sjsing if (pval == NULL)
945444ada83Sjsing return 0;
946444ada83Sjsing
947444ada83Sjsing if (++depth > ASN1_MAX_CONSTRUCTED_NEST) {
948444ada83Sjsing ASN1error(ASN1_R_NESTED_TOO_DEEP);
949444ada83Sjsing goto err;
950444ada83Sjsing }
951444ada83Sjsing
952444ada83Sjsing switch (it->itype) {
953444ada83Sjsing case ASN1_ITYPE_PRIMITIVE:
95469e6d811Sjsing if (it->templates != NULL) {
95569e6d811Sjsing /*
95669e6d811Sjsing * Tagging or OPTIONAL is currently illegal on an item
957444ada83Sjsing * template because the flags can't get passed down.
958444ada83Sjsing * In practice this isn't a problem: we include the
959444ada83Sjsing * relevant flags from the item template in the
960444ada83Sjsing * template itself.
961444ada83Sjsing */
96269e6d811Sjsing if (tag_number != -1 || optional) {
963444ada83Sjsing ASN1error(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
964444ada83Sjsing goto err;
965444ada83Sjsing }
9666db14da9Sjsing return asn1_template_d2i(pval, cbs, it->templates,
9676db14da9Sjsing optional, depth);
968444ada83Sjsing }
9696db14da9Sjsing return asn1_d2i_primitive(pval, cbs, it, tag_number, tag_class,
9706db14da9Sjsing optional);
971444ada83Sjsing
972444ada83Sjsing case ASN1_ITYPE_MSTRING:
9736db14da9Sjsing return asn1_d2i_mstring(pval, cbs, it, tag_number, tag_class,
974f4540edcSjsing optional);
975444ada83Sjsing
976444ada83Sjsing case ASN1_ITYPE_EXTERN:
977892fb814Sjsing return asn1_item_d2i_extern(pval, cbs, it, tag_number,
978892fb814Sjsing tag_class, optional);
979444ada83Sjsing
980444ada83Sjsing case ASN1_ITYPE_CHOICE:
9816db14da9Sjsing return asn1_item_d2i_choice(pval, cbs, it, tag_number,
98269e6d811Sjsing tag_class, optional, depth);
983444ada83Sjsing
984444ada83Sjsing case ASN1_ITYPE_NDEF_SEQUENCE:
985444ada83Sjsing case ASN1_ITYPE_SEQUENCE:
9866db14da9Sjsing return asn1_item_d2i_sequence(pval, cbs, it, tag_number,
98769e6d811Sjsing tag_class, optional, depth);
988444ada83Sjsing
989444ada83Sjsing default:
990444ada83Sjsing return 0;
991444ada83Sjsing }
992444ada83Sjsing
993444ada83Sjsing err:
994444ada83Sjsing ASN1_item_ex_free(pval, it);
995444ada83Sjsing
996444ada83Sjsing ERR_asprintf_error_data("Type=%s", it->sname);
997444ada83Sjsing
998444ada83Sjsing return 0;
999444ada83Sjsing }
1000444ada83Sjsing
1001ecad301fSjsing static void
asn1_template_stack_of_free(STACK_OF (ASN1_VALUE)* avals,const ASN1_TEMPLATE * at)10023069054eSjsing asn1_template_stack_of_free(STACK_OF(ASN1_VALUE) *avals,
10033069054eSjsing const ASN1_TEMPLATE *at)
10043069054eSjsing {
1005ecad301fSjsing ASN1_VALUE *aval;
1006ecad301fSjsing
1007ecad301fSjsing if (avals == NULL)
1008ecad301fSjsing return;
1009ecad301fSjsing
1010ecad301fSjsing while (sk_ASN1_VALUE_num(avals) > 0) {
1011ecad301fSjsing aval = sk_ASN1_VALUE_pop(avals);
101296903d9fSjsing ASN1_item_ex_free(&aval, at->item);
1013ecad301fSjsing }
1014ecad301fSjsing sk_ASN1_VALUE_free(avals);
1015ecad301fSjsing }
1016ecad301fSjsing
101704a37b9bSjsing static int
asn1_template_stack_of_d2i(ASN1_VALUE ** pval,CBS * cbs,const ASN1_TEMPLATE * at,int optional,int depth)101896903d9fSjsing asn1_template_stack_of_d2i(ASN1_VALUE **pval, CBS *cbs, const ASN1_TEMPLATE *at,
101996ded9f8Sjsing int optional, int depth)
102069e6d811Sjsing {
1021ecad301fSjsing CBS cbs_object, cbs_object_content;
1022ecad301fSjsing STACK_OF(ASN1_VALUE) *avals = NULL;
1023ecad301fSjsing ASN1_VALUE *aval = NULL;
1024ecad301fSjsing int tag_number, tag_class;
1025ecad301fSjsing int eoc_needed;
102696ded9f8Sjsing int indefinite;
1027ecad301fSjsing size_t length;
102869e6d811Sjsing int ret;
102969e6d811Sjsing
1030ecad301fSjsing CBS_init(&cbs_object, CBS_data(cbs), CBS_len(cbs));
1031ecad301fSjsing
1032ecad301fSjsing if (pval == NULL)
103369e6d811Sjsing return 0;
103469e6d811Sjsing
103596903d9fSjsing asn1_template_stack_of_free((STACK_OF(ASN1_VALUE) *)*pval, at);
1036ecad301fSjsing *pval = NULL;
1037ecad301fSjsing
103896903d9fSjsing tag_number = at->tag;
103996903d9fSjsing tag_class = at->flags & ASN1_TFLG_TAG_CLASS;
1040ecad301fSjsing
1041ecad301fSjsing /* Determine the inner tag value for SET OF or SEQUENCE OF. */
104296903d9fSjsing if ((at->flags & ASN1_TFLG_IMPTAG) == 0) {
1043ecad301fSjsing tag_number = V_ASN1_SEQUENCE;
1044ecad301fSjsing tag_class = V_ASN1_UNIVERSAL;
104596903d9fSjsing if ((at->flags & ASN1_TFLG_SET_OF) != 0)
1046ecad301fSjsing tag_number = V_ASN1_SET;
104769e6d811Sjsing }
104869e6d811Sjsing
1049ecad301fSjsing ret = asn1_check_tag(&cbs_object, &length, NULL, NULL, &indefinite,
1050ecad301fSjsing NULL, tag_number, tag_class, optional);
1051ecad301fSjsing if (ret == -1)
1052ecad301fSjsing return -1;
1053ecad301fSjsing if (ret != 1) {
10545067ae9fSbeck ASN1error(ERR_R_NESTED_ASN1_ERROR);
1055da347917Sbeck return 0;
1056da347917Sbeck }
1057da347917Sbeck
1058ecad301fSjsing if (indefinite) {
1059ecad301fSjsing eoc_needed = 1;
1060ecad301fSjsing CBS_init(&cbs_object_content, CBS_data(&cbs_object),
1061ecad301fSjsing CBS_len(&cbs_object));
1062ecad301fSjsing } else {
1063ecad301fSjsing eoc_needed = 0;
1064ecad301fSjsing if (!CBS_get_bytes(&cbs_object, &cbs_object_content,
1065ecad301fSjsing length))
1066ecad301fSjsing goto err;
1067ecad301fSjsing }
1068ecad301fSjsing
1069ecad301fSjsing if ((avals = sk_ASN1_VALUE_new_null()) == NULL) {
10705067ae9fSbeck ASN1error(ERR_R_MALLOC_FAILURE);
1071da347917Sbeck goto err;
1072da347917Sbeck }
10734fcf65c5Sdjm
1074ecad301fSjsing /* Read as many items as possible. */
1075ecad301fSjsing while (CBS_len(&cbs_object_content) > 0) {
1076ecad301fSjsing if (asn1_check_eoc(&cbs_object_content)) {
1077ecad301fSjsing if (!eoc_needed) {
10785067ae9fSbeck ASN1error(ASN1_R_UNEXPECTED_EOC);
1079da347917Sbeck goto err;
1080da347917Sbeck }
1081ecad301fSjsing eoc_needed = 0;
1082da347917Sbeck break;
1083da347917Sbeck }
10843069054eSjsing if (!asn1_item_d2i(&aval, &cbs_object_content, at->item, -1, 0,
10853069054eSjsing 0, depth)) {
10865067ae9fSbeck ASN1error(ERR_R_NESTED_ASN1_ERROR);
1087da347917Sbeck goto err;
1088da347917Sbeck }
1089ecad301fSjsing if (!sk_ASN1_VALUE_push(avals, aval)) {
10905067ae9fSbeck ASN1error(ERR_R_MALLOC_FAILURE);
1091da347917Sbeck goto err;
1092da347917Sbeck }
1093ecad301fSjsing aval = NULL;
1094da347917Sbeck }
1095ecad301fSjsing if (eoc_needed) {
10965067ae9fSbeck ASN1error(ASN1_R_MISSING_EOC);
1097da347917Sbeck goto err;
1098da347917Sbeck }
109982ebfa93Sjsing
1100ecad301fSjsing if (indefinite) {
1101ecad301fSjsing if (!CBS_skip(&cbs_object, CBS_offset(&cbs_object_content)))
1102ecad301fSjsing goto err;
1103ecad301fSjsing }
1104ecad301fSjsing
1105ecad301fSjsing if (!CBS_skip(cbs, CBS_offset(&cbs_object)))
1106ecad301fSjsing goto err;
1107ecad301fSjsing
1108ecad301fSjsing *pval = (ASN1_VALUE *)avals;
1109ecad301fSjsing avals = NULL;
1110ecad301fSjsing
111182ebfa93Sjsing return 1;
111282ebfa93Sjsing
111382ebfa93Sjsing err:
111496903d9fSjsing asn1_template_stack_of_free(avals, at);
111596903d9fSjsing ASN1_item_ex_free(&aval, at->item);
1116ecad301fSjsing
111782ebfa93Sjsing return 0;
1118da347917Sbeck }
1119da347917Sbeck
112082ebfa93Sjsing static int
asn1_template_noexp_d2i(ASN1_VALUE ** pval,CBS * cbs,const ASN1_TEMPLATE * at,int optional,int depth)112196903d9fSjsing asn1_template_noexp_d2i(ASN1_VALUE **pval, CBS *cbs, const ASN1_TEMPLATE *at,
112296ded9f8Sjsing int optional, int depth)
112382ebfa93Sjsing {
112482ebfa93Sjsing int tag_number, tag_class;
112582ebfa93Sjsing int ret;
112682ebfa93Sjsing
1127ecad301fSjsing if (pval == NULL)
112882ebfa93Sjsing return 0;
112982ebfa93Sjsing
113096903d9fSjsing if ((at->flags & ASN1_TFLG_SK_MASK) != 0)
113196903d9fSjsing return asn1_template_stack_of_d2i(pval, cbs, at, optional, depth);
113282ebfa93Sjsing
113382ebfa93Sjsing tag_number = -1;
113482ebfa93Sjsing tag_class = V_ASN1_UNIVERSAL;
113582ebfa93Sjsing
113682ebfa93Sjsing /* See if we need to use IMPLICIT tagging. */
113796903d9fSjsing if ((at->flags & ASN1_TFLG_IMPTAG) != 0) {
113896903d9fSjsing tag_number = at->tag;
113996903d9fSjsing tag_class = at->flags & ASN1_TFLG_TAG_CLASS;
114082ebfa93Sjsing }
114182ebfa93Sjsing
114296903d9fSjsing ret = asn1_item_d2i(pval, cbs, at->item, tag_number, tag_class,
1143ecad301fSjsing optional, depth);
1144ecad301fSjsing if (ret == -1)
1145ecad301fSjsing return -1;
1146ecad301fSjsing if (ret != 1) {
114782ebfa93Sjsing ASN1error(ERR_R_NESTED_ASN1_ERROR);
114882ebfa93Sjsing goto err;
1149ecad301fSjsing }
115082ebfa93Sjsing
1151da347917Sbeck return 1;
1152da347917Sbeck
1153da347917Sbeck err:
1154ecad301fSjsing /* XXX - The called function should have freed already. */
115596903d9fSjsing ASN1_template_free(pval, at);
1156da347917Sbeck return 0;
1157da347917Sbeck }
1158da347917Sbeck
115904a37b9bSjsing static int
asn1_template_d2i(ASN1_VALUE ** pval,CBS * cbs,const ASN1_TEMPLATE * at,int optional,int depth)116096903d9fSjsing asn1_template_d2i(ASN1_VALUE **pval, CBS *cbs, const ASN1_TEMPLATE *at,
116196ded9f8Sjsing int optional, int depth)
1162da347917Sbeck {
1163d5028891Sjsing CBS cbs_exp, cbs_exp_content;
116496ded9f8Sjsing int constructed, indefinite;
1165f4540edcSjsing size_t length;
1166f4540edcSjsing int ret;
1167f4540edcSjsing
1168d5028891Sjsing if (pval == NULL)
1169f4540edcSjsing return 0;
1170f4540edcSjsing
1171d5028891Sjsing /* Check if EXPLICIT tag is expected. */
117296903d9fSjsing if ((at->flags & ASN1_TFLG_EXPTAG) == 0)
117396903d9fSjsing return asn1_template_noexp_d2i(pval, cbs, at, optional, depth);
1174f4540edcSjsing
1175d5028891Sjsing CBS_init(&cbs_exp, CBS_data(cbs), CBS_len(cbs));
1176f4540edcSjsing
1177d5028891Sjsing /* Read ASN.1 header for EXPLICIT tagged object. */
1178d5028891Sjsing ret = asn1_check_tag(&cbs_exp, &length, NULL, NULL, &indefinite,
117996903d9fSjsing &constructed, at->tag, at->flags & ASN1_TFLG_TAG_CLASS, optional);
1180f4540edcSjsing if (ret == -1)
1181f4540edcSjsing return -1;
1182f4540edcSjsing if (ret != 1) {
1183f4540edcSjsing ASN1error(ERR_R_NESTED_ASN1_ERROR);
1184f4540edcSjsing return 0;
1185f4540edcSjsing }
1186f4540edcSjsing
1187d5028891Sjsing if (!constructed) {
1188d5028891Sjsing ASN1error(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
1189e2cdf593Sjsing return 0;
1190da347917Sbeck }
1191da347917Sbeck
1192d5028891Sjsing if (indefinite) {
1193d5028891Sjsing CBS_init(&cbs_exp_content, CBS_data(&cbs_exp), CBS_len(&cbs_exp));
1194cc777fd4Stedu } else {
1195d5028891Sjsing if (!CBS_get_bytes(&cbs_exp, &cbs_exp_content, length))
1196da347917Sbeck goto err;
1197da347917Sbeck }
1198d5028891Sjsing
119996903d9fSjsing if ((ret = asn1_template_noexp_d2i(pval, &cbs_exp_content, at, 0,
1200d5028891Sjsing depth)) != 1) {
1201d5028891Sjsing ASN1error(ERR_R_NESTED_ASN1_ERROR);
1202d5028891Sjsing return 0;
1203da347917Sbeck }
1204da347917Sbeck
1205d5028891Sjsing if (indefinite) {
1206d5028891Sjsing if (!asn1_check_eoc(&cbs_exp_content)) {
1207d5028891Sjsing ASN1error(ASN1_R_MISSING_EOC);
1208d5028891Sjsing goto err;
1209d5028891Sjsing }
1210d5028891Sjsing if (!CBS_skip(&cbs_exp, CBS_offset(&cbs_exp_content)))
1211d5028891Sjsing goto err;
1212d5028891Sjsing } else if (CBS_len(&cbs_exp_content) != 0) {
1213d5028891Sjsing ASN1error(ASN1_R_SEQUENCE_LENGTH_MISMATCH);
1214d5028891Sjsing goto err;
1215d5028891Sjsing }
1216d5028891Sjsing
1217d5028891Sjsing if (!CBS_skip(cbs, CBS_offset(&cbs_exp)))
1218d5028891Sjsing goto err;
1219d5028891Sjsing
1220d5028891Sjsing return 1;
122104a37b9bSjsing
1222da347917Sbeck err:
122396903d9fSjsing ASN1_template_free(pval, at);
1224d5028891Sjsing return 0;
1225d5028891Sjsing }
1226d5028891Sjsing
1227d5028891Sjsing ASN1_VALUE *
ASN1_item_d2i(ASN1_VALUE ** pval,const unsigned char ** in,long inlen,const ASN1_ITEM * it)1228d5028891Sjsing ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long inlen,
1229d5028891Sjsing const ASN1_ITEM *it)
1230d5028891Sjsing {
1231d5028891Sjsing ASN1_VALUE *ptmpval = NULL;
1232d5028891Sjsing
1233d5028891Sjsing if (pval == NULL)
1234d5028891Sjsing pval = &ptmpval;
1235884131c6Sjsing if (ASN1_item_ex_d2i(pval, in, inlen, it, -1, 0, 0, NULL) <= 0)
1236d5028891Sjsing return NULL;
1237d5028891Sjsing
1238d5028891Sjsing return *pval;
1239d5028891Sjsing }
1240acf64401Sbeck LCRYPTO_ALIAS(ASN1_item_d2i);
1241d5028891Sjsing
1242d5028891Sjsing int
ASN1_item_ex_d2i(ASN1_VALUE ** pval,const unsigned char ** in,long inlen,const ASN1_ITEM * it,int tag_number,int tag_class,char optional,ASN1_TLC * ctx)1243d5028891Sjsing ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long inlen,
1244d5028891Sjsing const ASN1_ITEM *it, int tag_number, int tag_class, char optional,
1245d5028891Sjsing ASN1_TLC *ctx)
1246d5028891Sjsing {
1247d5028891Sjsing CBS cbs;
1248d5028891Sjsing int ret;
1249d5028891Sjsing
1250d5028891Sjsing if (inlen < 0)
1251d5028891Sjsing return 0;
1252d5028891Sjsing
1253d5028891Sjsing CBS_init(&cbs, *in, inlen);
12546db14da9Sjsing if ((ret = asn1_item_d2i(pval, &cbs, it, tag_number, tag_class,
125596ded9f8Sjsing (int)optional, 0)) == 1)
1256d5028891Sjsing *in = CBS_data(&cbs);
1257d5028891Sjsing
1258da347917Sbeck return ret;
1259da347917Sbeck }
1260acf64401Sbeck LCRYPTO_ALIAS(ASN1_item_ex_d2i);
1261