blob: 6a8cd6c54547ef77c654ce02f0ad9ee5a34b0c01 [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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022#if defined(MBEDTLS_ASN1_PARSE_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 */
David Horstmannceeaeb92023-01-05 15:44:23 +000039int mbedtls_asn1_get_len(unsigned char **p,
40 const unsigned char *end,
41 size_t *len)
Paul Bakkerefc30292011-11-10 14:43:23 +000042{
David Horstmannceeaeb92023-01-05 15:44:23 +000043 if ((end - *p) < 1) {
44 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
45 }
Paul Bakkerefc30292011-11-10 14:43:23 +000046
David Horstmannceeaeb92023-01-05 15:44:23 +000047 if ((**p & 0x80) == 0) {
Paul Bakkerefc30292011-11-10 14:43:23 +000048 *len = *(*p)++;
David Horstmannceeaeb92023-01-05 15:44:23 +000049 } else {
50 switch (**p & 0x7F) {
51 case 1:
52 if ((end - *p) < 2) {
53 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
54 }
Paul Bakkerefc30292011-11-10 14:43:23 +000055
David Horstmannceeaeb92023-01-05 15:44:23 +000056 *len = (*p)[1];
57 (*p) += 2;
58 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000059
David Horstmannceeaeb92023-01-05 15:44:23 +000060 case 2:
61 if ((end - *p) < 3) {
62 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
63 }
Paul Bakkerefc30292011-11-10 14:43:23 +000064
David Horstmannceeaeb92023-01-05 15:44:23 +000065 *len = ((size_t) (*p)[1] << 8) | (*p)[2];
66 (*p) += 3;
67 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000068
David Horstmannceeaeb92023-01-05 15:44:23 +000069 case 3:
70 if ((end - *p) < 4) {
71 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
72 }
Paul Bakkerefc30292011-11-10 14:43:23 +000073
David Horstmannceeaeb92023-01-05 15:44:23 +000074 *len = ((size_t) (*p)[1] << 16) |
75 ((size_t) (*p)[2] << 8) | (*p)[3];
76 (*p) += 4;
77 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000078
David Horstmannceeaeb92023-01-05 15:44:23 +000079 case 4:
80 if ((end - *p) < 5) {
81 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
82 }
Paul Bakkerefc30292011-11-10 14:43:23 +000083
David Horstmannceeaeb92023-01-05 15:44:23 +000084 *len = ((size_t) (*p)[1] << 24) | ((size_t) (*p)[2] << 16) |
85 ((size_t) (*p)[3] << 8) | (*p)[4];
86 (*p) += 5;
87 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000088
David Horstmannceeaeb92023-01-05 15:44:23 +000089 default:
90 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
Paul Bakkerefc30292011-11-10 14:43:23 +000091 }
92 }
93
David Horstmannceeaeb92023-01-05 15:44:23 +000094 if (*len > (size_t) (end - *p)) {
95 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
96 }
Paul Bakkerefc30292011-11-10 14:43:23 +000097
David Horstmannceeaeb92023-01-05 15:44:23 +000098 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +000099}
100
David Horstmannceeaeb92023-01-05 15:44:23 +0000101int mbedtls_asn1_get_tag(unsigned char **p,
102 const unsigned char *end,
103 size_t *len, int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +0000104{
David Horstmannceeaeb92023-01-05 15:44:23 +0000105 if ((end - *p) < 1) {
106 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
107 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000108
David Horstmannceeaeb92023-01-05 15:44:23 +0000109 if (**p != tag) {
110 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
111 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000112
113 (*p)++;
114
David Horstmannceeaeb92023-01-05 15:44:23 +0000115 return mbedtls_asn1_get_len(p, end, len);
Paul Bakkerefc30292011-11-10 14:43:23 +0000116}
117
David Horstmannceeaeb92023-01-05 15:44:23 +0000118int mbedtls_asn1_get_bool(unsigned char **p,
119 const unsigned char *end,
120 int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +0000121{
Janos Follath24eed8d2019-11-22 13:21:35 +0000122 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000123 size_t len;
124
David Horstmannceeaeb92023-01-05 15:44:23 +0000125 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
126 return ret;
127 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000128
David Horstmannceeaeb92023-01-05 15:44:23 +0000129 if (len != 1) {
130 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
131 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000132
David Horstmannceeaeb92023-01-05 15:44:23 +0000133 *val = (**p != 0) ? 1 : 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000134 (*p)++;
135
David Horstmannceeaeb92023-01-05 15:44:23 +0000136 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000137}
138
David Horstmannceeaeb92023-01-05 15:44:23 +0000139static int asn1_get_tagged_int(unsigned char **p,
140 const unsigned char *end,
141 int tag, int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +0000142{
Janos Follath24eed8d2019-11-22 13:21:35 +0000143 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000144 size_t len;
145
David Horstmannceeaeb92023-01-05 15:44:23 +0000146 if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
147 return ret;
148 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000149
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200150 /*
151 * len==0 is malformed (0 must be represented as 020100 for INTEGER,
152 * or 0A0100 for ENUMERATED tags
153 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000154 if (len == 0) {
155 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
156 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200157 /* This is a cryptography library. Reject negative integers. */
David Horstmannceeaeb92023-01-05 15:44:23 +0000158 if ((**p & 0x80) != 0) {
159 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
160 }
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100161
Gilles Peskine9fd97942019-10-10 19:27:53 +0200162 /* Skip leading zeros. */
David Horstmannceeaeb92023-01-05 15:44:23 +0000163 while (len > 0 && **p == 0) {
164 ++(*p);
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100165 --len;
166 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200167
168 /* Reject integers that don't fit in an int. This code assumes that
169 * the int type has no padding bit. */
David Horstmannceeaeb92023-01-05 15:44:23 +0000170 if (len > sizeof(int)) {
171 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
172 }
173 if (len == sizeof(int) && (**p & 0x80) != 0) {
174 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
175 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000176
177 *val = 0;
David Horstmannceeaeb92023-01-05 15:44:23 +0000178 while (len-- > 0) {
179 *val = (*val << 8) | **p;
Paul Bakkerefc30292011-11-10 14:43:23 +0000180 (*p)++;
181 }
182
David Horstmannceeaeb92023-01-05 15:44:23 +0000183 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000184}
185
David Horstmannceeaeb92023-01-05 15:44:23 +0000186int mbedtls_asn1_get_int(unsigned char **p,
187 const unsigned char *end,
188 int *val)
189{
190 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
191}
192
193int mbedtls_asn1_get_enum(unsigned char **p,
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200194 const unsigned char *end,
David Horstmannceeaeb92023-01-05 15:44:23 +0000195 int *val)
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200196{
David Horstmannceeaeb92023-01-05 15:44:23 +0000197 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200198}
199
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200#if defined(MBEDTLS_BIGNUM_C)
David Horstmannceeaeb92023-01-05 15:44:23 +0000201int mbedtls_asn1_get_mpi(unsigned char **p,
202 const unsigned char *end,
203 mbedtls_mpi *X)
Paul Bakkerefc30292011-11-10 14:43:23 +0000204{
Janos Follath24eed8d2019-11-22 13:21:35 +0000205 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000206 size_t len;
207
David Horstmannceeaeb92023-01-05 15:44:23 +0000208 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
209 return ret;
210 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000211
David Horstmannceeaeb92023-01-05 15:44:23 +0000212 ret = mbedtls_mpi_read_binary(X, *p, len);
Paul Bakkerefc30292011-11-10 14:43:23 +0000213
214 *p += len;
215
David Horstmannceeaeb92023-01-05 15:44:23 +0000216 return ret;
Paul Bakkerefc30292011-11-10 14:43:23 +0000217}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200218#endif /* MBEDTLS_BIGNUM_C */
Paul Bakkerefc30292011-11-10 14:43:23 +0000219
David Horstmannceeaeb92023-01-05 15:44:23 +0000220int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
221 mbedtls_asn1_bitstring *bs)
Paul Bakkerefc30292011-11-10 14:43:23 +0000222{
Janos Follath24eed8d2019-11-22 13:21:35 +0000223 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000224
225 /* Certificate type is a single byte bitstring */
David Horstmannceeaeb92023-01-05 15:44:23 +0000226 if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
227 return ret;
228 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000229
230 /* Check length, subtract one for actual bit string length */
David Horstmannceeaeb92023-01-05 15:44:23 +0000231 if (bs->len < 1) {
232 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
233 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000234 bs->len -= 1;
235
236 /* Get number of unused bits, ensure unused bits <= 7 */
237 bs->unused_bits = **p;
David Horstmannceeaeb92023-01-05 15:44:23 +0000238 if (bs->unused_bits > 7) {
239 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
240 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000241 (*p)++;
242
243 /* Get actual bitstring */
244 bs->p = *p;
245 *p += bs->len;
246
David Horstmannceeaeb92023-01-05 15:44:23 +0000247 if (*p != end) {
248 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
249 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000250
David Horstmannceeaeb92023-01-05 15:44:23 +0000251 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000252}
253
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200254/*
Hanno Becker199b7092019-09-11 14:21:26 +0100255 * Traverse an ASN.1 "SEQUENCE OF <tag>"
256 * and call a callback for each entry found.
257 */
258int mbedtls_asn1_traverse_sequence_of(
259 unsigned char **p,
260 const unsigned char *end,
Hanno Becker34aada22020-02-03 10:39:55 +0000261 unsigned char tag_must_mask, unsigned char tag_must_val,
262 unsigned char tag_may_mask, unsigned char tag_may_val,
David Horstmannceeaeb92023-01-05 15:44:23 +0000263 int (*cb)(void *ctx, int tag,
264 unsigned char *start, size_t len),
265 void *ctx)
Hanno Becker199b7092019-09-11 14:21:26 +0100266{
267 int ret;
268 size_t len;
269
270 /* Get main sequence tag */
David Horstmannceeaeb92023-01-05 15:44:23 +0000271 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
272 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
273 return ret;
Hanno Becker199b7092019-09-11 14:21:26 +0100274 }
275
David Horstmannceeaeb92023-01-05 15:44:23 +0000276 if (*p + len != end) {
277 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
278 }
Hanno Becker199b7092019-09-11 14:21:26 +0100279
David Horstmannceeaeb92023-01-05 15:44:23 +0000280 while (*p < end) {
Hanno Becker199b7092019-09-11 14:21:26 +0100281 unsigned char const tag = *(*p)++;
282
David Horstmannceeaeb92023-01-05 15:44:23 +0000283 if ((tag & tag_must_mask) != tag_must_val) {
284 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
285 }
Hanno Becker199b7092019-09-11 14:21:26 +0100286
David Horstmannceeaeb92023-01-05 15:44:23 +0000287 if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
288 return ret;
289 }
Hanno Becker199b7092019-09-11 14:21:26 +0100290
David Horstmannceeaeb92023-01-05 15:44:23 +0000291 if ((tag & tag_may_mask) == tag_may_val) {
292 if (cb != NULL) {
293 ret = cb(ctx, tag, *p, len);
294 if (ret != 0) {
295 return ret;
296 }
Hanno Becker199b7092019-09-11 14:21:26 +0100297 }
298 }
299
300 *p += len;
301 }
302
David Horstmannceeaeb92023-01-05 15:44:23 +0000303 return 0;
Hanno Becker199b7092019-09-11 14:21:26 +0100304}
305
306/*
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200307 * Get a bit string without unused bits
308 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000309int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
310 size_t *len)
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200311{
Janos Follath24eed8d2019-11-22 13:21:35 +0000312 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200313
David Horstmannceeaeb92023-01-05 15:44:23 +0000314 if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
315 return ret;
316 }
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200317
David Horstmannceeaeb92023-01-05 15:44:23 +0000318 if (*len == 0) {
319 return MBEDTLS_ERR_ASN1_INVALID_DATA;
320 }
321 --(*len);
Gilles Peskinee40d1202019-03-01 18:08:35 +0100322
David Horstmannceeaeb92023-01-05 15:44:23 +0000323 if (**p != 0) {
324 return MBEDTLS_ERR_ASN1_INVALID_DATA;
325 }
326 ++(*p);
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200327
David Horstmannceeaeb92023-01-05 15:44:23 +0000328 return 0;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200329}
330
David Horstmannceeaeb92023-01-05 15:44:23 +0000331void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
Hanno Becker12ae27d2019-09-11 14:20:09 +0100332{
David Horstmannceeaeb92023-01-05 15:44:23 +0000333 while (seq != NULL) {
Hanno Becker12ae27d2019-09-11 14:20:09 +0100334 mbedtls_asn1_sequence *next = seq->next;
David Horstmannceeaeb92023-01-05 15:44:23 +0000335 mbedtls_platform_zeroize(seq, sizeof(*seq));
336 mbedtls_free(seq);
Hanno Becker12ae27d2019-09-11 14:20:09 +0100337 seq = next;
338 }
339}
Paul Bakkerefc30292011-11-10 14:43:23 +0000340
David Horstmannceeaeb92023-01-05 15:44:23 +0000341typedef struct {
Hanno Becker1505f632019-09-11 14:25:26 +0100342 int tag;
343 mbedtls_asn1_sequence *cur;
344} asn1_get_sequence_of_cb_ctx_t;
345
David Horstmannceeaeb92023-01-05 15:44:23 +0000346static int asn1_get_sequence_of_cb(void *ctx,
347 int tag,
348 unsigned char *start,
349 size_t len)
Hanno Becker1505f632019-09-11 14:25:26 +0100350{
351 asn1_get_sequence_of_cb_ctx_t *cb_ctx =
352 (asn1_get_sequence_of_cb_ctx_t *) ctx;
353 mbedtls_asn1_sequence *cur =
354 cb_ctx->cur;
355
David Horstmannceeaeb92023-01-05 15:44:23 +0000356 if (cur->buf.p != NULL) {
Hanno Becker1505f632019-09-11 14:25:26 +0100357 cur->next =
David Horstmannceeaeb92023-01-05 15:44:23 +0000358 mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
Hanno Becker1505f632019-09-11 14:25:26 +0100359
David Horstmannceeaeb92023-01-05 15:44:23 +0000360 if (cur->next == NULL) {
361 return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
362 }
Hanno Becker1505f632019-09-11 14:25:26 +0100363
364 cur = cur->next;
365 }
366
367 cur->buf.p = start;
368 cur->buf.len = len;
369 cur->buf.tag = tag;
370
371 cb_ctx->cur = cur;
David Horstmannceeaeb92023-01-05 15:44:23 +0000372 return 0;
Hanno Becker1505f632019-09-11 14:25:26 +0100373}
374
Paul Bakkerefc30292011-11-10 14:43:23 +0000375/*
376 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
377 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000378int mbedtls_asn1_get_sequence_of(unsigned char **p,
379 const unsigned char *end,
380 mbedtls_asn1_sequence *cur,
381 int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +0000382{
Hanno Becker1505f632019-09-11 14:25:26 +0100383 asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
David Horstmannceeaeb92023-01-05 15:44:23 +0000384 memset(cur, 0, sizeof(mbedtls_asn1_sequence));
385 return mbedtls_asn1_traverse_sequence_of(
386 p, end, 0xFF, tag, 0, 0,
387 asn1_get_sequence_of_cb, &cb_ctx);
Paul Bakkerefc30292011-11-10 14:43:23 +0000388}
389
David Horstmannceeaeb92023-01-05 15:44:23 +0000390int mbedtls_asn1_get_alg(unsigned char **p,
391 const unsigned char *end,
392 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200393{
Janos Follath24eed8d2019-11-22 13:21:35 +0000394 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200395 size_t len;
396
David Horstmannceeaeb92023-01-05 15:44:23 +0000397 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
398 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
399 return ret;
400 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200401
David Horstmannceeaeb92023-01-05 15:44:23 +0000402 if ((end - *p) < 1) {
403 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
404 }
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200405
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200406 alg->tag = **p;
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200407 end = *p + len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200408
David Horstmannceeaeb92023-01-05 15:44:23 +0000409 if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
410 return ret;
411 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200412
413 alg->p = *p;
414 *p += alg->len;
415
David Horstmannceeaeb92023-01-05 15:44:23 +0000416 if (*p == end) {
417 mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
418 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200419 }
420
421 params->tag = **p;
422 (*p)++;
423
David Horstmannceeaeb92023-01-05 15:44:23 +0000424 if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0) {
425 return ret;
426 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200427
428 params->p = *p;
429 *p += params->len;
430
David Horstmannceeaeb92023-01-05 15:44:23 +0000431 if (*p != end) {
432 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
433 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200434
David Horstmannceeaeb92023-01-05 15:44:23 +0000435 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200436}
437
David Horstmannceeaeb92023-01-05 15:44:23 +0000438int mbedtls_asn1_get_alg_null(unsigned char **p,
439 const unsigned char *end,
440 mbedtls_asn1_buf *alg)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200441{
Janos Follath24eed8d2019-11-22 13:21:35 +0000442 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443 mbedtls_asn1_buf params;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200444
David Horstmannceeaeb92023-01-05 15:44:23 +0000445 memset(&params, 0, sizeof(mbedtls_asn1_buf));
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200446
David Horstmannceeaeb92023-01-05 15:44:23 +0000447 if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0) {
448 return ret;
449 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200450
David Horstmannceeaeb92023-01-05 15:44:23 +0000451 if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
452 return MBEDTLS_ERR_ASN1_INVALID_DATA;
453 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200454
David Horstmannceeaeb92023-01-05 15:44:23 +0000455 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200456}
457
David Horstmannceeaeb92023-01-05 15:44:23 +0000458void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
Paul Bakkere5eae762013-08-26 12:05:14 +0200459{
David Horstmannceeaeb92023-01-05 15:44:23 +0000460 if (cur == NULL) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200461 return;
David Horstmannceeaeb92023-01-05 15:44:23 +0000462 }
Paul Bakkere5eae762013-08-26 12:05:14 +0200463
David Horstmannceeaeb92023-01-05 15:44:23 +0000464 mbedtls_free(cur->oid.p);
465 mbedtls_free(cur->val.p);
Paul Bakkere5eae762013-08-26 12:05:14 +0200466
David Horstmannceeaeb92023-01-05 15:44:23 +0000467 mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
Paul Bakkere5eae762013-08-26 12:05:14 +0200468}
469
David Horstmannceeaeb92023-01-05 15:44:23 +0000470void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
Paul Bakkerc547cc92013-09-09 12:01:23 +0200471{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472 mbedtls_asn1_named_data *cur;
Paul Bakkerc547cc92013-09-09 12:01:23 +0200473
David Horstmannceeaeb92023-01-05 15:44:23 +0000474 while ((cur = *head) != NULL) {
Paul Bakkerc547cc92013-09-09 12:01:23 +0200475 *head = cur->next;
David Horstmannceeaeb92023-01-05 15:44:23 +0000476 mbedtls_asn1_free_named_data(cur);
477 mbedtls_free(cur);
Paul Bakkerc547cc92013-09-09 12:01:23 +0200478 }
479}
480
David Horstmannceeaeb92023-01-05 15:44:23 +0000481mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(mbedtls_asn1_named_data *list,
482 const char *oid, size_t len)
Paul Bakkere5eae762013-08-26 12:05:14 +0200483{
David Horstmannceeaeb92023-01-05 15:44:23 +0000484 while (list != NULL) {
485 if (list->oid.len == len &&
486 memcmp(list->oid.p, oid, len) == 0) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200487 break;
488 }
489
490 list = list->next;
491 }
492
David Horstmannceeaeb92023-01-05 15:44:23 +0000493 return list;
Paul Bakkere5eae762013-08-26 12:05:14 +0200494}
495
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496#endif /* MBEDTLS_ASN1_PARSE_C */