blob: c02b233eca9129e536f8d09253301d22215c8479 [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
Agathiyan Bragadeeshfca08612023-09-04 15:45:37 +010010#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C)
Paul Bakkerefc30292011-11-10 14:43:23 +000011
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000012#include "mbedtls/asn1.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050013#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000014#include "mbedtls/error.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000015
Rich Evans00ab4702015-02-06 13:43:58 +000016#include <string.h>
17
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020018#if defined(MBEDTLS_BIGNUM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000019#include "mbedtls/bignum.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000020#endif
21
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000022#include "mbedtls/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020023
Paul Bakkerefc30292011-11-10 14:43:23 +000024/*
25 * ASN.1 DER decoding routines
26 */
Gilles Peskine449bd832023-01-11 14:50:10 +010027int mbedtls_asn1_get_len(unsigned char **p,
28 const unsigned char *end,
29 size_t *len)
Paul Bakkerefc30292011-11-10 14:43:23 +000030{
Gilles Peskine449bd832023-01-11 14:50:10 +010031 if ((end - *p) < 1) {
32 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
33 }
Paul Bakkerefc30292011-11-10 14:43:23 +000034
Gilles Peskine449bd832023-01-11 14:50:10 +010035 if ((**p & 0x80) == 0) {
Paul Bakkerefc30292011-11-10 14:43:23 +000036 *len = *(*p)++;
Gilles Peskine449bd832023-01-11 14:50:10 +010037 } else {
Dave Rodgmanef6795d2023-09-12 14:42:46 +010038 int n = (**p) & 0x7F;
39 if (n == 0 || n > 4) {
40 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
41 }
42 if ((end - *p) <= n) {
43 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
44 }
45 *len = 0;
46 (*p)++;
47 while (n--) {
48 *len = (*len << 8) | **p;
49 (*p)++;
Paul Bakkerefc30292011-11-10 14:43:23 +000050 }
51 }
52
Gilles Peskine449bd832023-01-11 14:50:10 +010053 if (*len > (size_t) (end - *p)) {
54 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
55 }
Paul Bakkerefc30292011-11-10 14:43:23 +000056
Gilles Peskine449bd832023-01-11 14:50:10 +010057 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +000058}
59
Gilles Peskine449bd832023-01-11 14:50:10 +010060int mbedtls_asn1_get_tag(unsigned char **p,
61 const unsigned char *end,
62 size_t *len, int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +000063{
Gilles Peskine449bd832023-01-11 14:50:10 +010064 if ((end - *p) < 1) {
65 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
66 }
Paul Bakkerefc30292011-11-10 14:43:23 +000067
Gilles Peskine449bd832023-01-11 14:50:10 +010068 if (**p != tag) {
69 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
70 }
Paul Bakkerefc30292011-11-10 14:43:23 +000071
72 (*p)++;
73
Gilles Peskine449bd832023-01-11 14:50:10 +010074 return mbedtls_asn1_get_len(p, end, len);
Paul Bakkerefc30292011-11-10 14:43:23 +000075}
Agathiyan Bragadeeshfca08612023-09-04 15:45:37 +010076#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */
Paul Bakkerefc30292011-11-10 14:43:23 +000077
Agathiyan Bragadeeshfca08612023-09-04 15:45:37 +010078#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010079int mbedtls_asn1_get_bool(unsigned char **p,
80 const unsigned char *end,
81 int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +000082{
Janos Follath24eed8d2019-11-22 13:21:35 +000083 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +000084 size_t len;
85
Gilles Peskine449bd832023-01-11 14:50:10 +010086 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
87 return ret;
88 }
Paul Bakkerefc30292011-11-10 14:43:23 +000089
Gilles Peskine449bd832023-01-11 14:50:10 +010090 if (len != 1) {
91 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
92 }
Paul Bakkerefc30292011-11-10 14:43:23 +000093
Gilles Peskine449bd832023-01-11 14:50:10 +010094 *val = (**p != 0) ? 1 : 0;
Paul Bakkerefc30292011-11-10 14:43:23 +000095 (*p)++;
96
Gilles Peskine449bd832023-01-11 14:50:10 +010097 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +000098}
99
Gilles Peskine449bd832023-01-11 14:50:10 +0100100static int asn1_get_tagged_int(unsigned char **p,
101 const unsigned char *end,
102 int tag, int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +0000103{
Janos Follath24eed8d2019-11-22 13:21:35 +0000104 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000105 size_t len;
106
Gilles Peskine449bd832023-01-11 14:50:10 +0100107 if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
108 return ret;
109 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000110
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200111 /*
112 * len==0 is malformed (0 must be represented as 020100 for INTEGER,
113 * or 0A0100 for ENUMERATED tags
114 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 if (len == 0) {
116 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
117 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200118 /* This is a cryptography library. Reject negative integers. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100119 if ((**p & 0x80) != 0) {
120 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
121 }
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100122
Gilles Peskine9fd97942019-10-10 19:27:53 +0200123 /* Skip leading zeros. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 while (len > 0 && **p == 0) {
125 ++(*p);
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100126 --len;
127 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200128
129 /* Reject integers that don't fit in an int. This code assumes that
130 * the int type has no padding bit. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 if (len > sizeof(int)) {
132 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
133 }
134 if (len == sizeof(int) && (**p & 0x80) != 0) {
135 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
136 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000137
138 *val = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 while (len-- > 0) {
140 *val = (*val << 8) | **p;
Paul Bakkerefc30292011-11-10 14:43:23 +0000141 (*p)++;
142 }
143
Gilles Peskine449bd832023-01-11 14:50:10 +0100144 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000145}
146
Gilles Peskine449bd832023-01-11 14:50:10 +0100147int mbedtls_asn1_get_int(unsigned char **p,
148 const unsigned char *end,
149 int *val)
150{
151 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
152}
153
154int mbedtls_asn1_get_enum(unsigned char **p,
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200155 const unsigned char *end,
Gilles Peskine449bd832023-01-11 14:50:10 +0100156 int *val)
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200157{
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200159}
160
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161#if defined(MBEDTLS_BIGNUM_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100162int mbedtls_asn1_get_mpi(unsigned char **p,
163 const unsigned char *end,
164 mbedtls_mpi *X)
Paul Bakkerefc30292011-11-10 14:43:23 +0000165{
Janos Follath24eed8d2019-11-22 13:21:35 +0000166 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000167 size_t len;
168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
170 return ret;
171 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 ret = mbedtls_mpi_read_binary(X, *p, len);
Paul Bakkerefc30292011-11-10 14:43:23 +0000174
175 *p += len;
176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 return ret;
Paul Bakkerefc30292011-11-10 14:43:23 +0000178}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200179#endif /* MBEDTLS_BIGNUM_C */
Paul Bakkerefc30292011-11-10 14:43:23 +0000180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
182 mbedtls_asn1_bitstring *bs)
Paul Bakkerefc30292011-11-10 14:43:23 +0000183{
Janos Follath24eed8d2019-11-22 13:21:35 +0000184 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000185
186 /* Certificate type is a single byte bitstring */
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
188 return ret;
189 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000190
191 /* Check length, subtract one for actual bit string length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 if (bs->len < 1) {
193 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
194 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000195 bs->len -= 1;
196
197 /* Get number of unused bits, ensure unused bits <= 7 */
198 bs->unused_bits = **p;
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 if (bs->unused_bits > 7) {
200 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
201 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000202 (*p)++;
203
204 /* Get actual bitstring */
205 bs->p = *p;
206 *p += bs->len;
207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 if (*p != end) {
209 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
210 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000211
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000213}
214
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200215/*
Hanno Becker199b7092019-09-11 14:21:26 +0100216 * Traverse an ASN.1 "SEQUENCE OF <tag>"
217 * and call a callback for each entry found.
218 */
219int mbedtls_asn1_traverse_sequence_of(
220 unsigned char **p,
221 const unsigned char *end,
Hanno Becker34aada22020-02-03 10:39:55 +0000222 unsigned char tag_must_mask, unsigned char tag_must_val,
223 unsigned char tag_may_mask, unsigned char tag_may_val,
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 int (*cb)(void *ctx, int tag,
225 unsigned char *start, size_t len),
226 void *ctx)
Hanno Becker199b7092019-09-11 14:21:26 +0100227{
228 int ret;
229 size_t len;
230
231 /* Get main sequence tag */
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
233 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
234 return ret;
Hanno Becker199b7092019-09-11 14:21:26 +0100235 }
236
Gilles Peskine449bd832023-01-11 14:50:10 +0100237 if (*p + len != end) {
238 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
239 }
Hanno Becker199b7092019-09-11 14:21:26 +0100240
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 while (*p < end) {
Hanno Becker199b7092019-09-11 14:21:26 +0100242 unsigned char const tag = *(*p)++;
243
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 if ((tag & tag_must_mask) != tag_must_val) {
245 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
246 }
Hanno Becker199b7092019-09-11 14:21:26 +0100247
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
249 return ret;
250 }
Hanno Becker199b7092019-09-11 14:21:26 +0100251
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 if ((tag & tag_may_mask) == tag_may_val) {
253 if (cb != NULL) {
254 ret = cb(ctx, tag, *p, len);
255 if (ret != 0) {
256 return ret;
257 }
Hanno Becker199b7092019-09-11 14:21:26 +0100258 }
259 }
260
261 *p += len;
262 }
263
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 return 0;
Hanno Becker199b7092019-09-11 14:21:26 +0100265}
266
267/*
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200268 * Get a bit string without unused bits
269 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100270int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
271 size_t *len)
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200272{
Janos Follath24eed8d2019-11-22 13:21:35 +0000273 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200274
Gilles Peskine449bd832023-01-11 14:50:10 +0100275 if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
276 return ret;
277 }
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200278
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 if (*len == 0) {
280 return MBEDTLS_ERR_ASN1_INVALID_DATA;
281 }
282 --(*len);
Gilles Peskinee40d1202019-03-01 18:08:35 +0100283
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 if (**p != 0) {
285 return MBEDTLS_ERR_ASN1_INVALID_DATA;
286 }
287 ++(*p);
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200288
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 return 0;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200290}
291
Gilles Peskine449bd832023-01-11 14:50:10 +0100292void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
Hanno Becker12ae27d2019-09-11 14:20:09 +0100293{
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 while (seq != NULL) {
Hanno Becker12ae27d2019-09-11 14:20:09 +0100295 mbedtls_asn1_sequence *next = seq->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 mbedtls_free(seq);
Hanno Becker12ae27d2019-09-11 14:20:09 +0100297 seq = next;
298 }
299}
Paul Bakkerefc30292011-11-10 14:43:23 +0000300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301typedef struct {
Hanno Becker1505f632019-09-11 14:25:26 +0100302 int tag;
303 mbedtls_asn1_sequence *cur;
304} asn1_get_sequence_of_cb_ctx_t;
305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306static int asn1_get_sequence_of_cb(void *ctx,
307 int tag,
308 unsigned char *start,
309 size_t len)
Hanno Becker1505f632019-09-11 14:25:26 +0100310{
311 asn1_get_sequence_of_cb_ctx_t *cb_ctx =
312 (asn1_get_sequence_of_cb_ctx_t *) ctx;
313 mbedtls_asn1_sequence *cur =
314 cb_ctx->cur;
315
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 if (cur->buf.p != NULL) {
Hanno Becker1505f632019-09-11 14:25:26 +0100317 cur->next =
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
Hanno Becker1505f632019-09-11 14:25:26 +0100319
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 if (cur->next == NULL) {
321 return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
322 }
Hanno Becker1505f632019-09-11 14:25:26 +0100323
324 cur = cur->next;
325 }
326
327 cur->buf.p = start;
328 cur->buf.len = len;
329 cur->buf.tag = tag;
330
331 cb_ctx->cur = cur;
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 return 0;
Hanno Becker1505f632019-09-11 14:25:26 +0100333}
334
Paul Bakkerefc30292011-11-10 14:43:23 +0000335/*
336 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
337 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100338int mbedtls_asn1_get_sequence_of(unsigned char **p,
339 const unsigned char *end,
340 mbedtls_asn1_sequence *cur,
341 int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +0000342{
Hanno Becker1505f632019-09-11 14:25:26 +0100343 asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 memset(cur, 0, sizeof(mbedtls_asn1_sequence));
345 return mbedtls_asn1_traverse_sequence_of(
346 p, end, 0xFF, tag, 0, 0,
347 asn1_get_sequence_of_cb, &cb_ctx);
Paul Bakkerefc30292011-11-10 14:43:23 +0000348}
349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350int mbedtls_asn1_get_alg(unsigned char **p,
351 const unsigned char *end,
352 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200353{
Janos Follath24eed8d2019-11-22 13:21:35 +0000354 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200355 size_t len;
356
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
358 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
359 return ret;
360 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200361
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 if ((end - *p) < 1) {
363 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
364 }
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200365
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200366 alg->tag = **p;
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200367 end = *p + len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200368
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
370 return ret;
371 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200372
373 alg->p = *p;
374 *p += alg->len;
375
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 if (*p == end) {
377 mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
378 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200379 }
380
381 params->tag = **p;
382 (*p)++;
383
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0) {
385 return ret;
386 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200387
388 params->p = *p;
389 *p += params->len;
390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 if (*p != end) {
392 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
393 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200396}
397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398int mbedtls_asn1_get_alg_null(unsigned char **p,
399 const unsigned char *end,
400 mbedtls_asn1_buf *alg)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200401{
Janos Follath24eed8d2019-11-22 13:21:35 +0000402 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403 mbedtls_asn1_buf params;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200404
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 memset(&params, 0, sizeof(mbedtls_asn1_buf));
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200406
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0) {
408 return ret;
409 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200410
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
412 return MBEDTLS_ERR_ASN1_INVALID_DATA;
413 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200414
Gilles Peskine449bd832023-01-11 14:50:10 +0100415 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200416}
417
Glenn Strauss82ba2742022-11-04 04:01:23 -0400418#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100419void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
Paul Bakkere5eae762013-08-26 12:05:14 +0200420{
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 if (cur == NULL) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200422 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 }
Paul Bakkere5eae762013-08-26 12:05:14 +0200424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 mbedtls_free(cur->oid.p);
426 mbedtls_free(cur->val.p);
Paul Bakkere5eae762013-08-26 12:05:14 +0200427
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
Paul Bakkere5eae762013-08-26 12:05:14 +0200429}
Glenn Strauss82ba2742022-11-04 04:01:23 -0400430#endif /* MBEDTLS_DEPRECATED_REMOVED */
Paul Bakkere5eae762013-08-26 12:05:14 +0200431
Gilles Peskine449bd832023-01-11 14:50:10 +0100432void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
Paul Bakkerc547cc92013-09-09 12:01:23 +0200433{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434 mbedtls_asn1_named_data *cur;
Paul Bakkerc547cc92013-09-09 12:01:23 +0200435
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 while ((cur = *head) != NULL) {
Paul Bakkerc547cc92013-09-09 12:01:23 +0200437 *head = cur->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 mbedtls_free(cur->oid.p);
439 mbedtls_free(cur->val.p);
440 mbedtls_free(cur);
Paul Bakkerc547cc92013-09-09 12:01:23 +0200441 }
442}
443
Gilles Peskine449bd832023-01-11 14:50:10 +0100444void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name)
Glenn Straussa4b40412022-06-26 19:32:09 -0400445{
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 for (mbedtls_asn1_named_data *next; name != NULL; name = next) {
Glenn Straussa4b40412022-06-26 19:32:09 -0400447 next = name->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 mbedtls_free(name);
Glenn Straussa4b40412022-06-26 19:32:09 -0400449 }
450}
451
Gilles Peskine449bd832023-01-11 14:50:10 +0100452const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list,
453 const char *oid, size_t len)
Paul Bakkere5eae762013-08-26 12:05:14 +0200454{
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 while (list != NULL) {
456 if (list->oid.len == len &&
457 memcmp(list->oid.p, oid, len) == 0) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200458 break;
459 }
460
461 list = list->next;
462 }
463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 return list;
Paul Bakkere5eae762013-08-26 12:05:14 +0200465}
466
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467#endif /* MBEDTLS_ASN1_PARSE_C */