blob: 644b43ba965effc6d98866af4187ec19286154c8 [file] [log] [blame]
Paul Bakkerefc30292011-11-10 14:43:23 +00001/*
2 * Generic ASN.1 parsing
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakkerefc30292011-11-10 14:43:23 +00006 */
7
Gilles Peskinedb09ef62020-06-03 01:43:33 +02008#include "common.h"
Paul Bakkerefc30292011-11-10 14:43:23 +00009
Valerio Setti688f7952024-01-16 09:18:40 +010010#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
Valerio Settib1f6d2a2024-02-08 17:41:45 +010011 defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) || defined(MBEDTLS_PEM_PARSE_C)
Paul Bakkerefc30292011-11-10 14:43:23 +000012
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000013#include "mbedtls/asn1.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050014#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000015#include "mbedtls/error.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000016
Rich Evans00ab4702015-02-06 13:43:58 +000017#include <string.h>
18
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020019#if defined(MBEDTLS_BIGNUM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000020#include "mbedtls/bignum.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000021#endif
22
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000023#include "mbedtls/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020024
Paul Bakkerefc30292011-11-10 14:43:23 +000025/*
26 * ASN.1 DER decoding routines
27 */
Gilles Peskine449bd832023-01-11 14:50:10 +010028int mbedtls_asn1_get_len(unsigned char **p,
29 const unsigned char *end,
30 size_t *len)
Paul Bakkerefc30292011-11-10 14:43:23 +000031{
Gilles Peskine449bd832023-01-11 14:50:10 +010032 if ((end - *p) < 1) {
33 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
34 }
Paul Bakkerefc30292011-11-10 14:43:23 +000035
Gilles Peskine449bd832023-01-11 14:50:10 +010036 if ((**p & 0x80) == 0) {
Paul Bakkerefc30292011-11-10 14:43:23 +000037 *len = *(*p)++;
Gilles Peskine449bd832023-01-11 14:50:10 +010038 } else {
Dave Rodgmanef6795d2023-09-12 14:42:46 +010039 int n = (**p) & 0x7F;
40 if (n == 0 || n > 4) {
41 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
42 }
43 if ((end - *p) <= n) {
44 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
45 }
46 *len = 0;
47 (*p)++;
48 while (n--) {
49 *len = (*len << 8) | **p;
50 (*p)++;
Paul Bakkerefc30292011-11-10 14:43:23 +000051 }
52 }
53
Gilles Peskine449bd832023-01-11 14:50:10 +010054 if (*len > (size_t) (end - *p)) {
55 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
56 }
Paul Bakkerefc30292011-11-10 14:43:23 +000057
Gilles Peskine449bd832023-01-11 14:50:10 +010058 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +000059}
60
Gilles Peskine449bd832023-01-11 14:50:10 +010061int mbedtls_asn1_get_tag(unsigned char **p,
62 const unsigned char *end,
63 size_t *len, int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +000064{
Gilles Peskine449bd832023-01-11 14:50:10 +010065 if ((end - *p) < 1) {
66 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
67 }
Paul Bakkerefc30292011-11-10 14:43:23 +000068
Gilles Peskine449bd832023-01-11 14:50:10 +010069 if (**p != tag) {
70 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
71 }
Paul Bakkerefc30292011-11-10 14:43:23 +000072
73 (*p)++;
74
Gilles Peskine449bd832023-01-11 14:50:10 +010075 return mbedtls_asn1_get_len(p, end, len);
Paul Bakkerefc30292011-11-10 14:43:23 +000076}
Valerio Settib1f6d2a2024-02-08 17:41:45 +010077#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C ||
78 MBEDTLS_PSA_UTIL_HAVE_ECDSA || MBEDTLS_PEM_PARSE_C */
Paul Bakkerefc30292011-11-10 14:43:23 +000079
Agathiyan Bragadeeshfca08612023-09-04 15:45:37 +010080#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010081int mbedtls_asn1_get_bool(unsigned char **p,
82 const unsigned char *end,
83 int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +000084{
Janos Follath24eed8d2019-11-22 13:21:35 +000085 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +000086 size_t len;
87
Gilles Peskine449bd832023-01-11 14:50:10 +010088 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
89 return ret;
90 }
Paul Bakkerefc30292011-11-10 14:43:23 +000091
Gilles Peskine449bd832023-01-11 14:50:10 +010092 if (len != 1) {
93 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
94 }
Paul Bakkerefc30292011-11-10 14:43:23 +000095
Gilles Peskine449bd832023-01-11 14:50:10 +010096 *val = (**p != 0) ? 1 : 0;
Paul Bakkerefc30292011-11-10 14:43:23 +000097 (*p)++;
98
Gilles Peskine449bd832023-01-11 14:50:10 +010099 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000100}
101
Gilles Peskine449bd832023-01-11 14:50:10 +0100102static int asn1_get_tagged_int(unsigned char **p,
103 const unsigned char *end,
104 int tag, int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +0000105{
Janos Follath24eed8d2019-11-22 13:21:35 +0000106 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000107 size_t len;
108
Gilles Peskine449bd832023-01-11 14:50:10 +0100109 if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
110 return ret;
111 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000112
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200113 /*
114 * len==0 is malformed (0 must be represented as 020100 for INTEGER,
115 * or 0A0100 for ENUMERATED tags
116 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 if (len == 0) {
118 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
119 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200120 /* This is a cryptography library. Reject negative integers. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100121 if ((**p & 0x80) != 0) {
122 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
123 }
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100124
Gilles Peskine9fd97942019-10-10 19:27:53 +0200125 /* Skip leading zeros. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 while (len > 0 && **p == 0) {
127 ++(*p);
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100128 --len;
129 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200130
131 /* Reject integers that don't fit in an int. This code assumes that
132 * the int type has no padding bit. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 if (len > sizeof(int)) {
134 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
135 }
136 if (len == sizeof(int) && (**p & 0x80) != 0) {
137 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
138 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000139
140 *val = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 while (len-- > 0) {
142 *val = (*val << 8) | **p;
Paul Bakkerefc30292011-11-10 14:43:23 +0000143 (*p)++;
144 }
145
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000147}
148
Gilles Peskine449bd832023-01-11 14:50:10 +0100149int mbedtls_asn1_get_int(unsigned char **p,
150 const unsigned char *end,
151 int *val)
152{
153 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
154}
155
156int mbedtls_asn1_get_enum(unsigned char **p,
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200157 const unsigned char *end,
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 int *val)
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200159{
Gilles Peskine449bd832023-01-11 14:50:10 +0100160 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200161}
162
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200163#if defined(MBEDTLS_BIGNUM_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100164int mbedtls_asn1_get_mpi(unsigned char **p,
165 const unsigned char *end,
166 mbedtls_mpi *X)
Paul Bakkerefc30292011-11-10 14:43:23 +0000167{
Janos Follath24eed8d2019-11-22 13:21:35 +0000168 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000169 size_t len;
170
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
172 return ret;
173 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175 ret = mbedtls_mpi_read_binary(X, *p, len);
Paul Bakkerefc30292011-11-10 14:43:23 +0000176
177 *p += len;
178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 return ret;
Paul Bakkerefc30292011-11-10 14:43:23 +0000180}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181#endif /* MBEDTLS_BIGNUM_C */
Paul Bakkerefc30292011-11-10 14:43:23 +0000182
Gilles Peskine449bd832023-01-11 14:50:10 +0100183int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
184 mbedtls_asn1_bitstring *bs)
Paul Bakkerefc30292011-11-10 14:43:23 +0000185{
Janos Follath24eed8d2019-11-22 13:21:35 +0000186 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000187
188 /* Certificate type is a single byte bitstring */
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
190 return ret;
191 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000192
193 /* Check length, subtract one for actual bit string length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 if (bs->len < 1) {
195 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
196 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000197 bs->len -= 1;
198
199 /* Get number of unused bits, ensure unused bits <= 7 */
200 bs->unused_bits = **p;
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 if (bs->unused_bits > 7) {
202 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
203 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000204 (*p)++;
205
206 /* Get actual bitstring */
207 bs->p = *p;
208 *p += bs->len;
209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 if (*p != end) {
211 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
212 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000213
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000215}
216
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200217/*
Hanno Becker199b7092019-09-11 14:21:26 +0100218 * Traverse an ASN.1 "SEQUENCE OF <tag>"
219 * and call a callback for each entry found.
220 */
221int mbedtls_asn1_traverse_sequence_of(
222 unsigned char **p,
223 const unsigned char *end,
Hanno Becker34aada22020-02-03 10:39:55 +0000224 unsigned char tag_must_mask, unsigned char tag_must_val,
225 unsigned char tag_may_mask, unsigned char tag_may_val,
Gilles Peskine449bd832023-01-11 14:50:10 +0100226 int (*cb)(void *ctx, int tag,
227 unsigned char *start, size_t len),
228 void *ctx)
Hanno Becker199b7092019-09-11 14:21:26 +0100229{
230 int ret;
231 size_t len;
232
233 /* Get main sequence tag */
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
235 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
236 return ret;
Hanno Becker199b7092019-09-11 14:21:26 +0100237 }
238
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 if (*p + len != end) {
240 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
241 }
Hanno Becker199b7092019-09-11 14:21:26 +0100242
Gilles Peskine449bd832023-01-11 14:50:10 +0100243 while (*p < end) {
Hanno Becker199b7092019-09-11 14:21:26 +0100244 unsigned char const tag = *(*p)++;
245
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 if ((tag & tag_must_mask) != tag_must_val) {
247 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
248 }
Hanno Becker199b7092019-09-11 14:21:26 +0100249
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
251 return ret;
252 }
Hanno Becker199b7092019-09-11 14:21:26 +0100253
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 if ((tag & tag_may_mask) == tag_may_val) {
255 if (cb != NULL) {
256 ret = cb(ctx, tag, *p, len);
257 if (ret != 0) {
258 return ret;
259 }
Hanno Becker199b7092019-09-11 14:21:26 +0100260 }
261 }
262
263 *p += len;
264 }
265
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 return 0;
Hanno Becker199b7092019-09-11 14:21:26 +0100267}
268
269/*
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200270 * Get a bit string without unused bits
271 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100272int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
273 size_t *len)
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200274{
Janos Follath24eed8d2019-11-22 13:21:35 +0000275 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200276
Gilles Peskine449bd832023-01-11 14:50:10 +0100277 if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
278 return ret;
279 }
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200280
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 if (*len == 0) {
282 return MBEDTLS_ERR_ASN1_INVALID_DATA;
283 }
284 --(*len);
Gilles Peskinee40d1202019-03-01 18:08:35 +0100285
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 if (**p != 0) {
287 return MBEDTLS_ERR_ASN1_INVALID_DATA;
288 }
289 ++(*p);
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 return 0;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200292}
293
Gilles Peskine449bd832023-01-11 14:50:10 +0100294void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
Hanno Becker12ae27d2019-09-11 14:20:09 +0100295{
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 while (seq != NULL) {
Hanno Becker12ae27d2019-09-11 14:20:09 +0100297 mbedtls_asn1_sequence *next = seq->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 mbedtls_free(seq);
Hanno Becker12ae27d2019-09-11 14:20:09 +0100299 seq = next;
300 }
301}
Paul Bakkerefc30292011-11-10 14:43:23 +0000302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303typedef struct {
Hanno Becker1505f632019-09-11 14:25:26 +0100304 int tag;
305 mbedtls_asn1_sequence *cur;
306} asn1_get_sequence_of_cb_ctx_t;
307
Gilles Peskine449bd832023-01-11 14:50:10 +0100308static int asn1_get_sequence_of_cb(void *ctx,
309 int tag,
310 unsigned char *start,
311 size_t len)
Hanno Becker1505f632019-09-11 14:25:26 +0100312{
313 asn1_get_sequence_of_cb_ctx_t *cb_ctx =
314 (asn1_get_sequence_of_cb_ctx_t *) ctx;
315 mbedtls_asn1_sequence *cur =
316 cb_ctx->cur;
317
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 if (cur->buf.p != NULL) {
Hanno Becker1505f632019-09-11 14:25:26 +0100319 cur->next =
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
Hanno Becker1505f632019-09-11 14:25:26 +0100321
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 if (cur->next == NULL) {
323 return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
324 }
Hanno Becker1505f632019-09-11 14:25:26 +0100325
326 cur = cur->next;
327 }
328
329 cur->buf.p = start;
330 cur->buf.len = len;
331 cur->buf.tag = tag;
332
333 cb_ctx->cur = cur;
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 return 0;
Hanno Becker1505f632019-09-11 14:25:26 +0100335}
336
Paul Bakkerefc30292011-11-10 14:43:23 +0000337/*
338 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
339 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100340int mbedtls_asn1_get_sequence_of(unsigned char **p,
341 const unsigned char *end,
342 mbedtls_asn1_sequence *cur,
343 int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +0000344{
Hanno Becker1505f632019-09-11 14:25:26 +0100345 asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 memset(cur, 0, sizeof(mbedtls_asn1_sequence));
347 return mbedtls_asn1_traverse_sequence_of(
348 p, end, 0xFF, tag, 0, 0,
349 asn1_get_sequence_of_cb, &cb_ctx);
Paul Bakkerefc30292011-11-10 14:43:23 +0000350}
351
Gilles Peskine449bd832023-01-11 14:50:10 +0100352int mbedtls_asn1_get_alg(unsigned char **p,
353 const unsigned char *end,
354 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200355{
Janos Follath24eed8d2019-11-22 13:21:35 +0000356 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200357 size_t len;
358
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
360 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
361 return ret;
362 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200363
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 if ((end - *p) < 1) {
365 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
366 }
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200367
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200368 alg->tag = **p;
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200369 end = *p + len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200370
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
372 return ret;
373 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200374
375 alg->p = *p;
376 *p += alg->len;
377
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 if (*p == end) {
379 mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
380 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200381 }
382
383 params->tag = **p;
384 (*p)++;
385
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0) {
387 return ret;
388 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200389
390 params->p = *p;
391 *p += params->len;
392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 if (*p != end) {
394 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
395 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200396
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200398}
399
Gilles Peskine449bd832023-01-11 14:50:10 +0100400int mbedtls_asn1_get_alg_null(unsigned char **p,
401 const unsigned char *end,
402 mbedtls_asn1_buf *alg)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200403{
Janos Follath24eed8d2019-11-22 13:21:35 +0000404 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 mbedtls_asn1_buf params;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200406
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 memset(&params, 0, sizeof(mbedtls_asn1_buf));
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200408
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0) {
410 return ret;
411 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200412
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
414 return MBEDTLS_ERR_ASN1_INVALID_DATA;
415 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200416
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200418}
419
Glenn Strauss82ba2742022-11-04 04:01:23 -0400420#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100421void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
Paul Bakkere5eae762013-08-26 12:05:14 +0200422{
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 if (cur == NULL) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200424 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 }
Paul Bakkere5eae762013-08-26 12:05:14 +0200426
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 mbedtls_free(cur->oid.p);
428 mbedtls_free(cur->val.p);
Paul Bakkere5eae762013-08-26 12:05:14 +0200429
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
Paul Bakkere5eae762013-08-26 12:05:14 +0200431}
Glenn Strauss82ba2742022-11-04 04:01:23 -0400432#endif /* MBEDTLS_DEPRECATED_REMOVED */
Paul Bakkere5eae762013-08-26 12:05:14 +0200433
Gilles Peskine449bd832023-01-11 14:50:10 +0100434void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
Paul Bakkerc547cc92013-09-09 12:01:23 +0200435{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436 mbedtls_asn1_named_data *cur;
Paul Bakkerc547cc92013-09-09 12:01:23 +0200437
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 while ((cur = *head) != NULL) {
Paul Bakkerc547cc92013-09-09 12:01:23 +0200439 *head = cur->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 mbedtls_free(cur->oid.p);
441 mbedtls_free(cur->val.p);
442 mbedtls_free(cur);
Paul Bakkerc547cc92013-09-09 12:01:23 +0200443 }
444}
445
Gilles Peskine449bd832023-01-11 14:50:10 +0100446void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name)
Glenn Straussa4b40412022-06-26 19:32:09 -0400447{
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 for (mbedtls_asn1_named_data *next; name != NULL; name = next) {
Glenn Straussa4b40412022-06-26 19:32:09 -0400449 next = name->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 mbedtls_free(name);
Glenn Straussa4b40412022-06-26 19:32:09 -0400451 }
452}
453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list,
455 const char *oid, size_t len)
Paul Bakkere5eae762013-08-26 12:05:14 +0200456{
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 while (list != NULL) {
458 if (list->oid.len == len &&
459 memcmp(list->oid.p, oid, len) == 0) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200460 break;
461 }
462
463 list = list->next;
464 }
465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 return list;
Paul Bakkere5eae762013-08-26 12:05:14 +0200467}
468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469#endif /* MBEDTLS_ASN1_PARSE_C */