1a8e1175bSopenharmony_ci/*
2a8e1175bSopenharmony_ci *  Generic ASN.1 parsing
3a8e1175bSopenharmony_ci *
4a8e1175bSopenharmony_ci *  Copyright The Mbed TLS Contributors
5a8e1175bSopenharmony_ci *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6a8e1175bSopenharmony_ci */
7a8e1175bSopenharmony_ci
8a8e1175bSopenharmony_ci#include "common.h"
9a8e1175bSopenharmony_ci
10a8e1175bSopenharmony_ci#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
11a8e1175bSopenharmony_ci    defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
12a8e1175bSopenharmony_ci
13a8e1175bSopenharmony_ci#include "mbedtls/asn1.h"
14a8e1175bSopenharmony_ci#include "mbedtls/platform_util.h"
15a8e1175bSopenharmony_ci#include "mbedtls/error.h"
16a8e1175bSopenharmony_ci
17a8e1175bSopenharmony_ci#include <string.h>
18a8e1175bSopenharmony_ci
19a8e1175bSopenharmony_ci#if defined(MBEDTLS_BIGNUM_C)
20a8e1175bSopenharmony_ci#include "mbedtls/bignum.h"
21a8e1175bSopenharmony_ci#endif
22a8e1175bSopenharmony_ci
23a8e1175bSopenharmony_ci#include "mbedtls/platform.h"
24a8e1175bSopenharmony_ci
25a8e1175bSopenharmony_ci/*
26a8e1175bSopenharmony_ci * ASN.1 DER decoding routines
27a8e1175bSopenharmony_ci */
28a8e1175bSopenharmony_ciint mbedtls_asn1_get_len(unsigned char **p,
29a8e1175bSopenharmony_ci                         const unsigned char *end,
30a8e1175bSopenharmony_ci                         size_t *len)
31a8e1175bSopenharmony_ci{
32a8e1175bSopenharmony_ci    if ((end - *p) < 1) {
33a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
34a8e1175bSopenharmony_ci    }
35a8e1175bSopenharmony_ci
36a8e1175bSopenharmony_ci    if ((**p & 0x80) == 0) {
37a8e1175bSopenharmony_ci        *len = *(*p)++;
38a8e1175bSopenharmony_ci    } else {
39a8e1175bSopenharmony_ci        int n = (**p) & 0x7F;
40a8e1175bSopenharmony_ci        if (n == 0 || n > 4) {
41a8e1175bSopenharmony_ci            return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
42a8e1175bSopenharmony_ci        }
43a8e1175bSopenharmony_ci        if ((end - *p) <= n) {
44a8e1175bSopenharmony_ci            return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
45a8e1175bSopenharmony_ci        }
46a8e1175bSopenharmony_ci        *len = 0;
47a8e1175bSopenharmony_ci        (*p)++;
48a8e1175bSopenharmony_ci        while (n--) {
49a8e1175bSopenharmony_ci            *len = (*len << 8) | **p;
50a8e1175bSopenharmony_ci            (*p)++;
51a8e1175bSopenharmony_ci        }
52a8e1175bSopenharmony_ci    }
53a8e1175bSopenharmony_ci
54a8e1175bSopenharmony_ci    if (*len > (size_t) (end - *p)) {
55a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
56a8e1175bSopenharmony_ci    }
57a8e1175bSopenharmony_ci
58a8e1175bSopenharmony_ci    return 0;
59a8e1175bSopenharmony_ci}
60a8e1175bSopenharmony_ci
61a8e1175bSopenharmony_ciint mbedtls_asn1_get_tag(unsigned char **p,
62a8e1175bSopenharmony_ci                         const unsigned char *end,
63a8e1175bSopenharmony_ci                         size_t *len, int tag)
64a8e1175bSopenharmony_ci{
65a8e1175bSopenharmony_ci    if ((end - *p) < 1) {
66a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
67a8e1175bSopenharmony_ci    }
68a8e1175bSopenharmony_ci
69a8e1175bSopenharmony_ci    if (**p != tag) {
70a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
71a8e1175bSopenharmony_ci    }
72a8e1175bSopenharmony_ci
73a8e1175bSopenharmony_ci    (*p)++;
74a8e1175bSopenharmony_ci
75a8e1175bSopenharmony_ci    return mbedtls_asn1_get_len(p, end, len);
76a8e1175bSopenharmony_ci}
77a8e1175bSopenharmony_ci#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
78a8e1175bSopenharmony_ci
79a8e1175bSopenharmony_ci#if defined(MBEDTLS_ASN1_PARSE_C)
80a8e1175bSopenharmony_ciint mbedtls_asn1_get_bool(unsigned char **p,
81a8e1175bSopenharmony_ci                          const unsigned char *end,
82a8e1175bSopenharmony_ci                          int *val)
83a8e1175bSopenharmony_ci{
84a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
85a8e1175bSopenharmony_ci    size_t len;
86a8e1175bSopenharmony_ci
87a8e1175bSopenharmony_ci    if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
88a8e1175bSopenharmony_ci        return ret;
89a8e1175bSopenharmony_ci    }
90a8e1175bSopenharmony_ci
91a8e1175bSopenharmony_ci    if (len != 1) {
92a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
93a8e1175bSopenharmony_ci    }
94a8e1175bSopenharmony_ci
95a8e1175bSopenharmony_ci    *val = (**p != 0) ? 1 : 0;
96a8e1175bSopenharmony_ci    (*p)++;
97a8e1175bSopenharmony_ci
98a8e1175bSopenharmony_ci    return 0;
99a8e1175bSopenharmony_ci}
100a8e1175bSopenharmony_ci
101a8e1175bSopenharmony_cistatic int asn1_get_tagged_int(unsigned char **p,
102a8e1175bSopenharmony_ci                               const unsigned char *end,
103a8e1175bSopenharmony_ci                               int tag, int *val)
104a8e1175bSopenharmony_ci{
105a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
106a8e1175bSopenharmony_ci    size_t len;
107a8e1175bSopenharmony_ci
108a8e1175bSopenharmony_ci    if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
109a8e1175bSopenharmony_ci        return ret;
110a8e1175bSopenharmony_ci    }
111a8e1175bSopenharmony_ci
112a8e1175bSopenharmony_ci    /*
113a8e1175bSopenharmony_ci     * len==0 is malformed (0 must be represented as 020100 for INTEGER,
114a8e1175bSopenharmony_ci     * or 0A0100 for ENUMERATED tags
115a8e1175bSopenharmony_ci     */
116a8e1175bSopenharmony_ci    if (len == 0) {
117a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
118a8e1175bSopenharmony_ci    }
119a8e1175bSopenharmony_ci    /* This is a cryptography library. Reject negative integers. */
120a8e1175bSopenharmony_ci    if ((**p & 0x80) != 0) {
121a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
122a8e1175bSopenharmony_ci    }
123a8e1175bSopenharmony_ci
124a8e1175bSopenharmony_ci    /* Skip leading zeros. */
125a8e1175bSopenharmony_ci    while (len > 0 && **p == 0) {
126a8e1175bSopenharmony_ci        ++(*p);
127a8e1175bSopenharmony_ci        --len;
128a8e1175bSopenharmony_ci    }
129a8e1175bSopenharmony_ci
130a8e1175bSopenharmony_ci    /* Reject integers that don't fit in an int. This code assumes that
131a8e1175bSopenharmony_ci     * the int type has no padding bit. */
132a8e1175bSopenharmony_ci    if (len > sizeof(int)) {
133a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
134a8e1175bSopenharmony_ci    }
135a8e1175bSopenharmony_ci    if (len == sizeof(int) && (**p & 0x80) != 0) {
136a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
137a8e1175bSopenharmony_ci    }
138a8e1175bSopenharmony_ci
139a8e1175bSopenharmony_ci    *val = 0;
140a8e1175bSopenharmony_ci    while (len-- > 0) {
141a8e1175bSopenharmony_ci        *val = (*val << 8) | **p;
142a8e1175bSopenharmony_ci        (*p)++;
143a8e1175bSopenharmony_ci    }
144a8e1175bSopenharmony_ci
145a8e1175bSopenharmony_ci    return 0;
146a8e1175bSopenharmony_ci}
147a8e1175bSopenharmony_ci
148a8e1175bSopenharmony_ciint mbedtls_asn1_get_int(unsigned char **p,
149a8e1175bSopenharmony_ci                         const unsigned char *end,
150a8e1175bSopenharmony_ci                         int *val)
151a8e1175bSopenharmony_ci{
152a8e1175bSopenharmony_ci    return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
153a8e1175bSopenharmony_ci}
154a8e1175bSopenharmony_ci
155a8e1175bSopenharmony_ciint mbedtls_asn1_get_enum(unsigned char **p,
156a8e1175bSopenharmony_ci                          const unsigned char *end,
157a8e1175bSopenharmony_ci                          int *val)
158a8e1175bSopenharmony_ci{
159a8e1175bSopenharmony_ci    return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
160a8e1175bSopenharmony_ci}
161a8e1175bSopenharmony_ci
162a8e1175bSopenharmony_ci#if defined(MBEDTLS_BIGNUM_C)
163a8e1175bSopenharmony_ciint mbedtls_asn1_get_mpi(unsigned char **p,
164a8e1175bSopenharmony_ci                         const unsigned char *end,
165a8e1175bSopenharmony_ci                         mbedtls_mpi *X)
166a8e1175bSopenharmony_ci{
167a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
168a8e1175bSopenharmony_ci    size_t len;
169a8e1175bSopenharmony_ci
170a8e1175bSopenharmony_ci    if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
171a8e1175bSopenharmony_ci        return ret;
172a8e1175bSopenharmony_ci    }
173a8e1175bSopenharmony_ci
174a8e1175bSopenharmony_ci    ret = mbedtls_mpi_read_binary(X, *p, len);
175a8e1175bSopenharmony_ci
176a8e1175bSopenharmony_ci    *p += len;
177a8e1175bSopenharmony_ci
178a8e1175bSopenharmony_ci    return ret;
179a8e1175bSopenharmony_ci}
180a8e1175bSopenharmony_ci#endif /* MBEDTLS_BIGNUM_C */
181a8e1175bSopenharmony_ci
182a8e1175bSopenharmony_ciint mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
183a8e1175bSopenharmony_ci                               mbedtls_asn1_bitstring *bs)
184a8e1175bSopenharmony_ci{
185a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
186a8e1175bSopenharmony_ci
187a8e1175bSopenharmony_ci    /* Certificate type is a single byte bitstring */
188a8e1175bSopenharmony_ci    if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
189a8e1175bSopenharmony_ci        return ret;
190a8e1175bSopenharmony_ci    }
191a8e1175bSopenharmony_ci
192a8e1175bSopenharmony_ci    /* Check length, subtract one for actual bit string length */
193a8e1175bSopenharmony_ci    if (bs->len < 1) {
194a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
195a8e1175bSopenharmony_ci    }
196a8e1175bSopenharmony_ci    bs->len -= 1;
197a8e1175bSopenharmony_ci
198a8e1175bSopenharmony_ci    /* Get number of unused bits, ensure unused bits <= 7 */
199a8e1175bSopenharmony_ci    bs->unused_bits = **p;
200a8e1175bSopenharmony_ci    if (bs->unused_bits > 7) {
201a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
202a8e1175bSopenharmony_ci    }
203a8e1175bSopenharmony_ci    (*p)++;
204a8e1175bSopenharmony_ci
205a8e1175bSopenharmony_ci    /* Get actual bitstring */
206a8e1175bSopenharmony_ci    bs->p = *p;
207a8e1175bSopenharmony_ci    *p += bs->len;
208a8e1175bSopenharmony_ci
209a8e1175bSopenharmony_ci    if (*p != end) {
210a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
211a8e1175bSopenharmony_ci    }
212a8e1175bSopenharmony_ci
213a8e1175bSopenharmony_ci    return 0;
214a8e1175bSopenharmony_ci}
215a8e1175bSopenharmony_ci
216a8e1175bSopenharmony_ci/*
217a8e1175bSopenharmony_ci * Traverse an ASN.1 "SEQUENCE OF <tag>"
218a8e1175bSopenharmony_ci * and call a callback for each entry found.
219a8e1175bSopenharmony_ci */
220a8e1175bSopenharmony_ciint mbedtls_asn1_traverse_sequence_of(
221a8e1175bSopenharmony_ci    unsigned char **p,
222a8e1175bSopenharmony_ci    const unsigned char *end,
223a8e1175bSopenharmony_ci    unsigned char tag_must_mask, unsigned char tag_must_val,
224a8e1175bSopenharmony_ci    unsigned char tag_may_mask, unsigned char tag_may_val,
225a8e1175bSopenharmony_ci    int (*cb)(void *ctx, int tag,
226a8e1175bSopenharmony_ci              unsigned char *start, size_t len),
227a8e1175bSopenharmony_ci    void *ctx)
228a8e1175bSopenharmony_ci{
229a8e1175bSopenharmony_ci    int ret;
230a8e1175bSopenharmony_ci    size_t len;
231a8e1175bSopenharmony_ci
232a8e1175bSopenharmony_ci    /* Get main sequence tag */
233a8e1175bSopenharmony_ci    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
234a8e1175bSopenharmony_ci                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
235a8e1175bSopenharmony_ci        return ret;
236a8e1175bSopenharmony_ci    }
237a8e1175bSopenharmony_ci
238a8e1175bSopenharmony_ci    if (*p + len != end) {
239a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
240a8e1175bSopenharmony_ci    }
241a8e1175bSopenharmony_ci
242a8e1175bSopenharmony_ci    while (*p < end) {
243a8e1175bSopenharmony_ci        unsigned char const tag = *(*p)++;
244a8e1175bSopenharmony_ci
245a8e1175bSopenharmony_ci        if ((tag & tag_must_mask) != tag_must_val) {
246a8e1175bSopenharmony_ci            return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
247a8e1175bSopenharmony_ci        }
248a8e1175bSopenharmony_ci
249a8e1175bSopenharmony_ci        if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
250a8e1175bSopenharmony_ci            return ret;
251a8e1175bSopenharmony_ci        }
252a8e1175bSopenharmony_ci
253a8e1175bSopenharmony_ci        if ((tag & tag_may_mask) == tag_may_val) {
254a8e1175bSopenharmony_ci            if (cb != NULL) {
255a8e1175bSopenharmony_ci                ret = cb(ctx, tag, *p, len);
256a8e1175bSopenharmony_ci                if (ret != 0) {
257a8e1175bSopenharmony_ci                    return ret;
258a8e1175bSopenharmony_ci                }
259a8e1175bSopenharmony_ci            }
260a8e1175bSopenharmony_ci        }
261a8e1175bSopenharmony_ci
262a8e1175bSopenharmony_ci        *p += len;
263a8e1175bSopenharmony_ci    }
264a8e1175bSopenharmony_ci
265a8e1175bSopenharmony_ci    return 0;
266a8e1175bSopenharmony_ci}
267a8e1175bSopenharmony_ci
268a8e1175bSopenharmony_ci/*
269a8e1175bSopenharmony_ci * Get a bit string without unused bits
270a8e1175bSopenharmony_ci */
271a8e1175bSopenharmony_ciint mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
272a8e1175bSopenharmony_ci                                    size_t *len)
273a8e1175bSopenharmony_ci{
274a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
275a8e1175bSopenharmony_ci
276a8e1175bSopenharmony_ci    if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
277a8e1175bSopenharmony_ci        return ret;
278a8e1175bSopenharmony_ci    }
279a8e1175bSopenharmony_ci
280a8e1175bSopenharmony_ci    if (*len == 0) {
281a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_INVALID_DATA;
282a8e1175bSopenharmony_ci    }
283a8e1175bSopenharmony_ci    --(*len);
284a8e1175bSopenharmony_ci
285a8e1175bSopenharmony_ci    if (**p != 0) {
286a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_INVALID_DATA;
287a8e1175bSopenharmony_ci    }
288a8e1175bSopenharmony_ci    ++(*p);
289a8e1175bSopenharmony_ci
290a8e1175bSopenharmony_ci    return 0;
291a8e1175bSopenharmony_ci}
292a8e1175bSopenharmony_ci
293a8e1175bSopenharmony_civoid mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
294a8e1175bSopenharmony_ci{
295a8e1175bSopenharmony_ci    while (seq != NULL) {
296a8e1175bSopenharmony_ci        mbedtls_asn1_sequence *next = seq->next;
297a8e1175bSopenharmony_ci        mbedtls_free(seq);
298a8e1175bSopenharmony_ci        seq = next;
299a8e1175bSopenharmony_ci    }
300a8e1175bSopenharmony_ci}
301a8e1175bSopenharmony_ci
302a8e1175bSopenharmony_citypedef struct {
303a8e1175bSopenharmony_ci    int tag;
304a8e1175bSopenharmony_ci    mbedtls_asn1_sequence *cur;
305a8e1175bSopenharmony_ci} asn1_get_sequence_of_cb_ctx_t;
306a8e1175bSopenharmony_ci
307a8e1175bSopenharmony_cistatic int asn1_get_sequence_of_cb(void *ctx,
308a8e1175bSopenharmony_ci                                   int tag,
309a8e1175bSopenharmony_ci                                   unsigned char *start,
310a8e1175bSopenharmony_ci                                   size_t len)
311a8e1175bSopenharmony_ci{
312a8e1175bSopenharmony_ci    asn1_get_sequence_of_cb_ctx_t *cb_ctx =
313a8e1175bSopenharmony_ci        (asn1_get_sequence_of_cb_ctx_t *) ctx;
314a8e1175bSopenharmony_ci    mbedtls_asn1_sequence *cur =
315a8e1175bSopenharmony_ci        cb_ctx->cur;
316a8e1175bSopenharmony_ci
317a8e1175bSopenharmony_ci    if (cur->buf.p != NULL) {
318a8e1175bSopenharmony_ci        cur->next =
319a8e1175bSopenharmony_ci            mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
320a8e1175bSopenharmony_ci
321a8e1175bSopenharmony_ci        if (cur->next == NULL) {
322a8e1175bSopenharmony_ci            return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
323a8e1175bSopenharmony_ci        }
324a8e1175bSopenharmony_ci
325a8e1175bSopenharmony_ci        cur = cur->next;
326a8e1175bSopenharmony_ci    }
327a8e1175bSopenharmony_ci
328a8e1175bSopenharmony_ci    cur->buf.p = start;
329a8e1175bSopenharmony_ci    cur->buf.len = len;
330a8e1175bSopenharmony_ci    cur->buf.tag = tag;
331a8e1175bSopenharmony_ci
332a8e1175bSopenharmony_ci    cb_ctx->cur = cur;
333a8e1175bSopenharmony_ci    return 0;
334a8e1175bSopenharmony_ci}
335a8e1175bSopenharmony_ci
336a8e1175bSopenharmony_ci/*
337a8e1175bSopenharmony_ci *  Parses and splits an ASN.1 "SEQUENCE OF <tag>"
338a8e1175bSopenharmony_ci */
339a8e1175bSopenharmony_ciint mbedtls_asn1_get_sequence_of(unsigned char **p,
340a8e1175bSopenharmony_ci                                 const unsigned char *end,
341a8e1175bSopenharmony_ci                                 mbedtls_asn1_sequence *cur,
342a8e1175bSopenharmony_ci                                 int tag)
343a8e1175bSopenharmony_ci{
344a8e1175bSopenharmony_ci    asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
345a8e1175bSopenharmony_ci    memset(cur, 0, sizeof(mbedtls_asn1_sequence));
346a8e1175bSopenharmony_ci    return mbedtls_asn1_traverse_sequence_of(
347a8e1175bSopenharmony_ci        p, end, 0xFF, tag, 0, 0,
348a8e1175bSopenharmony_ci        asn1_get_sequence_of_cb, &cb_ctx);
349a8e1175bSopenharmony_ci}
350a8e1175bSopenharmony_ci
351a8e1175bSopenharmony_ciint mbedtls_asn1_get_alg(unsigned char **p,
352a8e1175bSopenharmony_ci                         const unsigned char *end,
353a8e1175bSopenharmony_ci                         mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
354a8e1175bSopenharmony_ci{
355a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
356a8e1175bSopenharmony_ci    size_t len;
357a8e1175bSopenharmony_ci
358a8e1175bSopenharmony_ci    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
359a8e1175bSopenharmony_ci                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
360a8e1175bSopenharmony_ci        return ret;
361a8e1175bSopenharmony_ci    }
362a8e1175bSopenharmony_ci
363a8e1175bSopenharmony_ci    if ((end - *p) < 1) {
364a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
365a8e1175bSopenharmony_ci    }
366a8e1175bSopenharmony_ci
367a8e1175bSopenharmony_ci    alg->tag = **p;
368a8e1175bSopenharmony_ci    end = *p + len;
369a8e1175bSopenharmony_ci
370a8e1175bSopenharmony_ci    if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
371a8e1175bSopenharmony_ci        return ret;
372a8e1175bSopenharmony_ci    }
373a8e1175bSopenharmony_ci
374a8e1175bSopenharmony_ci    alg->p = *p;
375a8e1175bSopenharmony_ci    *p += alg->len;
376a8e1175bSopenharmony_ci
377a8e1175bSopenharmony_ci    if (*p == end) {
378a8e1175bSopenharmony_ci        mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
379a8e1175bSopenharmony_ci        return 0;
380a8e1175bSopenharmony_ci    }
381a8e1175bSopenharmony_ci
382a8e1175bSopenharmony_ci    params->tag = **p;
383a8e1175bSopenharmony_ci    (*p)++;
384a8e1175bSopenharmony_ci
385a8e1175bSopenharmony_ci    if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0) {
386a8e1175bSopenharmony_ci        return ret;
387a8e1175bSopenharmony_ci    }
388a8e1175bSopenharmony_ci
389a8e1175bSopenharmony_ci    params->p = *p;
390a8e1175bSopenharmony_ci    *p += params->len;
391a8e1175bSopenharmony_ci
392a8e1175bSopenharmony_ci    if (*p != end) {
393a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
394a8e1175bSopenharmony_ci    }
395a8e1175bSopenharmony_ci
396a8e1175bSopenharmony_ci    return 0;
397a8e1175bSopenharmony_ci}
398a8e1175bSopenharmony_ci
399a8e1175bSopenharmony_ciint mbedtls_asn1_get_alg_null(unsigned char **p,
400a8e1175bSopenharmony_ci                              const unsigned char *end,
401a8e1175bSopenharmony_ci                              mbedtls_asn1_buf *alg)
402a8e1175bSopenharmony_ci{
403a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
404a8e1175bSopenharmony_ci    mbedtls_asn1_buf params;
405a8e1175bSopenharmony_ci
406a8e1175bSopenharmony_ci    memset(&params, 0, sizeof(mbedtls_asn1_buf));
407a8e1175bSopenharmony_ci
408a8e1175bSopenharmony_ci    if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0) {
409a8e1175bSopenharmony_ci        return ret;
410a8e1175bSopenharmony_ci    }
411a8e1175bSopenharmony_ci
412a8e1175bSopenharmony_ci    if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
413a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ASN1_INVALID_DATA;
414a8e1175bSopenharmony_ci    }
415a8e1175bSopenharmony_ci
416a8e1175bSopenharmony_ci    return 0;
417a8e1175bSopenharmony_ci}
418a8e1175bSopenharmony_ci
419a8e1175bSopenharmony_ci#if !defined(MBEDTLS_DEPRECATED_REMOVED)
420a8e1175bSopenharmony_civoid mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
421a8e1175bSopenharmony_ci{
422a8e1175bSopenharmony_ci    if (cur == NULL) {
423a8e1175bSopenharmony_ci        return;
424a8e1175bSopenharmony_ci    }
425a8e1175bSopenharmony_ci
426a8e1175bSopenharmony_ci    mbedtls_free(cur->oid.p);
427a8e1175bSopenharmony_ci    mbedtls_free(cur->val.p);
428a8e1175bSopenharmony_ci
429a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
430a8e1175bSopenharmony_ci}
431a8e1175bSopenharmony_ci#endif /* MBEDTLS_DEPRECATED_REMOVED */
432a8e1175bSopenharmony_ci
433a8e1175bSopenharmony_civoid mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
434a8e1175bSopenharmony_ci{
435a8e1175bSopenharmony_ci    mbedtls_asn1_named_data *cur;
436a8e1175bSopenharmony_ci
437a8e1175bSopenharmony_ci    while ((cur = *head) != NULL) {
438a8e1175bSopenharmony_ci        *head = cur->next;
439a8e1175bSopenharmony_ci        mbedtls_free(cur->oid.p);
440a8e1175bSopenharmony_ci        mbedtls_free(cur->val.p);
441a8e1175bSopenharmony_ci        mbedtls_free(cur);
442a8e1175bSopenharmony_ci    }
443a8e1175bSopenharmony_ci}
444a8e1175bSopenharmony_ci
445a8e1175bSopenharmony_civoid mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name)
446a8e1175bSopenharmony_ci{
447a8e1175bSopenharmony_ci    for (mbedtls_asn1_named_data *next; name != NULL; name = next) {
448a8e1175bSopenharmony_ci        next = name->next;
449a8e1175bSopenharmony_ci        mbedtls_free(name);
450a8e1175bSopenharmony_ci    }
451a8e1175bSopenharmony_ci}
452a8e1175bSopenharmony_ci
453a8e1175bSopenharmony_ciconst mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list,
454a8e1175bSopenharmony_ci                                                            const char *oid, size_t len)
455a8e1175bSopenharmony_ci{
456a8e1175bSopenharmony_ci    while (list != NULL) {
457a8e1175bSopenharmony_ci        if (list->oid.len == len &&
458a8e1175bSopenharmony_ci            memcmp(list->oid.p, oid, len) == 0) {
459a8e1175bSopenharmony_ci            break;
460a8e1175bSopenharmony_ci        }
461a8e1175bSopenharmony_ci
462a8e1175bSopenharmony_ci        list = list->next;
463a8e1175bSopenharmony_ci    }
464a8e1175bSopenharmony_ci
465a8e1175bSopenharmony_ci    return list;
466a8e1175bSopenharmony_ci}
467a8e1175bSopenharmony_ci
468a8e1175bSopenharmony_ci#endif /* MBEDTLS_ASN1_PARSE_C */
469