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