blob: 4a6132e6721a7637820f13fe0260d3dbc520c21e [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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020024# include "mbedtls/asn1.h"
25# include "mbedtls/platform_util.h"
26# include "mbedtls/error.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000027
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020028# include <string.h>
Rich Evans00ab4702015-02-06 13:43:58 +000029
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020030# if defined(MBEDTLS_BIGNUM_C)
31# include "mbedtls/bignum.h"
32# endif
Paul Bakkerefc30292011-11-10 14:43:23 +000033
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020034# if defined(MBEDTLS_PLATFORM_C)
35# include "mbedtls/platform.h"
36# else
37# include <stdlib.h>
38# define mbedtls_calloc calloc
39# define mbedtls_free free
40# endif
Paul Bakker6e339b52013-07-03 13:37:05 +020041
Paul Bakkerefc30292011-11-10 14:43:23 +000042/*
43 * ASN.1 DER decoding routines
44 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020045int mbedtls_asn1_get_len(unsigned char **p,
46 const unsigned char *end,
47 size_t *len)
Paul Bakkerefc30292011-11-10 14:43:23 +000048{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020049 if ((end - *p) < 1)
50 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
Paul Bakkerefc30292011-11-10 14:43:23 +000051
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020052 if ((**p & 0x80) == 0)
Paul Bakkerefc30292011-11-10 14:43:23 +000053 *len = *(*p)++;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020054 else {
55 switch (**p & 0x7F) {
56 case 1:
57 if ((end - *p) < 2)
58 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
Paul Bakkerefc30292011-11-10 14:43:23 +000059
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020060 *len = (*p)[1];
61 (*p) += 2;
62 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000063
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020064 case 2:
65 if ((end - *p) < 3)
66 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
Paul Bakkerefc30292011-11-10 14:43:23 +000067
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020068 *len = ((size_t)(*p)[1] << 8) | (*p)[2];
69 (*p) += 3;
70 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000071
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020072 case 3:
73 if ((end - *p) < 4)
74 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
Paul Bakkerefc30292011-11-10 14:43:23 +000075
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020076 *len = ((size_t)(*p)[1] << 16) | ((size_t)(*p)[2] << 8) |
77 (*p)[3];
78 (*p) += 4;
79 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000080
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020081 case 4:
82 if ((end - *p) < 5)
83 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
Paul Bakkerefc30292011-11-10 14:43:23 +000084
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020085 *len = ((size_t)(*p)[1] << 24) | ((size_t)(*p)[2] << 16) |
86 ((size_t)(*p)[3] << 8) | (*p)[4];
87 (*p) += 5;
88 break;
Paul Bakkerefc30292011-11-10 14:43:23 +000089
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020090 default:
91 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
Paul Bakkerefc30292011-11-10 14:43:23 +000092 }
93 }
94
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020095 if (*len > (size_t)(end - *p))
96 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
Paul Bakkerefc30292011-11-10 14:43:23 +000097
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020098 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +000099}
100
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200101int mbedtls_asn1_get_tag(unsigned char **p,
102 const unsigned char *end,
103 size_t *len,
104 int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +0000105{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200106 if ((end - *p) < 1)
107 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
Paul Bakkerefc30292011-11-10 14:43:23 +0000108
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200109 if (**p != tag)
110 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
Paul Bakkerefc30292011-11-10 14:43:23 +0000111
112 (*p)++;
113
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200114 return mbedtls_asn1_get_len(p, end, len);
Paul Bakkerefc30292011-11-10 14:43:23 +0000115}
116
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200117int mbedtls_asn1_get_bool(unsigned char **p, const unsigned char *end, int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +0000118{
Janos Follath24eed8d2019-11-22 13:21:35 +0000119 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000120 size_t len;
121
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200122 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0)
123 return ret;
Paul Bakkerefc30292011-11-10 14:43:23 +0000124
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200125 if (len != 1)
126 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
Paul Bakkerefc30292011-11-10 14:43:23 +0000127
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200128 *val = (**p != 0) ? 1 : 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000129 (*p)++;
130
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200131 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000132}
133
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200134static int asn1_get_tagged_int(unsigned char **p,
135 const unsigned char *end,
136 int tag,
137 int *val)
Paul Bakkerefc30292011-11-10 14:43:23 +0000138{
Janos Follath24eed8d2019-11-22 13:21:35 +0000139 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000140 size_t len;
141
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200142 if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0)
143 return ret;
Paul Bakkerefc30292011-11-10 14:43:23 +0000144
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200145 /*
146 * len==0 is malformed (0 must be represented as 020100 for INTEGER,
147 * or 0A0100 for ENUMERATED tags
148 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200149 if (len == 0)
150 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
Gilles Peskine9fd97942019-10-10 19:27:53 +0200151 /* This is a cryptography library. Reject negative integers. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200152 if ((**p & 0x80) != 0)
153 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100154
Gilles Peskine9fd97942019-10-10 19:27:53 +0200155 /* Skip leading zeros. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200156 while (len > 0 && **p == 0) {
157 ++(*p);
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100158 --len;
159 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200160
161 /* Reject integers that don't fit in an int. This code assumes that
162 * the int type has no padding bit. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200163 if (len > sizeof(int))
164 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
165 if (len == sizeof(int) && (**p & 0x80) != 0)
166 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
Paul Bakkerefc30292011-11-10 14:43:23 +0000167
168 *val = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200169 while (len-- > 0) {
170 *val = (*val << 8) | **p;
Paul Bakkerefc30292011-11-10 14:43:23 +0000171 (*p)++;
172 }
173
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200174 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000175}
176
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200177int mbedtls_asn1_get_int(unsigned char **p, const unsigned char *end, int *val)
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200178{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200179 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200180}
181
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200182int mbedtls_asn1_get_enum(unsigned char **p, const unsigned char *end, int *val)
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200183{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200184 return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200185}
186
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200187# if defined(MBEDTLS_BIGNUM_C)
188int mbedtls_asn1_get_mpi(unsigned char **p,
189 const unsigned char *end,
190 mbedtls_mpi *X)
Paul Bakkerefc30292011-11-10 14:43:23 +0000191{
Janos Follath24eed8d2019-11-22 13:21:35 +0000192 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000193 size_t len;
194
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200195 if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0)
196 return ret;
Paul Bakkerefc30292011-11-10 14:43:23 +0000197
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200198 ret = mbedtls_mpi_read_binary(X, *p, len);
Paul Bakkerefc30292011-11-10 14:43:23 +0000199
200 *p += len;
201
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200202 return ret;
Paul Bakkerefc30292011-11-10 14:43:23 +0000203}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200204# endif /* MBEDTLS_BIGNUM_C */
Paul Bakkerefc30292011-11-10 14:43:23 +0000205
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200206int mbedtls_asn1_get_bitstring(unsigned char **p,
207 const unsigned char *end,
208 mbedtls_asn1_bitstring *bs)
Paul Bakkerefc30292011-11-10 14:43:23 +0000209{
Janos Follath24eed8d2019-11-22 13:21:35 +0000210 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000211
212 /* Certificate type is a single byte bitstring */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200213 if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len,
214 MBEDTLS_ASN1_BIT_STRING)) != 0)
215 return ret;
Paul Bakkerefc30292011-11-10 14:43:23 +0000216
217 /* Check length, subtract one for actual bit string length */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200218 if (bs->len < 1)
219 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
Paul Bakkerefc30292011-11-10 14:43:23 +0000220 bs->len -= 1;
221
222 /* Get number of unused bits, ensure unused bits <= 7 */
223 bs->unused_bits = **p;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200224 if (bs->unused_bits > 7)
225 return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
Paul Bakkerefc30292011-11-10 14:43:23 +0000226 (*p)++;
227
228 /* Get actual bitstring */
229 bs->p = *p;
230 *p += bs->len;
231
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200232 if (*p != end)
233 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
Paul Bakkerefc30292011-11-10 14:43:23 +0000234
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200235 return 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000236}
237
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200238/*
Hanno Becker199b7092019-09-11 14:21:26 +0100239 * Traverse an ASN.1 "SEQUENCE OF <tag>"
240 * and call a callback for each entry found.
241 */
242int mbedtls_asn1_traverse_sequence_of(
243 unsigned char **p,
244 const unsigned char *end,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200245 unsigned char tag_must_mask,
246 unsigned char tag_must_val,
247 unsigned char tag_may_mask,
248 unsigned char tag_may_val,
249 int (*cb)(void *ctx, int tag, unsigned char *start, size_t len),
250 void *ctx)
Hanno Becker199b7092019-09-11 14:21:26 +0100251{
252 int ret;
253 size_t len;
254
255 /* Get main sequence tag */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200256 if ((ret = mbedtls_asn1_get_tag(
257 p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) !=
258 0) {
259 return ret;
Hanno Becker199b7092019-09-11 14:21:26 +0100260 }
261
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200262 if (*p + len != end)
263 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
Hanno Becker199b7092019-09-11 14:21:26 +0100264
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200265 while (*p < end) {
Hanno Becker199b7092019-09-11 14:21:26 +0100266 unsigned char const tag = *(*p)++;
267
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200268 if ((tag & tag_must_mask) != tag_must_val)
269 return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
Hanno Becker199b7092019-09-11 14:21:26 +0100270
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200271 if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0)
272 return ret;
Hanno Becker199b7092019-09-11 14:21:26 +0100273
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200274 if ((tag & tag_may_mask) == tag_may_val) {
275 if (cb != NULL) {
276 ret = cb(ctx, tag, *p, len);
277 if (ret != 0)
278 return ret;
Hanno Becker199b7092019-09-11 14:21:26 +0100279 }
280 }
281
282 *p += len;
283 }
284
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200285 return 0;
Hanno Becker199b7092019-09-11 14:21:26 +0100286}
287
288/*
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200289 * Get a bit string without unused bits
290 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200291int mbedtls_asn1_get_bitstring_null(unsigned char **p,
292 const unsigned char *end,
293 size_t *len)
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200294{
Janos Follath24eed8d2019-11-22 13:21:35 +0000295 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200296
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200297 if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0)
298 return ret;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200299
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200300 if (*len == 0)
301 return MBEDTLS_ERR_ASN1_INVALID_DATA;
302 --(*len);
Gilles Peskinee40d1202019-03-01 18:08:35 +0100303
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200304 if (**p != 0)
305 return MBEDTLS_ERR_ASN1_INVALID_DATA;
306 ++(*p);
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200307
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200308 return 0;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200309}
310
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200311void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
Hanno Becker12ae27d2019-09-11 14:20:09 +0100312{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200313 while (seq != NULL) {
Hanno Becker12ae27d2019-09-11 14:20:09 +0100314 mbedtls_asn1_sequence *next = seq->next;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200315 mbedtls_platform_zeroize(seq, sizeof(*seq));
316 mbedtls_free(seq);
Hanno Becker12ae27d2019-09-11 14:20:09 +0100317 seq = next;
318 }
319}
Paul Bakkerefc30292011-11-10 14:43:23 +0000320
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200321typedef struct {
Hanno Becker1505f632019-09-11 14:25:26 +0100322 int tag;
323 mbedtls_asn1_sequence *cur;
324} asn1_get_sequence_of_cb_ctx_t;
325
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200326static int
327asn1_get_sequence_of_cb(void *ctx, int tag, unsigned char *start, size_t len)
Hanno Becker1505f632019-09-11 14:25:26 +0100328{
329 asn1_get_sequence_of_cb_ctx_t *cb_ctx =
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200330 (asn1_get_sequence_of_cb_ctx_t *)ctx;
331 mbedtls_asn1_sequence *cur = cb_ctx->cur;
Hanno Becker1505f632019-09-11 14:25:26 +0100332
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200333 if (cur->buf.p != NULL) {
334 cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
Hanno Becker1505f632019-09-11 14:25:26 +0100335
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200336 if (cur->next == NULL)
337 return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
Hanno Becker1505f632019-09-11 14:25:26 +0100338
339 cur = cur->next;
340 }
341
342 cur->buf.p = start;
343 cur->buf.len = len;
344 cur->buf.tag = tag;
345
346 cb_ctx->cur = cur;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200347 return 0;
Hanno Becker1505f632019-09-11 14:25:26 +0100348}
349
Paul Bakkerefc30292011-11-10 14:43:23 +0000350/*
351 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
352 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200353int mbedtls_asn1_get_sequence_of(unsigned char **p,
354 const unsigned char *end,
355 mbedtls_asn1_sequence *cur,
356 int tag)
Paul Bakkerefc30292011-11-10 14:43:23 +0000357{
Hanno Becker1505f632019-09-11 14:25:26 +0100358 asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200359 memset(cur, 0, sizeof(mbedtls_asn1_sequence));
360 return (mbedtls_asn1_traverse_sequence_of(
361 p, end, 0xFF, tag, 0, 0, asn1_get_sequence_of_cb, &cb_ctx));
Paul Bakkerefc30292011-11-10 14:43:23 +0000362}
363
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200364int mbedtls_asn1_get_alg(unsigned char **p,
365 const unsigned char *end,
366 mbedtls_asn1_buf *alg,
367 mbedtls_asn1_buf *params)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200368{
Janos Follath24eed8d2019-11-22 13:21:35 +0000369 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200370 size_t len;
371
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200372 if ((ret = mbedtls_asn1_get_tag(
373 p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) !=
374 0)
375 return ret;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200376
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200377 if ((end - *p) < 1)
378 return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200379
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200380 alg->tag = **p;
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200381 end = *p + len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200382
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200383 if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0)
384 return ret;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200385
386 alg->p = *p;
387 *p += alg->len;
388
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200389 if (*p == end) {
390 mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
391 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200392 }
393
394 params->tag = **p;
395 (*p)++;
396
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200397 if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0)
398 return ret;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200399
400 params->p = *p;
401 *p += params->len;
402
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200403 if (*p != end)
404 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200405
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200406 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200407}
408
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200409int mbedtls_asn1_get_alg_null(unsigned char **p,
410 const unsigned char *end,
411 mbedtls_asn1_buf *alg)
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200412{
Janos Follath24eed8d2019-11-22 13:21:35 +0000413 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414 mbedtls_asn1_buf params;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200415
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200416 memset(&params, 0, sizeof(mbedtls_asn1_buf));
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200417
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200418 if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0)
419 return ret;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200420
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200421 if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0)
422 return MBEDTLS_ERR_ASN1_INVALID_DATA;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200423
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200424 return 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200425}
426
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200427void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
Paul Bakkere5eae762013-08-26 12:05:14 +0200428{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200429 if (cur == NULL)
Paul Bakkere5eae762013-08-26 12:05:14 +0200430 return;
431
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200432 mbedtls_free(cur->oid.p);
433 mbedtls_free(cur->val.p);
Paul Bakkere5eae762013-08-26 12:05:14 +0200434
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200435 mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
Paul Bakkere5eae762013-08-26 12:05:14 +0200436}
437
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200438void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
Paul Bakkerc547cc92013-09-09 12:01:23 +0200439{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 mbedtls_asn1_named_data *cur;
Paul Bakkerc547cc92013-09-09 12:01:23 +0200441
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200442 while ((cur = *head) != NULL) {
Paul Bakkerc547cc92013-09-09 12:01:23 +0200443 *head = cur->next;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200444 mbedtls_asn1_free_named_data(cur);
445 mbedtls_free(cur);
Paul Bakkerc547cc92013-09-09 12:01:23 +0200446 }
447}
448
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200449const mbedtls_asn1_named_data *
450mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list,
451 const char *oid,
452 size_t len)
Paul Bakkere5eae762013-08-26 12:05:14 +0200453{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200454 while (list != NULL) {
455 if (list->oid.len == len && memcmp(list->oid.p, oid, len) == 0) {
Paul Bakkere5eae762013-08-26 12:05:14 +0200456 break;
457 }
458
459 list = list->next;
460 }
461
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200462 return list;
Paul Bakkere5eae762013-08-26 12:05:14 +0200463}
464
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465#endif /* MBEDTLS_ASN1_PARSE_C */