Line data Source code
1 : /*
2 : * Generic ASN.1 parsing
3 : *
4 : * Copyright The Mbed TLS Contributors
5 : * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 : */
7 :
8 : #include "common.h"
9 :
10 : #if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
11 : defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
12 :
13 : #include "mbedtls/asn1.h"
14 : #include "mbedtls/platform_util.h"
15 : #include "mbedtls/error.h"
16 :
17 : #include <string.h>
18 :
19 : #if defined(MBEDTLS_BIGNUM_C)
20 : #include "mbedtls/bignum.h"
21 : #endif
22 :
23 : #include "mbedtls/platform.h"
24 :
25 : /*
26 : * ASN.1 DER decoding routines
27 : */
28 777366 : int mbedtls_asn1_get_len(unsigned char **p,
29 : const unsigned char *end,
30 : size_t *len)
31 : {
32 777366 : if ((end - *p) < 1) {
33 0 : return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
34 : }
35 :
36 777366 : if ((**p & 0x80) == 0) {
37 716041 : *len = *(*p)++;
38 : } else {
39 61325 : int n = (**p) & 0x7F;
40 61325 : if (n == 0 || n > 4) {
41 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
42 : }
43 61325 : if ((end - *p) <= n) {
44 0 : return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
45 : }
46 61325 : *len = 0;
47 61325 : (*p)++;
48 164028 : while (n--) {
49 102703 : *len = (*len << 8) | **p;
50 102703 : (*p)++;
51 : }
52 : }
53 :
54 777366 : if (*len > (size_t) (end - *p)) {
55 0 : return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
56 : }
57 :
58 777366 : return 0;
59 : }
60 :
61 730717 : int mbedtls_asn1_get_tag(unsigned char **p,
62 : const unsigned char *end,
63 : size_t *len, int tag)
64 : {
65 730717 : if ((end - *p) < 1) {
66 1778 : return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
67 : }
68 :
69 728939 : if (**p != tag) {
70 71358 : return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
71 : }
72 :
73 657581 : (*p)++;
74 :
75 657581 : return mbedtls_asn1_get_len(p, end, len);
76 : }
77 : #endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
78 :
79 : #if defined(MBEDTLS_ASN1_PARSE_C)
80 70465 : int mbedtls_asn1_get_bool(unsigned char **p,
81 : const unsigned char *end,
82 : int *val)
83 : {
84 70465 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
85 : size_t len;
86 :
87 70465 : if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
88 44811 : return ret;
89 : }
90 :
91 25654 : if (len != 1) {
92 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
93 : }
94 :
95 25654 : *val = (**p != 0) ? 1 : 0;
96 25654 : (*p)++;
97 :
98 25654 : return 0;
99 : }
100 :
101 13172 : static int asn1_get_tagged_int(unsigned char **p,
102 : const unsigned char *end,
103 : int tag, int *val)
104 : {
105 13172 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
106 : size_t len;
107 :
108 13172 : if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
109 0 : return ret;
110 : }
111 :
112 : /*
113 : * len==0 is malformed (0 must be represented as 020100 for INTEGER,
114 : * or 0A0100 for ENUMERATED tags
115 : */
116 13172 : if (len == 0) {
117 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
118 : }
119 : /* This is a cryptography library. Reject negative integers. */
120 13172 : if ((**p & 0x80) != 0) {
121 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
122 : }
123 :
124 : /* Skip leading zeros. */
125 13389 : while (len > 0 && **p == 0) {
126 217 : ++(*p);
127 217 : --len;
128 : }
129 :
130 : /* Reject integers that don't fit in an int. This code assumes that
131 : * the int type has no padding bit. */
132 13172 : if (len > sizeof(int)) {
133 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
134 : }
135 13172 : if (len == sizeof(int) && (**p & 0x80) != 0) {
136 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
137 : }
138 :
139 13172 : *val = 0;
140 26127 : while (len-- > 0) {
141 12955 : *val = (*val << 8) | **p;
142 12955 : (*p)++;
143 : }
144 :
145 13172 : return 0;
146 : }
147 :
148 13172 : int mbedtls_asn1_get_int(unsigned char **p,
149 : const unsigned char *end,
150 : int *val)
151 : {
152 13172 : return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
153 : }
154 :
155 0 : int mbedtls_asn1_get_enum(unsigned char **p,
156 : const unsigned char *end,
157 : int *val)
158 : {
159 0 : return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
160 : }
161 :
162 : #if defined(MBEDTLS_BIGNUM_C)
163 3070 : int mbedtls_asn1_get_mpi(unsigned char **p,
164 : const unsigned char *end,
165 : mbedtls_mpi *X)
166 : {
167 3070 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
168 : size_t len;
169 :
170 3070 : if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
171 0 : return ret;
172 : }
173 :
174 3070 : ret = mbedtls_mpi_read_binary(X, *p, len);
175 :
176 3070 : *p += len;
177 :
178 3070 : return ret;
179 : }
180 : #endif /* MBEDTLS_BIGNUM_C */
181 :
182 10540 : int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
183 : mbedtls_asn1_bitstring *bs)
184 : {
185 10540 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
186 :
187 : /* Certificate type is a single byte bitstring */
188 10540 : if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
189 0 : return ret;
190 : }
191 :
192 : /* Check length, subtract one for actual bit string length */
193 10540 : if (bs->len < 1) {
194 0 : return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
195 : }
196 10540 : bs->len -= 1;
197 :
198 : /* Get number of unused bits, ensure unused bits <= 7 */
199 10540 : bs->unused_bits = **p;
200 10540 : if (bs->unused_bits > 7) {
201 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
202 : }
203 10540 : (*p)++;
204 :
205 : /* Get actual bitstring */
206 10540 : bs->p = *p;
207 10540 : *p += bs->len;
208 :
209 10540 : if (*p != end) {
210 0 : return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
211 : }
212 :
213 10540 : return 0;
214 : }
215 :
216 : /*
217 : * Traverse an ASN.1 "SEQUENCE OF <tag>"
218 : * and call a callback for each entry found.
219 : */
220 10546 : int mbedtls_asn1_traverse_sequence_of(
221 : unsigned char **p,
222 : const unsigned char *end,
223 : unsigned char tag_must_mask, unsigned char tag_must_val,
224 : unsigned char tag_may_mask, unsigned char tag_may_val,
225 : int (*cb)(void *ctx, int tag,
226 : unsigned char *start, size_t len),
227 : void *ctx)
228 : {
229 : int ret;
230 : size_t len;
231 :
232 : /* Get main sequence tag */
233 10546 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
234 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
235 0 : return ret;
236 : }
237 :
238 10546 : if (*p + len != end) {
239 0 : return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
240 : }
241 :
242 40382 : while (*p < end) {
243 29836 : unsigned char const tag = *(*p)++;
244 :
245 29836 : if ((tag & tag_must_mask) != tag_must_val) {
246 0 : return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
247 : }
248 :
249 29836 : if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
250 0 : return ret;
251 : }
252 :
253 29836 : if ((tag & tag_may_mask) == tag_may_val) {
254 29836 : if (cb != NULL) {
255 29836 : ret = cb(ctx, tag, *p, len);
256 29836 : if (ret != 0) {
257 0 : return ret;
258 : }
259 : }
260 : }
261 :
262 29836 : *p += len;
263 : }
264 :
265 10546 : return 0;
266 : }
267 :
268 : /*
269 : * Get a bit string without unused bits
270 : */
271 25775 : int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
272 : size_t *len)
273 : {
274 25775 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
275 :
276 25775 : if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
277 0 : return ret;
278 : }
279 :
280 25775 : if (*len == 0) {
281 0 : return MBEDTLS_ERR_ASN1_INVALID_DATA;
282 : }
283 25775 : --(*len);
284 :
285 25775 : if (**p != 0) {
286 0 : return MBEDTLS_ERR_ASN1_INVALID_DATA;
287 : }
288 25775 : ++(*p);
289 :
290 25775 : return 0;
291 : }
292 :
293 51216 : void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
294 : {
295 71984 : while (seq != NULL) {
296 20768 : mbedtls_asn1_sequence *next = seq->next;
297 20768 : mbedtls_free(seq);
298 20768 : seq = next;
299 : }
300 51216 : }
301 :
302 : typedef struct {
303 : int tag;
304 : mbedtls_asn1_sequence *cur;
305 : } asn1_get_sequence_of_cb_ctx_t;
306 :
307 29836 : static int asn1_get_sequence_of_cb(void *ctx,
308 : int tag,
309 : unsigned char *start,
310 : size_t len)
311 : {
312 29836 : asn1_get_sequence_of_cb_ctx_t *cb_ctx =
313 : (asn1_get_sequence_of_cb_ctx_t *) ctx;
314 29836 : mbedtls_asn1_sequence *cur =
315 : cb_ctx->cur;
316 :
317 29836 : if (cur->buf.p != NULL) {
318 19290 : cur->next =
319 19290 : mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
320 :
321 19290 : if (cur->next == NULL) {
322 0 : return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
323 : }
324 :
325 19290 : cur = cur->next;
326 : }
327 :
328 29836 : cur->buf.p = start;
329 29836 : cur->buf.len = len;
330 29836 : cur->buf.tag = tag;
331 :
332 29836 : cb_ctx->cur = cur;
333 29836 : return 0;
334 : }
335 :
336 : /*
337 : * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
338 : */
339 10546 : int mbedtls_asn1_get_sequence_of(unsigned char **p,
340 : const unsigned char *end,
341 : mbedtls_asn1_sequence *cur,
342 : int tag)
343 : {
344 10546 : asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
345 10546 : memset(cur, 0, sizeof(mbedtls_asn1_sequence));
346 10546 : return mbedtls_asn1_traverse_sequence_of(
347 : p, end, 0xFF, tag, 0, 0,
348 : asn1_get_sequence_of_cb, &cb_ctx);
349 : }
350 :
351 38621 : int mbedtls_asn1_get_alg(unsigned char **p,
352 : const unsigned char *end,
353 : mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
354 : {
355 38621 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
356 : size_t len;
357 :
358 38621 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
359 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
360 0 : return ret;
361 : }
362 :
363 38621 : if ((end - *p) < 1) {
364 0 : return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
365 : }
366 :
367 38621 : alg->tag = **p;
368 38621 : end = *p + len;
369 :
370 38621 : if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
371 0 : return ret;
372 : }
373 :
374 38621 : alg->p = *p;
375 38621 : *p += alg->len;
376 :
377 38621 : if (*p == end) {
378 22980 : mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
379 22980 : return 0;
380 : }
381 :
382 15641 : params->tag = **p;
383 15641 : (*p)++;
384 :
385 15641 : if ((ret = mbedtls_asn1_get_len(p, end, ¶ms->len)) != 0) {
386 0 : return ret;
387 : }
388 :
389 15641 : params->p = *p;
390 15641 : *p += params->len;
391 :
392 15641 : if (*p != end) {
393 0 : return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
394 : }
395 :
396 15641 : return 0;
397 : }
398 :
399 0 : int mbedtls_asn1_get_alg_null(unsigned char **p,
400 : const unsigned char *end,
401 : mbedtls_asn1_buf *alg)
402 : {
403 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
404 : mbedtls_asn1_buf params;
405 :
406 0 : memset(¶ms, 0, sizeof(mbedtls_asn1_buf));
407 :
408 0 : if ((ret = mbedtls_asn1_get_alg(p, end, alg, ¶ms)) != 0) {
409 0 : return ret;
410 : }
411 :
412 0 : if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
413 0 : return MBEDTLS_ERR_ASN1_INVALID_DATA;
414 : }
415 :
416 0 : return 0;
417 : }
418 :
419 : #if !defined(MBEDTLS_DEPRECATED_REMOVED)
420 0 : void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
421 : {
422 0 : if (cur == NULL) {
423 0 : return;
424 : }
425 :
426 0 : mbedtls_free(cur->oid.p);
427 0 : mbedtls_free(cur->val.p);
428 :
429 0 : mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
430 : }
431 : #endif /* MBEDTLS_DEPRECATED_REMOVED */
432 :
433 20 : void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
434 : {
435 : mbedtls_asn1_named_data *cur;
436 :
437 82 : while ((cur = *head) != NULL) {
438 62 : *head = cur->next;
439 62 : mbedtls_free(cur->oid.p);
440 62 : mbedtls_free(cur->val.p);
441 62 : mbedtls_free(cur);
442 : }
443 20 : }
444 :
445 25608 : void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name)
446 : {
447 25728 : for (mbedtls_asn1_named_data *next; name != NULL; name = next) {
448 120 : next = name->next;
449 120 : mbedtls_free(name);
450 : }
451 25608 : }
452 :
453 62 : const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list,
454 : const char *oid, size_t len)
455 : {
456 188 : while (list != NULL) {
457 126 : if (list->oid.len == len &&
458 84 : memcmp(list->oid.p, oid, len) == 0) {
459 0 : break;
460 : }
461 :
462 126 : list = list->next;
463 : }
464 :
465 62 : return list;
466 : }
467 :
468 : #endif /* MBEDTLS_ASN1_PARSE_C */
|