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 832291 : int mbedtls_asn1_get_len(unsigned char **p,
29 : const unsigned char *end,
30 : size_t *len)
31 : {
32 832291 : if ((end - *p) < 1) {
33 0 : return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
34 : }
35 :
36 832291 : if ((**p & 0x80) == 0) {
37 766986 : *len = *(*p)++;
38 : } else {
39 65305 : int n = (**p) & 0x7F;
40 65305 : if (n == 0 || n > 4) {
41 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
42 : }
43 65305 : if ((end - *p) <= n) {
44 0 : return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
45 : }
46 65305 : *len = 0;
47 65305 : (*p)++;
48 174220 : while (n--) {
49 108915 : *len = (*len << 8) | **p;
50 108915 : (*p)++;
51 : }
52 : }
53 :
54 832291 : if (*len > (size_t) (end - *p)) {
55 0 : return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
56 : }
57 :
58 832291 : return 0;
59 : }
60 :
61 781812 : int mbedtls_asn1_get_tag(unsigned char **p,
62 : const unsigned char *end,
63 : size_t *len, int tag)
64 : {
65 781812 : if ((end - *p) < 1) {
66 1795 : return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
67 : }
68 :
69 780017 : if (**p != tag) {
70 76740 : return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
71 : }
72 :
73 703277 : (*p)++;
74 :
75 703277 : 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 75842 : int mbedtls_asn1_get_bool(unsigned char **p,
81 : const unsigned char *end,
82 : int *val)
83 : {
84 75842 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
85 : size_t len;
86 :
87 75842 : if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
88 48371 : return ret;
89 : }
90 :
91 27471 : if (len != 1) {
92 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
93 : }
94 :
95 27471 : *val = (**p != 0) ? 1 : 0;
96 27471 : (*p)++;
97 :
98 27471 : return 0;
99 : }
100 :
101 14079 : static int asn1_get_tagged_int(unsigned char **p,
102 : const unsigned char *end,
103 : int tag, int *val)
104 : {
105 14079 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
106 : size_t len;
107 :
108 14079 : 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 14079 : if (len == 0) {
117 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
118 : }
119 : /* This is a cryptography library. Reject negative integers. */
120 14079 : if ((**p & 0x80) != 0) {
121 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
122 : }
123 :
124 : /* Skip leading zeros. */
125 14296 : 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 14079 : if (len > sizeof(int)) {
133 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
134 : }
135 14079 : if (len == sizeof(int) && (**p & 0x80) != 0) {
136 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
137 : }
138 :
139 14079 : *val = 0;
140 27941 : while (len-- > 0) {
141 13862 : *val = (*val << 8) | **p;
142 13862 : (*p)++;
143 : }
144 :
145 14079 : return 0;
146 : }
147 :
148 14079 : int mbedtls_asn1_get_int(unsigned char **p,
149 : const unsigned char *end,
150 : int *val)
151 : {
152 14079 : 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 3102 : int mbedtls_asn1_get_mpi(unsigned char **p,
164 : const unsigned char *end,
165 : mbedtls_mpi *X)
166 : {
167 3102 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
168 : size_t len;
169 :
170 3102 : if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
171 0 : return ret;
172 : }
173 :
174 3102 : ret = mbedtls_mpi_read_binary(X, *p, len);
175 :
176 3102 : *p += len;
177 :
178 3102 : return ret;
179 : }
180 : #endif /* MBEDTLS_BIGNUM_C */
181 :
182 11423 : int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
183 : mbedtls_asn1_bitstring *bs)
184 : {
185 11423 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
186 :
187 : /* Certificate type is a single byte bitstring */
188 11423 : 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 11423 : if (bs->len < 1) {
194 0 : return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
195 : }
196 11423 : bs->len -= 1;
197 :
198 : /* Get number of unused bits, ensure unused bits <= 7 */
199 11423 : bs->unused_bits = **p;
200 11423 : if (bs->unused_bits > 7) {
201 0 : return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
202 : }
203 11423 : (*p)++;
204 :
205 : /* Get actual bitstring */
206 11423 : bs->p = *p;
207 11423 : *p += bs->len;
208 :
209 11423 : if (*p != end) {
210 0 : return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
211 : }
212 :
213 11423 : return 0;
214 : }
215 :
216 : /*
217 : * Traverse an ASN.1 "SEQUENCE OF <tag>"
218 : * and call a callback for each entry found.
219 : */
220 11429 : 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 11429 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
234 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
235 0 : return ret;
236 : }
237 :
238 11429 : if (*p + len != end) {
239 0 : return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
240 : }
241 :
242 43901 : while (*p < end) {
243 32472 : unsigned char const tag = *(*p)++;
244 :
245 32472 : if ((tag & tag_must_mask) != tag_must_val) {
246 0 : return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
247 : }
248 :
249 32472 : if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
250 0 : return ret;
251 : }
252 :
253 32472 : if ((tag & tag_may_mask) == tag_may_val) {
254 32472 : if (cb != NULL) {
255 32472 : ret = cb(ctx, tag, *p, len);
256 32472 : if (ret != 0) {
257 0 : return ret;
258 : }
259 : }
260 : }
261 :
262 32472 : *p += len;
263 : }
264 :
265 11429 : return 0;
266 : }
267 :
268 : /*
269 : * Get a bit string without unused bits
270 : */
271 27589 : int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
272 : size_t *len)
273 : {
274 27589 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
275 :
276 27589 : if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
277 0 : return ret;
278 : }
279 :
280 27589 : if (*len == 0) {
281 0 : return MBEDTLS_ERR_ASN1_INVALID_DATA;
282 : }
283 27589 : --(*len);
284 :
285 27589 : if (**p != 0) {
286 0 : return MBEDTLS_ERR_ASN1_INVALID_DATA;
287 : }
288 27589 : ++(*p);
289 :
290 27589 : return 0;
291 : }
292 :
293 54844 : void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
294 : {
295 77517 : while (seq != NULL) {
296 22673 : mbedtls_asn1_sequence *next = seq->next;
297 22673 : mbedtls_free(seq);
298 22673 : seq = next;
299 : }
300 54844 : }
301 :
302 : typedef struct {
303 : int tag;
304 : mbedtls_asn1_sequence *cur;
305 : } asn1_get_sequence_of_cb_ctx_t;
306 :
307 32472 : static int asn1_get_sequence_of_cb(void *ctx,
308 : int tag,
309 : unsigned char *start,
310 : size_t len)
311 : {
312 32472 : asn1_get_sequence_of_cb_ctx_t *cb_ctx =
313 : (asn1_get_sequence_of_cb_ctx_t *) ctx;
314 32472 : mbedtls_asn1_sequence *cur =
315 : cb_ctx->cur;
316 :
317 32472 : if (cur->buf.p != NULL) {
318 21043 : cur->next =
319 21043 : mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
320 :
321 21043 : if (cur->next == NULL) {
322 0 : return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
323 : }
324 :
325 21043 : cur = cur->next;
326 : }
327 :
328 32472 : cur->buf.p = start;
329 32472 : cur->buf.len = len;
330 32472 : cur->buf.tag = tag;
331 :
332 32472 : cb_ctx->cur = cur;
333 32472 : return 0;
334 : }
335 :
336 : /*
337 : * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
338 : */
339 11429 : int mbedtls_asn1_get_sequence_of(unsigned char **p,
340 : const unsigned char *end,
341 : mbedtls_asn1_sequence *cur,
342 : int tag)
343 : {
344 11429 : asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
345 11429 : memset(cur, 0, sizeof(mbedtls_asn1_sequence));
346 11429 : return mbedtls_asn1_traverse_sequence_of(
347 : p, end, 0xFF, tag, 0, 0,
348 : asn1_get_sequence_of_cb, &cb_ctx);
349 : }
350 :
351 41342 : int mbedtls_asn1_get_alg(unsigned char **p,
352 : const unsigned char *end,
353 : mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
354 : {
355 41342 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
356 : size_t len;
357 :
358 41342 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
359 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
360 0 : return ret;
361 : }
362 :
363 41342 : if ((end - *p) < 1) {
364 0 : return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
365 : }
366 :
367 41342 : alg->tag = **p;
368 41342 : end = *p + len;
369 :
370 41342 : if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
371 0 : return ret;
372 : }
373 :
374 41342 : alg->p = *p;
375 41342 : *p += alg->len;
376 :
377 41342 : if (*p == end) {
378 24666 : mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
379 24666 : return 0;
380 : }
381 :
382 16676 : params->tag = **p;
383 16676 : (*p)++;
384 :
385 16676 : if ((ret = mbedtls_asn1_get_len(p, end, ¶ms->len)) != 0) {
386 0 : return ret;
387 : }
388 :
389 16676 : params->p = *p;
390 16676 : *p += params->len;
391 :
392 16676 : if (*p != end) {
393 0 : return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
394 : }
395 :
396 16676 : 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 27422 : void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name)
446 : {
447 27554 : for (mbedtls_asn1_named_data *next; name != NULL; name = next) {
448 132 : next = name->next;
449 132 : mbedtls_free(name);
450 : }
451 27422 : }
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 */
|