blob: edc4c698ff20cf612fcfb2d492456338b7f7facb [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 {
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
Gilles Peskine449bd832023-01-11 14:50:10 +010056 *len = (*p)[1];
57 (*p) += 2;
58 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000059
Gilles Peskine449bd832023-01-11 14:50:10 +010060 case 2:
61 if ((end - *p) < 3) {
62 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
63 }
Paul Bakkerefc30292011-11-10 14:43:23 +000064
Gilles Peskine449bd832023-01-11 14:50:10 +010065 *len = ((size_t) (*p)[1] << 8) | (*p)[2];
66 (*p) += 3;
67 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000068
Gilles Peskine449bd832023-01-11 14:50:10 +010069 case 3:
70 if ((end - *p) < 4) {
71 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
72 }
Paul Bakkerefc30292011-11-10 14:43:23 +000073
Gilles Peskine449bd832023-01-11 14:50:10 +010074 *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
Gilles Peskine449bd832023-01-11 14:50:10 +010079 case 4:
80 if ((end - *p) < 5) {
81 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
82 }
Paul Bakkerefc30292011-11-10 14:43:23 +000083
Gilles Peskine449bd832023-01-11 14:50:10 +010084 *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
Gilles Peskine449bd832023-01-11 14:50:10 +010089 default:
90 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
Paul Bakkerefc30292011-11-10 14:43:23 +000091 }
92 }
93
Gilles Peskine449bd832023-01-11 14:50:10 +010094 if (*len > (size_t) (end - *p)) {
95 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
96 }
Paul Bakkerefc30292011-11-10 14:43:23 +000097
Gilles Peskine449bd832023-01-11 14:50:10 +010098 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +000099}
100
Gilles Peskine449bd832023-01-11 14:50:10 +0100101int 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{
Gilles Peskine449bd832023-01-11 14:50:10 +0100105 if ((end - *p) < 1) {
106 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
107 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000108
Gilles Peskine449bd832023-01-11 14:50:10 +0100109 if (**p != tag) {
110 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
111 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000112
113 (*p)++;
114
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 return mbedtls_asn1_get_len(p, end, len);
Paul Bakkerefc30292011-11-10 14:43:23 +0000116}
Agathiyan Bragadeeshfca08612023-09-04 15:45:37 +0100117#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */
Paul Bakkerefc30292011-11-10 14:43:23 +0000118
Agathiyan Bragadeeshfca08612023-09-04 15:45:37 +0100119#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100120int mbedtls_asn1_get_bool(unsigned char **p,
121 const unsigned char *end,
122 int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +0000123{
Janos Follath24eed8d2019-11-22 13:21:35 +0000124 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000125 size_t len;
126
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
128 return ret;
129 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000130
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 if (len != 1) {
132 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
133 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000134
Gilles Peskine449bd832023-01-11 14:50:10 +0100135 *val = (**p != 0) ? 1 : 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000136 (*p)++;
137
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000139}
140
Gilles Peskine449bd832023-01-11 14:50:10 +0100141static int asn1_get_tagged_int(unsigned char **p,
142 const unsigned char *end,
143 int tag, int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +0000144{
Janos Follath24eed8d2019-11-22 13:21:35 +0000145 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000146 size_t len;
147
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
149 return ret;
150 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000151
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200152 /*
153 * len==0 is malformed (0 must be represented as 020100 for INTEGER,
154 * or 0A0100 for ENUMERATED tags
155 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100156 if (len == 0) {
157 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
158 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200159 /* This is a cryptography library. Reject negative integers. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100160 if ((**p & 0x80) != 0) {
161 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
162 }
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100163
Gilles Peskine9fd97942019-10-10 19:27:53 +0200164 /* Skip leading zeros. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100165 while (len > 0 && **p == 0) {
166 ++(*p);
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100167 --len;
168 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200169
170 /* Reject integers that don't fit in an int. This code assumes that
171 * the int type has no padding bit. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100172 if (len > sizeof(int)) {
173 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
174 }
175 if (len == sizeof(int) && (**p & 0x80) != 0) {
176 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
177 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000178
179 *val = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100180 while (len-- > 0) {
181 *val = (*val << 8) | **p;
Paul Bakkerefc30292011-11-10 14:43:23 +0000182 (*p)++;
183 }
184
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000186}
187
Gilles Peskine449bd832023-01-11 14:50:10 +0100188int mbedtls_asn1_get_int(unsigned char **p,
189 const unsigned char *end,
190 int *val)
191{
192 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
193}
194
195int mbedtls_asn1_get_enum(unsigned char **p,
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200196 const unsigned char *end,
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 int *val)
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200198{
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200200}
201
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200202#if defined(MBEDTLS_BIGNUM_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100203int mbedtls_asn1_get_mpi(unsigned char **p,
204 const unsigned char *end,
205 mbedtls_mpi *X)
Paul Bakkerefc30292011-11-10 14:43:23 +0000206{
Janos Follath24eed8d2019-11-22 13:21:35 +0000207 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000208 size_t len;
209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
211 return ret;
212 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000213
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 ret = mbedtls_mpi_read_binary(X, *p, len);
Paul Bakkerefc30292011-11-10 14:43:23 +0000215
216 *p += len;
217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 return ret;
Paul Bakkerefc30292011-11-10 14:43:23 +0000219}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200220#endif /* MBEDTLS_BIGNUM_C */
Paul Bakkerefc30292011-11-10 14:43:23 +0000221
Gilles Peskine449bd832023-01-11 14:50:10 +0100222int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
223 mbedtls_asn1_bitstring *bs)
Paul Bakkerefc30292011-11-10 14:43:23 +0000224{
Janos Follath24eed8d2019-11-22 13:21:35 +0000225 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000226
227 /* Certificate type is a single byte bitstring */
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
229 return ret;
230 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000231
232 /* Check length, subtract one for actual bit string length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 if (bs->len < 1) {
234 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
235 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000236 bs->len -= 1;
237
238 /* Get number of unused bits, ensure unused bits <= 7 */
239 bs->unused_bits = **p;
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 if (bs->unused_bits > 7) {
241 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
242 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000243 (*p)++;
244
245 /* Get actual bitstring */
246 bs->p = *p;
247 *p += bs->len;
248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 if (*p != end) {
250 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
251 }
Paul Bakkerefc30292011-11-10 14:43:23 +0000252
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000254}
255
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200256/*
Hanno Becker199b7092019-09-11 14:21:26 +0100257 * Traverse an ASN.1 "SEQUENCE OF <tag>"
258 * and call a callback for each entry found.
259 */
260int mbedtls_asn1_traverse_sequence_of(
261 unsigned char **p,
262 const unsigned char *end,
Hanno Becker34aada22020-02-03 10:39:55 +0000263 unsigned char tag_must_mask, unsigned char tag_must_val,
264 unsigned char tag_may_mask, unsigned char tag_may_val,
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 int (*cb)(void *ctx, int tag,
266 unsigned char *start, size_t len),
267 void *ctx)
Hanno Becker199b7092019-09-11 14:21:26 +0100268{
269 int ret;
270 size_t len;
271
272 /* Get main sequence tag */
Gilles Peskine449bd832023-01-11 14:50:10 +0100273 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
274 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
275 return ret;
Hanno Becker199b7092019-09-11 14:21:26 +0100276 }
277
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 if (*p + len != end) {
279 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
280 }
Hanno Becker199b7092019-09-11 14:21:26 +0100281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282 while (*p < end) {
Hanno Becker199b7092019-09-11 14:21:26 +0100283 unsigned char const tag = *(*p)++;
284
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 if ((tag & tag_must_mask) != tag_must_val) {
286 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
287 }
Hanno Becker199b7092019-09-11 14:21:26 +0100288
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
290 return ret;
291 }
Hanno Becker199b7092019-09-11 14:21:26 +0100292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 if ((tag & tag_may_mask) == tag_may_val) {
294 if (cb != NULL) {
295 ret = cb(ctx, tag, *p, len);
296 if (ret != 0) {
297 return ret;
298 }
Hanno Becker199b7092019-09-11 14:21:26 +0100299 }
300 }
301
302 *p += len;
303 }
304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 return 0;
Hanno Becker199b7092019-09-11 14:21:26 +0100306}
307
308/*
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200309 * Get a bit string without unused bits
310 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100311int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
312 size_t *len)
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200313{
Janos Follath24eed8d2019-11-22 13:21:35 +0000314 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200315
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
317 return ret;
318 }
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200319
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 if (*len == 0) {
321 return MBEDTLS_ERR_ASN1_INVALID_DATA;
322 }
323 --(*len);
Gilles Peskinee40d1202019-03-01 18:08:35 +0100324
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 if (**p != 0) {
326 return MBEDTLS_ERR_ASN1_INVALID_DATA;
327 }
328 ++(*p);
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200329
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 return 0;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200331}
332
Gilles Peskine449bd832023-01-11 14:50:10 +0100333void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
Hanno Becker12ae27d2019-09-11 14:20:09 +0100334{
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 while (seq != NULL) {
Hanno Becker12ae27d2019-09-11 14:20:09 +0100336 mbedtls_asn1_sequence *next = seq->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 mbedtls_free(seq);
Hanno Becker12ae27d2019-09-11 14:20:09 +0100338 seq = next;
339 }
340}
Paul Bakkerefc30292011-11-10 14:43:23 +0000341
Gilles Peskine449bd832023-01-11 14:50:10 +0100342typedef struct {
Hanno Becker1505f632019-09-11 14:25:26 +0100343 int tag;
344 mbedtls_asn1_sequence *cur;
345} asn1_get_sequence_of_cb_ctx_t;
346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347static int asn1_get_sequence_of_cb(void *ctx,
348 int tag,
349 unsigned char *start,
350 size_t len)
Hanno Becker1505f632019-09-11 14:25:26 +0100351{
352 asn1_get_sequence_of_cb_ctx_t *cb_ctx =
353 (asn1_get_sequence_of_cb_ctx_t *) ctx;
354 mbedtls_asn1_sequence *cur =
355 cb_ctx->cur;
356
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 if (cur->buf.p != NULL) {
Hanno Becker1505f632019-09-11 14:25:26 +0100358 cur->next =
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
Hanno Becker1505f632019-09-11 14:25:26 +0100360
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 if (cur->next == NULL) {
362 return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
363 }
Hanno Becker1505f632019-09-11 14:25:26 +0100364
365 cur = cur->next;
366 }
367
368 cur->buf.p = start;
369 cur->buf.len = len;
370 cur->buf.tag = tag;
371
372 cb_ctx->cur = cur;
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 return 0;
Hanno Becker1505f632019-09-11 14:25:26 +0100374}
375
Paul Bakkerefc30292011-11-10 14:43:23 +0000376/*
377 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
378 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100379int mbedtls_asn1_get_sequence_of(unsigned char **p,
380 const unsigned char *end,
381 mbedtls_asn1_sequence *cur,
382 int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +0000383{
Hanno Becker1505f632019-09-11 14:25:26 +0100384 asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 memset(cur, 0, sizeof(mbedtls_asn1_sequence));
386 return mbedtls_asn1_traverse_sequence_of(
387 p, end, 0xFF, tag, 0, 0,
388 asn1_get_sequence_of_cb, &cb_ctx);
Paul Bakkerefc30292011-11-10 14:43:23 +0000389}
390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391int mbedtls_asn1_get_alg(unsigned char **p,
392 const unsigned char *end,
393 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200394{
Janos Follath24eed8d2019-11-22 13:21:35 +0000395 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200396 size_t len;
397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
399 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
400 return ret;
401 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 if ((end - *p) < 1) {
404 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
405 }
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200406
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200407 alg->tag = **p;
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200408 end = *p + len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200409
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
411 return ret;
412 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200413
414 alg->p = *p;
415 *p += alg->len;
416
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 if (*p == end) {
418 mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
419 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200420 }
421
422 params->tag = **p;
423 (*p)++;
424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0) {
426 return ret;
427 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200428
429 params->p = *p;
430 *p += params->len;
431
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 if (*p != end) {
433 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
434 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200435
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200437}
438
Gilles Peskine449bd832023-01-11 14:50:10 +0100439int mbedtls_asn1_get_alg_null(unsigned char **p,
440 const unsigned char *end,
441 mbedtls_asn1_buf *alg)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200442{
Janos Follath24eed8d2019-11-22 13:21:35 +0000443 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 mbedtls_asn1_buf params;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200445
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 memset(&params, 0, sizeof(mbedtls_asn1_buf));
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200447
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0) {
449 return ret;
450 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200451
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
453 return MBEDTLS_ERR_ASN1_INVALID_DATA;
454 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200457}
458
Glenn Strauss82ba2742022-11-04 04:01:23 -0400459#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100460void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
Paul Bakkere5eae762013-08-26 12:05:14 +0200461{
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 if (cur == NULL) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200463 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 }
Paul Bakkere5eae762013-08-26 12:05:14 +0200465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 mbedtls_free(cur->oid.p);
467 mbedtls_free(cur->val.p);
Paul Bakkere5eae762013-08-26 12:05:14 +0200468
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
Paul Bakkere5eae762013-08-26 12:05:14 +0200470}
Glenn Strauss82ba2742022-11-04 04:01:23 -0400471#endif /* MBEDTLS_DEPRECATED_REMOVED */
Paul Bakkere5eae762013-08-26 12:05:14 +0200472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
Paul Bakkerc547cc92013-09-09 12:01:23 +0200474{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475 mbedtls_asn1_named_data *cur;
Paul Bakkerc547cc92013-09-09 12:01:23 +0200476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 while ((cur = *head) != NULL) {
Paul Bakkerc547cc92013-09-09 12:01:23 +0200478 *head = cur->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 mbedtls_free(cur->oid.p);
480 mbedtls_free(cur->val.p);
481 mbedtls_free(cur);
Paul Bakkerc547cc92013-09-09 12:01:23 +0200482 }
483}
484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name)
Glenn Straussa4b40412022-06-26 19:32:09 -0400486{
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 for (mbedtls_asn1_named_data *next; name != NULL; name = next) {
Glenn Straussa4b40412022-06-26 19:32:09 -0400488 next = name->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 mbedtls_free(name);
Glenn Straussa4b40412022-06-26 19:32:09 -0400490 }
491}
492
Gilles Peskine449bd832023-01-11 14:50:10 +0100493const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list,
494 const char *oid, size_t len)
Paul Bakkere5eae762013-08-26 12:05:14 +0200495{
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 while (list != NULL) {
497 if (list->oid.len == len &&
498 memcmp(list->oid.p, oid, len) == 0) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200499 break;
500 }
501
502 list = list->next;
503 }
504
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 return list;
Paul Bakkere5eae762013-08-26 12:05:14 +0200506}
507
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508#endif /* MBEDTLS_ASN1_PARSE_C */