xref: /openbsd/lib/libcrypto/asn1/tasn_dec.c (revision c9ae38aa)
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