blob: c7f7f0b33a5b8be3b60acbebf8b967a5f8dadf2c [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 Rodgman7ff79652023-11-03 12:04:52 +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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020010#if defined(MBEDTLS_ASN1_PARSE_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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +010031 if ((end - *p) < 1) {
32 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
33 }
Paul Bakkerefc30292011-11-10 14:43:23 +000034
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010035 if ((**p & 0x80) == 0) {
Paul Bakkerefc30292011-11-10 14:43:23 +000036 *len = *(*p)++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010037 } else {
38 switch (**p & 0x7F) {
39 case 1:
40 if ((end - *p) < 2) {
41 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
42 }
Paul Bakkerefc30292011-11-10 14:43:23 +000043
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010044 *len = (*p)[1];
45 (*p) += 2;
46 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000047
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010048 case 2:
49 if ((end - *p) < 3) {
50 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
51 }
Paul Bakkerefc30292011-11-10 14:43:23 +000052
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010053 *len = ((size_t) (*p)[1] << 8) | (*p)[2];
54 (*p) += 3;
55 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000056
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010057 case 3:
58 if ((end - *p) < 4) {
59 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
60 }
Paul Bakkerefc30292011-11-10 14:43:23 +000061
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010062 *len = ((size_t) (*p)[1] << 16) |
63 ((size_t) (*p)[2] << 8) | (*p)[3];
64 (*p) += 4;
65 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000066
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010067 case 4:
68 if ((end - *p) < 5) {
69 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
70 }
Paul Bakkerefc30292011-11-10 14:43:23 +000071
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010072 *len = ((size_t) (*p)[1] << 24) | ((size_t) (*p)[2] << 16) |
73 ((size_t) (*p)[3] << 8) | (*p)[4];
74 (*p) += 5;
75 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000076
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010077 default:
78 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
Paul Bakkerefc30292011-11-10 14:43:23 +000079 }
80 }
81
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010082 if (*len > (size_t) (end - *p)) {
83 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
84 }
Paul Bakkerefc30292011-11-10 14:43:23 +000085
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010086 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +000087}
88
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010089int mbedtls_asn1_get_tag(unsigned char **p,
90 const unsigned char *end,
91 size_t *len, int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +000092{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010093 if ((end - *p) < 1) {
94 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
95 }
Paul Bakkerefc30292011-11-10 14:43:23 +000096
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010097 if (**p != tag) {
98 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
99 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000100
101 (*p)++;
102
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100103 return mbedtls_asn1_get_len(p, end, len);
Paul Bakkerefc30292011-11-10 14:43:23 +0000104}
105
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100106int mbedtls_asn1_get_bool(unsigned char **p,
107 const unsigned char *end,
108 int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +0000109{
Janos Follath24eed8d2019-11-22 13:21:35 +0000110 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000111 size_t len;
112
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100113 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
114 return ret;
115 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000116
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100117 if (len != 1) {
118 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
119 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000120
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100121 *val = (**p != 0) ? 1 : 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000122 (*p)++;
123
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100124 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000125}
126
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100127static int asn1_get_tagged_int(unsigned char **p,
128 const unsigned char *end,
129 int tag, int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +0000130{
Janos Follath24eed8d2019-11-22 13:21:35 +0000131 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000132 size_t len;
133
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100134 if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
135 return ret;
136 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000137
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200138 /*
139 * len==0 is malformed (0 must be represented as 020100 for INTEGER,
140 * or 0A0100 for ENUMERATED tags
141 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100142 if (len == 0) {
143 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
144 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200145 /* This is a cryptography library. Reject negative integers. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100146 if ((**p & 0x80) != 0) {
147 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
148 }
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100149
Gilles Peskine9fd97942019-10-10 19:27:53 +0200150 /* Skip leading zeros. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100151 while (len > 0 && **p == 0) {
152 ++(*p);
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100153 --len;
154 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200155
156 /* Reject integers that don't fit in an int. This code assumes that
157 * the int type has no padding bit. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100158 if (len > sizeof(int)) {
159 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
160 }
161 if (len == sizeof(int) && (**p & 0x80) != 0) {
162 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
163 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000164
165 *val = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100166 while (len-- > 0) {
167 *val = (*val << 8) | **p;
Paul Bakkerefc30292011-11-10 14:43:23 +0000168 (*p)++;
169 }
170
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100171 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000172}
173
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100174int mbedtls_asn1_get_int(unsigned char **p,
175 const unsigned char *end,
176 int *val)
177{
178 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
179}
180
181int mbedtls_asn1_get_enum(unsigned char **p,
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200182 const unsigned char *end,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100183 int *val)
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200184{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100185 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200186}
187
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200188#if defined(MBEDTLS_BIGNUM_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100189int mbedtls_asn1_get_mpi(unsigned char **p,
190 const unsigned char *end,
191 mbedtls_mpi *X)
Paul Bakkerefc30292011-11-10 14:43:23 +0000192{
Janos Follath24eed8d2019-11-22 13:21:35 +0000193 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000194 size_t len;
195
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100196 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
197 return ret;
198 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000199
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100200 ret = mbedtls_mpi_read_binary(X, *p, len);
Paul Bakkerefc30292011-11-10 14:43:23 +0000201
202 *p += len;
203
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100204 return ret;
Paul Bakkerefc30292011-11-10 14:43:23 +0000205}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200206#endif /* MBEDTLS_BIGNUM_C */
Paul Bakkerefc30292011-11-10 14:43:23 +0000207
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100208int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
209 mbedtls_asn1_bitstring *bs)
Paul Bakkerefc30292011-11-10 14:43:23 +0000210{
Janos Follath24eed8d2019-11-22 13:21:35 +0000211 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000212
213 /* Certificate type is a single byte bitstring */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100214 if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
215 return ret;
216 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000217
218 /* Check length, subtract one for actual bit string length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100219 if (bs->len < 1) {
220 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
221 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000222 bs->len -= 1;
223
224 /* Get number of unused bits, ensure unused bits <= 7 */
225 bs->unused_bits = **p;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100226 if (bs->unused_bits > 7) {
227 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
228 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000229 (*p)++;
230
231 /* Get actual bitstring */
232 bs->p = *p;
233 *p += bs->len;
234
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100235 if (*p != end) {
236 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
237 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000238
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100239 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000240}
241
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200242/*
Hanno Becker199b7092019-09-11 14:21:26 +0100243 * Traverse an ASN.1 "SEQUENCE OF <tag>"
244 * and call a callback for each entry found.
245 */
246int mbedtls_asn1_traverse_sequence_of(
247 unsigned char **p,
248 const unsigned char *end,
Hanno Becker34aada22020-02-03 10:39:55 +0000249 unsigned char tag_must_mask, unsigned char tag_must_val,
250 unsigned char tag_may_mask, unsigned char tag_may_val,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100251 int (*cb)(void *ctx, int tag,
252 unsigned char *start, size_t len),
253 void *ctx)
Hanno Becker199b7092019-09-11 14:21:26 +0100254{
255 int ret;
256 size_t len;
257
258 /* Get main sequence tag */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100259 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
260 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
261 return ret;
Hanno Becker199b7092019-09-11 14:21:26 +0100262 }
263
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100264 if (*p + len != end) {
265 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
266 }
Hanno Becker199b7092019-09-11 14:21:26 +0100267
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100268 while (*p < end) {
Hanno Becker199b7092019-09-11 14:21:26 +0100269 unsigned char const tag = *(*p)++;
270
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100271 if ((tag & tag_must_mask) != tag_must_val) {
272 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
273 }
Hanno Becker199b7092019-09-11 14:21:26 +0100274
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100275 if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
276 return ret;
277 }
Hanno Becker199b7092019-09-11 14:21:26 +0100278
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100279 if ((tag & tag_may_mask) == tag_may_val) {
280 if (cb != NULL) {
281 ret = cb(ctx, tag, *p, len);
282 if (ret != 0) {
283 return ret;
284 }
Hanno Becker199b7092019-09-11 14:21:26 +0100285 }
286 }
287
288 *p += len;
289 }
290
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100291 return 0;
Hanno Becker199b7092019-09-11 14:21:26 +0100292}
293
294/*
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200295 * Get a bit string without unused bits
296 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100297int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
298 size_t *len)
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200299{
Janos Follath24eed8d2019-11-22 13:21:35 +0000300 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200301
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100302 if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
303 return ret;
304 }
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200305
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100306 if (*len == 0) {
307 return MBEDTLS_ERR_ASN1_INVALID_DATA;
308 }
309 --(*len);
Gilles Peskinee40d1202019-03-01 18:08:35 +0100310
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100311 if (**p != 0) {
312 return MBEDTLS_ERR_ASN1_INVALID_DATA;
313 }
314 ++(*p);
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200315
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100316 return 0;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200317}
318
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100319void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
Hanno Becker12ae27d2019-09-11 14:20:09 +0100320{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100321 while (seq != NULL) {
Hanno Becker12ae27d2019-09-11 14:20:09 +0100322 mbedtls_asn1_sequence *next = seq->next;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100323 mbedtls_platform_zeroize(seq, sizeof(*seq));
324 mbedtls_free(seq);
Hanno Becker12ae27d2019-09-11 14:20:09 +0100325 seq = next;
326 }
327}
Paul Bakkerefc30292011-11-10 14:43:23 +0000328
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100329typedef struct {
Hanno Becker1505f632019-09-11 14:25:26 +0100330 int tag;
331 mbedtls_asn1_sequence *cur;
332} asn1_get_sequence_of_cb_ctx_t;
333
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100334static int asn1_get_sequence_of_cb(void *ctx,
335 int tag,
336 unsigned char *start,
337 size_t len)
Hanno Becker1505f632019-09-11 14:25:26 +0100338{
339 asn1_get_sequence_of_cb_ctx_t *cb_ctx =
340 (asn1_get_sequence_of_cb_ctx_t *) ctx;
341 mbedtls_asn1_sequence *cur =
342 cb_ctx->cur;
343
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100344 if (cur->buf.p != NULL) {
Hanno Becker1505f632019-09-11 14:25:26 +0100345 cur->next =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100346 mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
Hanno Becker1505f632019-09-11 14:25:26 +0100347
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100348 if (cur->next == NULL) {
349 return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
350 }
Hanno Becker1505f632019-09-11 14:25:26 +0100351
352 cur = cur->next;
353 }
354
355 cur->buf.p = start;
356 cur->buf.len = len;
357 cur->buf.tag = tag;
358
359 cb_ctx->cur = cur;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100360 return 0;
Hanno Becker1505f632019-09-11 14:25:26 +0100361}
362
Paul Bakkerefc30292011-11-10 14:43:23 +0000363/*
364 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
365 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100366int mbedtls_asn1_get_sequence_of(unsigned char **p,
367 const unsigned char *end,
368 mbedtls_asn1_sequence *cur,
369 int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +0000370{
Hanno Becker1505f632019-09-11 14:25:26 +0100371 asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100372 memset(cur, 0, sizeof(mbedtls_asn1_sequence));
373 return mbedtls_asn1_traverse_sequence_of(
374 p, end, 0xFF, tag, 0, 0,
375 asn1_get_sequence_of_cb, &cb_ctx);
Paul Bakkerefc30292011-11-10 14:43:23 +0000376}
377
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100378int mbedtls_asn1_get_alg(unsigned char **p,
379 const unsigned char *end,
380 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200381{
Janos Follath24eed8d2019-11-22 13:21:35 +0000382 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200383 size_t len;
384
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
386 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
387 return ret;
388 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200389
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390 if ((end - *p) < 1) {
391 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
392 }
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200393
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200394 alg->tag = **p;
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200395 end = *p + len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200396
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100397 if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
398 return ret;
399 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200400
401 alg->p = *p;
402 *p += alg->len;
403
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100404 if (*p == end) {
405 mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
406 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200407 }
408
409 params->tag = **p;
410 (*p)++;
411
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100412 if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0) {
413 return ret;
414 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200415
416 params->p = *p;
417 *p += params->len;
418
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100419 if (*p != end) {
420 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
421 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200422
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100423 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200424}
425
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100426int mbedtls_asn1_get_alg_null(unsigned char **p,
427 const unsigned char *end,
428 mbedtls_asn1_buf *alg)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200429{
Janos Follath24eed8d2019-11-22 13:21:35 +0000430 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431 mbedtls_asn1_buf params;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200432
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100433 memset(&params, 0, sizeof(mbedtls_asn1_buf));
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200434
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100435 if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0) {
436 return ret;
437 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200438
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100439 if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
440 return MBEDTLS_ERR_ASN1_INVALID_DATA;
441 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200442
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100443 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200444}
445
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100446void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
Paul Bakkere5eae762013-08-26 12:05:14 +0200447{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100448 if (cur == NULL) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200449 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100450 }
Paul Bakkere5eae762013-08-26 12:05:14 +0200451
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100452 mbedtls_free(cur->oid.p);
453 mbedtls_free(cur->val.p);
Paul Bakkere5eae762013-08-26 12:05:14 +0200454
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100455 mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
Paul Bakkere5eae762013-08-26 12:05:14 +0200456}
457
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100458void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
Paul Bakkerc547cc92013-09-09 12:01:23 +0200459{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 mbedtls_asn1_named_data *cur;
Paul Bakkerc547cc92013-09-09 12:01:23 +0200461
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100462 while ((cur = *head) != NULL) {
Paul Bakkerc547cc92013-09-09 12:01:23 +0200463 *head = cur->next;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100464 mbedtls_asn1_free_named_data(cur);
465 mbedtls_free(cur);
Paul Bakkerc547cc92013-09-09 12:01:23 +0200466 }
467}
468
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100469mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(mbedtls_asn1_named_data *list,
470 const char *oid, size_t len)
Paul Bakkere5eae762013-08-26 12:05:14 +0200471{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100472 while (list != NULL) {
473 if (list->oid.len == len &&
474 memcmp(list->oid.p, oid, len) == 0) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200475 break;
476 }
477
478 list = list->next;
479 }
480
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100481 return list;
Paul Bakkere5eae762013-08-26 12:05:14 +0200482}
483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484#endif /* MBEDTLS_ASN1_PARSE_C */