blob: abdd0b1bd0104aa52fb35f73148ac372068cc389 [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
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakkerefc30292011-11-10 14:43:23 +000018 */
19
Gilles Peskinedb09ef62020-06-03 01:43:33 +020020#include "common.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000021
Agathiyan Bragadeeshfca08612023-09-04 15:45:37 +010022#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C)
Paul Bakkerefc30292011-11-10 14:43:23 +000023
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000024#include "mbedtls/asn1.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050025#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000026#include "mbedtls/error.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000027
Rich Evans00ab4702015-02-06 13:43:58 +000028#include <string.h>
29
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#if defined(MBEDTLS_BIGNUM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000031#include "mbedtls/bignum.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000032#endif
33
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020035
Paul Bakkerefc30292011-11-10 14:43:23 +000036/*
37 * ASN.1 DER decoding routines
38 */
Gilles Peskine449bd832023-01-11 14:50:10 +010039int mbedtls_asn1_get_len(unsigned char **p,
40 const unsigned char *end,
41 size_t *len)
Paul Bakkerefc30292011-11-10 14:43:23 +000042{
Gilles Peskine449bd832023-01-11 14:50:10 +010043 if ((end - *p) < 1) {
44 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
45 }
Paul Bakkerefc30292011-11-10 14:43:23 +000046
Gilles Peskine449bd832023-01-11 14:50:10 +010047 if ((**p & 0x80) == 0) {
Paul Bakkerefc30292011-11-10 14:43:23 +000048 *len = *(*p)++;
Gilles Peskine449bd832023-01-11 14:50:10 +010049 } else {
Dave Rodgmanef6795d2023-09-12 14:42:46 +010050 int n = (**p) & 0x7F;
51 if (n == 0 || n > 4) {
52 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
53 }
54 if ((end - *p) <= n) {
55 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
56 }
57 *len = 0;
58 (*p)++;
59 while (n--) {
60 *len = (*len << 8) | **p;
61 (*p)++;
Paul Bakkerefc30292011-11-10 14:43:23 +000062 }
63 }
64
Gilles Peskine449bd832023-01-11 14:50:10 +010065 if (*len > (size_t) (end - *p)) {
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 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +000070}
71
Gilles Peskine449bd832023-01-11 14:50:10 +010072int mbedtls_asn1_get_tag(unsigned char **p,
73 const unsigned char *end,
74 size_t *len, int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +000075{
Gilles Peskine449bd832023-01-11 14:50:10 +010076 if ((end - *p) < 1) {
77 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
78 }
Paul Bakkerefc30292011-11-10 14:43:23 +000079
Gilles Peskine449bd832023-01-11 14:50:10 +010080 if (**p != tag) {
81 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
82 }
Paul Bakkerefc30292011-11-10 14:43:23 +000083
84 (*p)++;
85
Gilles Peskine449bd832023-01-11 14:50:10 +010086 return mbedtls_asn1_get_len(p, end, len);
Paul Bakkerefc30292011-11-10 14:43:23 +000087}
Agathiyan Bragadeeshfca08612023-09-04 15:45:37 +010088#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */
Paul Bakkerefc30292011-11-10 14:43:23 +000089
Agathiyan Bragadeeshfca08612023-09-04 15:45:37 +010090#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010091int mbedtls_asn1_get_bool(unsigned char **p,
92 const unsigned char *end,
93 int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +000094{
Janos Follath24eed8d2019-11-22 13:21:35 +000095 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +000096 size_t len;
97
Gilles Peskine449bd832023-01-11 14:50:10 +010098 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
99 return ret;
100 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000101
Gilles Peskine449bd832023-01-11 14:50:10 +0100102 if (len != 1) {
103 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
104 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000105
Gilles Peskine449bd832023-01-11 14:50:10 +0100106 *val = (**p != 0) ? 1 : 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000107 (*p)++;
108
Gilles Peskine449bd832023-01-11 14:50:10 +0100109 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000110}
111
Gilles Peskine449bd832023-01-11 14:50:10 +0100112static int asn1_get_tagged_int(unsigned char **p,
113 const unsigned char *end,
114 int tag, int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +0000115{
Janos Follath24eed8d2019-11-22 13:21:35 +0000116 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000117 size_t len;
118
Gilles Peskine449bd832023-01-11 14:50:10 +0100119 if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
120 return ret;
121 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000122
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200123 /*
124 * len==0 is malformed (0 must be represented as 020100 for INTEGER,
125 * or 0A0100 for ENUMERATED tags
126 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 if (len == 0) {
128 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
129 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200130 /* This is a cryptography library. Reject negative integers. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 if ((**p & 0x80) != 0) {
132 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
133 }
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100134
Gilles Peskine9fd97942019-10-10 19:27:53 +0200135 /* Skip leading zeros. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 while (len > 0 && **p == 0) {
137 ++(*p);
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100138 --len;
139 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200140
141 /* Reject integers that don't fit in an int. This code assumes that
142 * the int type has no padding bit. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 if (len > sizeof(int)) {
144 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
145 }
146 if (len == sizeof(int) && (**p & 0x80) != 0) {
147 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
148 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000149
150 *val = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 while (len-- > 0) {
152 *val = (*val << 8) | **p;
Paul Bakkerefc30292011-11-10 14:43:23 +0000153 (*p)++;
154 }
155
Gilles Peskine449bd832023-01-11 14:50:10 +0100156 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000157}
158
Gilles Peskine449bd832023-01-11 14:50:10 +0100159int mbedtls_asn1_get_int(unsigned char **p,
160 const unsigned char *end,
161 int *val)
162{
163 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
164}
165
166int mbedtls_asn1_get_enum(unsigned char **p,
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200167 const unsigned char *end,
Gilles Peskine449bd832023-01-11 14:50:10 +0100168 int *val)
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200169{
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200171}
172
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173#if defined(MBEDTLS_BIGNUM_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100174int mbedtls_asn1_get_mpi(unsigned char **p,
175 const unsigned char *end,
176 mbedtls_mpi *X)
Paul Bakkerefc30292011-11-10 14:43:23 +0000177{
Janos Follath24eed8d2019-11-22 13:21:35 +0000178 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000179 size_t len;
180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
182 return ret;
183 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000184
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 ret = mbedtls_mpi_read_binary(X, *p, len);
Paul Bakkerefc30292011-11-10 14:43:23 +0000186
187 *p += len;
188
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 return ret;
Paul Bakkerefc30292011-11-10 14:43:23 +0000190}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200191#endif /* MBEDTLS_BIGNUM_C */
Paul Bakkerefc30292011-11-10 14:43:23 +0000192
Gilles Peskine449bd832023-01-11 14:50:10 +0100193int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
194 mbedtls_asn1_bitstring *bs)
Paul Bakkerefc30292011-11-10 14:43:23 +0000195{
Janos Follath24eed8d2019-11-22 13:21:35 +0000196 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000197
198 /* Certificate type is a single byte bitstring */
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
200 return ret;
201 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000202
203 /* Check length, subtract one for actual bit string length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 if (bs->len < 1) {
205 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
206 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000207 bs->len -= 1;
208
209 /* Get number of unused bits, ensure unused bits <= 7 */
210 bs->unused_bits = **p;
Gilles Peskine449bd832023-01-11 14:50:10 +0100211 if (bs->unused_bits > 7) {
212 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
213 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000214 (*p)++;
215
216 /* Get actual bitstring */
217 bs->p = *p;
218 *p += bs->len;
219
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 if (*p != end) {
221 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
222 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000225}
226
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200227/*
Hanno Becker199b7092019-09-11 14:21:26 +0100228 * Traverse an ASN.1 "SEQUENCE OF <tag>"
229 * and call a callback for each entry found.
230 */
231int mbedtls_asn1_traverse_sequence_of(
232 unsigned char **p,
233 const unsigned char *end,
Hanno Becker34aada22020-02-03 10:39:55 +0000234 unsigned char tag_must_mask, unsigned char tag_must_val,
235 unsigned char tag_may_mask, unsigned char tag_may_val,
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 int (*cb)(void *ctx, int tag,
237 unsigned char *start, size_t len),
238 void *ctx)
Hanno Becker199b7092019-09-11 14:21:26 +0100239{
240 int ret;
241 size_t len;
242
243 /* Get main sequence tag */
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
245 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
246 return ret;
Hanno Becker199b7092019-09-11 14:21:26 +0100247 }
248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 if (*p + len != end) {
250 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
251 }
Hanno Becker199b7092019-09-11 14:21:26 +0100252
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 while (*p < end) {
Hanno Becker199b7092019-09-11 14:21:26 +0100254 unsigned char const tag = *(*p)++;
255
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 if ((tag & tag_must_mask) != tag_must_val) {
257 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
258 }
Hanno Becker199b7092019-09-11 14:21:26 +0100259
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
261 return ret;
262 }
Hanno Becker199b7092019-09-11 14:21:26 +0100263
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 if ((tag & tag_may_mask) == tag_may_val) {
265 if (cb != NULL) {
266 ret = cb(ctx, tag, *p, len);
267 if (ret != 0) {
268 return ret;
269 }
Hanno Becker199b7092019-09-11 14:21:26 +0100270 }
271 }
272
273 *p += len;
274 }
275
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 return 0;
Hanno Becker199b7092019-09-11 14:21:26 +0100277}
278
279/*
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200280 * Get a bit string without unused bits
281 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100282int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
283 size_t *len)
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200284{
Janos Follath24eed8d2019-11-22 13:21:35 +0000285 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200286
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
288 return ret;
289 }
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 if (*len == 0) {
292 return MBEDTLS_ERR_ASN1_INVALID_DATA;
293 }
294 --(*len);
Gilles Peskinee40d1202019-03-01 18:08:35 +0100295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 if (**p != 0) {
297 return MBEDTLS_ERR_ASN1_INVALID_DATA;
298 }
299 ++(*p);
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 return 0;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200302}
303
Gilles Peskine449bd832023-01-11 14:50:10 +0100304void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
Hanno Becker12ae27d2019-09-11 14:20:09 +0100305{
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 while (seq != NULL) {
Hanno Becker12ae27d2019-09-11 14:20:09 +0100307 mbedtls_asn1_sequence *next = seq->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 mbedtls_free(seq);
Hanno Becker12ae27d2019-09-11 14:20:09 +0100309 seq = next;
310 }
311}
Paul Bakkerefc30292011-11-10 14:43:23 +0000312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313typedef struct {
Hanno Becker1505f632019-09-11 14:25:26 +0100314 int tag;
315 mbedtls_asn1_sequence *cur;
316} asn1_get_sequence_of_cb_ctx_t;
317
Gilles Peskine449bd832023-01-11 14:50:10 +0100318static int asn1_get_sequence_of_cb(void *ctx,
319 int tag,
320 unsigned char *start,
321 size_t len)
Hanno Becker1505f632019-09-11 14:25:26 +0100322{
323 asn1_get_sequence_of_cb_ctx_t *cb_ctx =
324 (asn1_get_sequence_of_cb_ctx_t *) ctx;
325 mbedtls_asn1_sequence *cur =
326 cb_ctx->cur;
327
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 if (cur->buf.p != NULL) {
Hanno Becker1505f632019-09-11 14:25:26 +0100329 cur->next =
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
Hanno Becker1505f632019-09-11 14:25:26 +0100331
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 if (cur->next == NULL) {
333 return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
334 }
Hanno Becker1505f632019-09-11 14:25:26 +0100335
336 cur = cur->next;
337 }
338
339 cur->buf.p = start;
340 cur->buf.len = len;
341 cur->buf.tag = tag;
342
343 cb_ctx->cur = cur;
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 return 0;
Hanno Becker1505f632019-09-11 14:25:26 +0100345}
346
Paul Bakkerefc30292011-11-10 14:43:23 +0000347/*
348 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
349 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100350int mbedtls_asn1_get_sequence_of(unsigned char **p,
351 const unsigned char *end,
352 mbedtls_asn1_sequence *cur,
353 int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +0000354{
Hanno Becker1505f632019-09-11 14:25:26 +0100355 asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 memset(cur, 0, sizeof(mbedtls_asn1_sequence));
357 return mbedtls_asn1_traverse_sequence_of(
358 p, end, 0xFF, tag, 0, 0,
359 asn1_get_sequence_of_cb, &cb_ctx);
Paul Bakkerefc30292011-11-10 14:43:23 +0000360}
361
Gilles Peskine449bd832023-01-11 14:50:10 +0100362int mbedtls_asn1_get_alg(unsigned char **p,
363 const unsigned char *end,
364 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200365{
Janos Follath24eed8d2019-11-22 13:21:35 +0000366 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200367 size_t len;
368
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
370 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
371 return ret;
372 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200373
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 if ((end - *p) < 1) {
375 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
376 }
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200377
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200378 alg->tag = **p;
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200379 end = *p + len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200380
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
382 return ret;
383 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200384
385 alg->p = *p;
386 *p += alg->len;
387
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 if (*p == end) {
389 mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
390 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200391 }
392
393 params->tag = **p;
394 (*p)++;
395
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0) {
397 return ret;
398 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200399
400 params->p = *p;
401 *p += params->len;
402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 if (*p != end) {
404 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
405 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200406
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200408}
409
Gilles Peskine449bd832023-01-11 14:50:10 +0100410int mbedtls_asn1_get_alg_null(unsigned char **p,
411 const unsigned char *end,
412 mbedtls_asn1_buf *alg)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200413{
Janos Follath24eed8d2019-11-22 13:21:35 +0000414 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415 mbedtls_asn1_buf params;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200416
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 memset(&params, 0, sizeof(mbedtls_asn1_buf));
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200418
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0) {
420 return ret;
421 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200422
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
424 return MBEDTLS_ERR_ASN1_INVALID_DATA;
425 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200426
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200428}
429
Glenn Strauss82ba2742022-11-04 04:01:23 -0400430#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100431void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
Paul Bakkere5eae762013-08-26 12:05:14 +0200432{
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 if (cur == NULL) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200434 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 }
Paul Bakkere5eae762013-08-26 12:05:14 +0200436
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 mbedtls_free(cur->oid.p);
438 mbedtls_free(cur->val.p);
Paul Bakkere5eae762013-08-26 12:05:14 +0200439
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
Paul Bakkere5eae762013-08-26 12:05:14 +0200441}
Glenn Strauss82ba2742022-11-04 04:01:23 -0400442#endif /* MBEDTLS_DEPRECATED_REMOVED */
Paul Bakkere5eae762013-08-26 12:05:14 +0200443
Gilles Peskine449bd832023-01-11 14:50:10 +0100444void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
Paul Bakkerc547cc92013-09-09 12:01:23 +0200445{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 mbedtls_asn1_named_data *cur;
Paul Bakkerc547cc92013-09-09 12:01:23 +0200447
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 while ((cur = *head) != NULL) {
Paul Bakkerc547cc92013-09-09 12:01:23 +0200449 *head = cur->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 mbedtls_free(cur->oid.p);
451 mbedtls_free(cur->val.p);
452 mbedtls_free(cur);
Paul Bakkerc547cc92013-09-09 12:01:23 +0200453 }
454}
455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name)
Glenn Straussa4b40412022-06-26 19:32:09 -0400457{
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 for (mbedtls_asn1_named_data *next; name != NULL; name = next) {
Glenn Straussa4b40412022-06-26 19:32:09 -0400459 next = name->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 mbedtls_free(name);
Glenn Straussa4b40412022-06-26 19:32:09 -0400461 }
462}
463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list,
465 const char *oid, size_t len)
Paul Bakkere5eae762013-08-26 12:05:14 +0200466{
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 while (list != NULL) {
468 if (list->oid.len == len &&
469 memcmp(list->oid.p, oid, len) == 0) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200470 break;
471 }
472
473 list = list->next;
474 }
475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 return list;
Paul Bakkere5eae762013-08-26 12:05:14 +0200477}
478
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479#endif /* MBEDTLS_ASN1_PARSE_C */