Line data Source code
1 : /*
2 : * X.509 certificate parsing and verification
3 : *
4 : * Copyright The Mbed TLS Contributors
5 : * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 : */
7 : /*
8 : * The ITU-T X.509 standard defines a certificate format for PKI.
9 : *
10 : * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
11 : * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
12 : * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
13 : *
14 : * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
15 : * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
16 : *
17 : * [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf
18 : */
19 :
20 : #include "common.h"
21 :
22 : #if defined(MBEDTLS_X509_CRT_PARSE_C)
23 :
24 : #include "mbedtls/x509_crt.h"
25 : #include "x509_internal.h"
26 : #include "mbedtls/error.h"
27 : #include "mbedtls/oid.h"
28 : #include "mbedtls/platform_util.h"
29 :
30 : #include <string.h>
31 :
32 : #if defined(MBEDTLS_PEM_PARSE_C)
33 : #include "mbedtls/pem.h"
34 : #endif
35 :
36 : #if defined(MBEDTLS_USE_PSA_CRYPTO)
37 : #include "psa/crypto.h"
38 : #include "psa_util_internal.h"
39 : #include "mbedtls/psa_util.h"
40 : #endif /* MBEDTLS_USE_PSA_CRYPTO */
41 : #include "pk_internal.h"
42 :
43 : #include "mbedtls/platform.h"
44 :
45 : #if defined(MBEDTLS_THREADING_C)
46 : #include "mbedtls/threading.h"
47 : #endif
48 :
49 : #if defined(MBEDTLS_HAVE_TIME)
50 : #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
51 : #ifndef WIN32_LEAN_AND_MEAN
52 : #define WIN32_LEAN_AND_MEAN
53 : #endif
54 : #include <windows.h>
55 : #else
56 : #include <time.h>
57 : #endif
58 : #endif
59 :
60 : #if defined(MBEDTLS_FS_IO)
61 : #include <stdio.h>
62 : #if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
63 : #include <sys/types.h>
64 : #include <sys/stat.h>
65 : #if defined(__MBED__)
66 : #include <platform/mbed_retarget.h>
67 : #else
68 : #include <dirent.h>
69 : #endif /* __MBED__ */
70 : #include <errno.h>
71 : #endif /* !_WIN32 || EFIX64 || EFI32 */
72 : #endif
73 :
74 : /*
75 : * Item in a verification chain: cert and flags for it
76 : */
77 : typedef struct {
78 : mbedtls_x509_crt *crt;
79 : uint32_t flags;
80 : } x509_crt_verify_chain_item;
81 :
82 : /*
83 : * Max size of verification chain: end-entity + intermediates + trusted root
84 : */
85 : #define X509_MAX_VERIFY_CHAIN_SIZE (MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2)
86 :
87 : /* Default profile. Do not remove items unless there are serious security
88 : * concerns. */
89 : const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
90 : {
91 : /* Hashes from SHA-256 and above. Note that this selection
92 : * should be aligned with ssl_preset_default_hashes in ssl_tls.c. */
93 : MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
94 : MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) |
95 : MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512),
96 : 0xFFFFFFF, /* Any PK alg */
97 : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
98 : /* Curves at or above 128-bit security level. Note that this selection
99 : * should be aligned with ssl_preset_default_curves in ssl_tls.c. */
100 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
101 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1) |
102 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP521R1) |
103 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP256R1) |
104 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP384R1) |
105 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP512R1) |
106 : 0,
107 : #else /* MBEDTLS_PK_HAVE_ECC_KEYS */
108 : 0,
109 : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
110 : 2048,
111 : };
112 :
113 : /* Next-generation profile. Currently identical to the default, but may
114 : * be tightened at any time. */
115 : const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next =
116 : {
117 : /* Hashes from SHA-256 and above. */
118 : MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
119 : MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) |
120 : MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512),
121 : 0xFFFFFFF, /* Any PK alg */
122 : #if defined(MBEDTLS_ECP_C)
123 : /* Curves at or above 128-bit security level. */
124 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
125 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1) |
126 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP521R1) |
127 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP256R1) |
128 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP384R1) |
129 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP512R1) |
130 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256K1),
131 : #else
132 : 0,
133 : #endif
134 : 2048,
135 : };
136 :
137 : /*
138 : * NSA Suite B Profile
139 : */
140 : const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb =
141 : {
142 : /* Only SHA-256 and 384 */
143 : MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
144 : MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384),
145 : /* Only ECDSA */
146 : MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA) |
147 : MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY),
148 : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
149 : /* Only NIST P-256 and P-384 */
150 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
151 : MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
152 : #else /* MBEDTLS_PK_HAVE_ECC_KEYS */
153 : 0,
154 : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
155 : 0,
156 : };
157 :
158 : /*
159 : * Empty / all-forbidden profile
160 : */
161 : const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_none =
162 : {
163 : 0,
164 : 0,
165 : 0,
166 : (uint32_t) -1,
167 : };
168 :
169 : /*
170 : * Check md_alg against profile
171 : * Return 0 if md_alg is acceptable for this profile, -1 otherwise
172 : */
173 2375 : static int x509_profile_check_md_alg(const mbedtls_x509_crt_profile *profile,
174 : mbedtls_md_type_t md_alg)
175 : {
176 2375 : if (md_alg == MBEDTLS_MD_NONE) {
177 0 : return -1;
178 : }
179 :
180 2375 : if ((profile->allowed_mds & MBEDTLS_X509_ID_FLAG(md_alg)) != 0) {
181 2375 : return 0;
182 : }
183 :
184 0 : return -1;
185 : }
186 :
187 : /*
188 : * Check pk_alg against profile
189 : * Return 0 if pk_alg is acceptable for this profile, -1 otherwise
190 : */
191 4750 : static int x509_profile_check_pk_alg(const mbedtls_x509_crt_profile *profile,
192 : mbedtls_pk_type_t pk_alg)
193 : {
194 4750 : if (pk_alg == MBEDTLS_PK_NONE) {
195 0 : return -1;
196 : }
197 :
198 4750 : if ((profile->allowed_pks & MBEDTLS_X509_ID_FLAG(pk_alg)) != 0) {
199 4750 : return 0;
200 : }
201 :
202 0 : return -1;
203 : }
204 :
205 : /*
206 : * Check key against profile
207 : * Return 0 if pk is acceptable for this profile, -1 otherwise
208 : */
209 4041 : static int x509_profile_check_key(const mbedtls_x509_crt_profile *profile,
210 : const mbedtls_pk_context *pk)
211 : {
212 4041 : const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(pk);
213 :
214 : #if defined(MBEDTLS_RSA_C)
215 4041 : if (pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS) {
216 600 : if (mbedtls_pk_get_bitlen(pk) >= profile->rsa_min_bitlen) {
217 600 : return 0;
218 : }
219 :
220 0 : return -1;
221 : }
222 : #endif /* MBEDTLS_RSA_C */
223 :
224 : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
225 3441 : if (pk_alg == MBEDTLS_PK_ECDSA ||
226 0 : pk_alg == MBEDTLS_PK_ECKEY ||
227 : pk_alg == MBEDTLS_PK_ECKEY_DH) {
228 3441 : const mbedtls_ecp_group_id gid = mbedtls_pk_get_ec_group_id(pk);
229 :
230 3441 : if (gid == MBEDTLS_ECP_DP_NONE) {
231 0 : return -1;
232 : }
233 :
234 3441 : if ((profile->allowed_curves & MBEDTLS_X509_ID_FLAG(gid)) != 0) {
235 3441 : return 0;
236 : }
237 :
238 0 : return -1;
239 : }
240 : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
241 :
242 0 : return -1;
243 : }
244 :
245 : /*
246 : * Like memcmp, but case-insensitive and always returns -1 if different
247 : */
248 175 : static int x509_memcasecmp(const void *s1, const void *s2, size_t len)
249 : {
250 : size_t i;
251 : unsigned char diff;
252 175 : const unsigned char *n1 = s1, *n2 = s2;
253 :
254 5374 : for (i = 0; i < len; i++) {
255 5374 : diff = n1[i] ^ n2[i];
256 :
257 5374 : if (diff == 0) {
258 5199 : continue;
259 : }
260 :
261 175 : if (diff == 32 &&
262 0 : ((n1[i] >= 'a' && n1[i] <= 'z') ||
263 0 : (n1[i] >= 'A' && n1[i] <= 'Z'))) {
264 0 : continue;
265 : }
266 :
267 175 : return -1;
268 : }
269 :
270 0 : return 0;
271 : }
272 :
273 : /*
274 : * Return 0 if name matches wildcard, -1 otherwise
275 : */
276 0 : static int x509_check_wildcard(const char *cn, const mbedtls_x509_buf *name)
277 : {
278 : size_t i;
279 0 : size_t cn_idx = 0, cn_len = strlen(cn);
280 :
281 : /* We can't have a match if there is no wildcard to match */
282 0 : if (name->len < 3 || name->p[0] != '*' || name->p[1] != '.') {
283 0 : return -1;
284 : }
285 :
286 0 : for (i = 0; i < cn_len; ++i) {
287 0 : if (cn[i] == '.') {
288 0 : cn_idx = i;
289 0 : break;
290 : }
291 : }
292 :
293 0 : if (cn_idx == 0) {
294 0 : return -1;
295 : }
296 :
297 0 : if (cn_len - cn_idx == name->len - 1 &&
298 0 : x509_memcasecmp(name->p + 1, cn + cn_idx, name->len - 1) == 0) {
299 0 : return 0;
300 : }
301 :
302 0 : return -1;
303 : }
304 :
305 : /*
306 : * Compare two X.509 strings, case-insensitive, and allowing for some encoding
307 : * variations (but not all).
308 : *
309 : * Return 0 if equal, -1 otherwise.
310 : */
311 4043 : static int x509_string_cmp(const mbedtls_x509_buf *a, const mbedtls_x509_buf *b)
312 : {
313 4043 : if (a->tag == b->tag &&
314 4043 : a->len == b->len &&
315 2550 : memcmp(a->p, b->p, b->len) == 0) {
316 2375 : return 0;
317 : }
318 :
319 1668 : if ((a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING) &&
320 1668 : (b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING) &&
321 1843 : a->len == b->len &&
322 175 : x509_memcasecmp(a->p, b->p, b->len) == 0) {
323 0 : return 0;
324 : }
325 :
326 1668 : return -1;
327 : }
328 :
329 : /*
330 : * Compare two X.509 Names (aka rdnSequence).
331 : *
332 : * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
333 : * we sometimes return unequal when the full algorithm would return equal,
334 : * but never the other way. (In particular, we don't do Unicode normalisation
335 : * or space folding.)
336 : *
337 : * Return 0 if equal, -1 otherwise.
338 : */
339 4043 : static int x509_name_cmp(const mbedtls_x509_name *a, const mbedtls_x509_name *b)
340 : {
341 : /* Avoid recursion, it might not be optimised by the compiler */
342 6418 : while (a != NULL || b != NULL) {
343 4043 : if (a == NULL || b == NULL) {
344 0 : return -1;
345 : }
346 :
347 : /* type */
348 4043 : if (a->oid.tag != b->oid.tag ||
349 4043 : a->oid.len != b->oid.len ||
350 4043 : memcmp(a->oid.p, b->oid.p, b->oid.len) != 0) {
351 0 : return -1;
352 : }
353 :
354 : /* value */
355 4043 : if (x509_string_cmp(&a->val, &b->val) != 0) {
356 1668 : return -1;
357 : }
358 :
359 : /* structure of the list of sets */
360 2375 : if (a->next_merged != b->next_merged) {
361 0 : return -1;
362 : }
363 :
364 2375 : a = a->next;
365 2375 : b = b->next;
366 : }
367 :
368 : /* a == NULL == b */
369 2375 : return 0;
370 : }
371 :
372 : /*
373 : * Reset (init or clear) a verify_chain
374 : */
375 2375 : static void x509_crt_verify_chain_reset(
376 : mbedtls_x509_crt_verify_chain *ver_chain)
377 : {
378 : size_t i;
379 :
380 26125 : for (i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++) {
381 23750 : ver_chain->items[i].crt = NULL;
382 23750 : ver_chain->items[i].flags = (uint32_t) -1;
383 : }
384 :
385 2375 : ver_chain->len = 0;
386 :
387 : #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
388 : ver_chain->trust_ca_cb_result = NULL;
389 : #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
390 2375 : }
391 :
392 : /*
393 : * Version ::= INTEGER { v1(0), v2(1), v3(2) }
394 : */
395 12810 : static int x509_get_version(unsigned char **p,
396 : const unsigned char *end,
397 : int *ver)
398 : {
399 12810 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
400 : size_t len;
401 :
402 12810 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
403 : MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
404 : 0)) != 0) {
405 0 : if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
406 0 : *ver = 0;
407 0 : return 0;
408 : }
409 :
410 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
411 : }
412 :
413 12810 : end = *p + len;
414 :
415 12810 : if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) {
416 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret);
417 : }
418 :
419 12810 : if (*p != end) {
420 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION,
421 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
422 : }
423 :
424 12810 : return 0;
425 : }
426 :
427 : /*
428 : * Validity ::= SEQUENCE {
429 : * notBefore Time,
430 : * notAfter Time }
431 : */
432 12810 : static int x509_get_dates(unsigned char **p,
433 : const unsigned char *end,
434 : mbedtls_x509_time *from,
435 : mbedtls_x509_time *to)
436 : {
437 12810 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
438 : size_t len;
439 :
440 12810 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
441 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
442 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, ret);
443 : }
444 :
445 12810 : end = *p + len;
446 :
447 12810 : if ((ret = mbedtls_x509_get_time(p, end, from)) != 0) {
448 0 : return ret;
449 : }
450 :
451 12810 : if ((ret = mbedtls_x509_get_time(p, end, to)) != 0) {
452 0 : return ret;
453 : }
454 :
455 12810 : if (*p != end) {
456 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
457 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
458 : }
459 :
460 12810 : return 0;
461 : }
462 :
463 : /*
464 : * X.509 v2/v3 unique identifier (not parsed)
465 : */
466 25620 : static int x509_get_uid(unsigned char **p,
467 : const unsigned char *end,
468 : mbedtls_x509_buf *uid, int n)
469 : {
470 25620 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
471 :
472 25620 : if (*p == end) {
473 0 : return 0;
474 : }
475 :
476 25620 : uid->tag = **p;
477 :
478 25620 : if ((ret = mbedtls_asn1_get_tag(p, end, &uid->len,
479 : MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
480 : n)) != 0) {
481 25620 : if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
482 25620 : return 0;
483 : }
484 :
485 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
486 : }
487 :
488 0 : uid->p = *p;
489 0 : *p += uid->len;
490 :
491 0 : return 0;
492 : }
493 :
494 12790 : static int x509_get_basic_constraints(unsigned char **p,
495 : const unsigned char *end,
496 : int *ca_istrue,
497 : int *max_pathlen)
498 : {
499 12790 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
500 : size_t len;
501 :
502 : /*
503 : * BasicConstraints ::= SEQUENCE {
504 : * cA BOOLEAN DEFAULT FALSE,
505 : * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
506 : */
507 12790 : *ca_istrue = 0; /* DEFAULT FALSE */
508 12790 : *max_pathlen = 0; /* endless */
509 :
510 12790 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
511 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
512 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
513 : }
514 :
515 12790 : if (*p == end) {
516 8610 : return 0;
517 : }
518 :
519 4180 : if ((ret = mbedtls_asn1_get_bool(p, end, ca_istrue)) != 0) {
520 0 : if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
521 0 : ret = mbedtls_asn1_get_int(p, end, ca_istrue);
522 : }
523 :
524 0 : if (ret != 0) {
525 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
526 : }
527 :
528 0 : if (*ca_istrue != 0) {
529 0 : *ca_istrue = 1;
530 : }
531 : }
532 :
533 4180 : if (*p == end) {
534 4180 : return 0;
535 : }
536 :
537 0 : if ((ret = mbedtls_asn1_get_int(p, end, max_pathlen)) != 0) {
538 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
539 : }
540 :
541 0 : if (*p != end) {
542 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
543 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
544 : }
545 :
546 : /* Do not accept max_pathlen equal to INT_MAX to avoid a signed integer
547 : * overflow, which is an undefined behavior. */
548 0 : if (*max_pathlen == INT_MAX) {
549 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
550 : MBEDTLS_ERR_ASN1_INVALID_LENGTH);
551 : }
552 :
553 0 : (*max_pathlen)++;
554 :
555 0 : return 0;
556 : }
557 :
558 : /*
559 : * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
560 : *
561 : * KeyPurposeId ::= OBJECT IDENTIFIER
562 : */
563 10540 : static int x509_get_ext_key_usage(unsigned char **p,
564 : const unsigned char *end,
565 : mbedtls_x509_sequence *ext_key_usage)
566 : {
567 10540 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
568 :
569 10540 : if ((ret = mbedtls_asn1_get_sequence_of(p, end, ext_key_usage, MBEDTLS_ASN1_OID)) != 0) {
570 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
571 : }
572 :
573 : /* Sequence length must be >= 1 */
574 10540 : if (ext_key_usage->buf.p == NULL) {
575 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
576 : MBEDTLS_ERR_ASN1_INVALID_LENGTH);
577 : }
578 :
579 10540 : return 0;
580 : }
581 :
582 : /*
583 : * SubjectKeyIdentifier ::= KeyIdentifier
584 : *
585 : * KeyIdentifier ::= OCTET STRING
586 : */
587 12810 : static int x509_get_subject_key_id(unsigned char **p,
588 : const unsigned char *end,
589 : mbedtls_x509_buf *subject_key_id)
590 : {
591 12810 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
592 12810 : size_t len = 0u;
593 :
594 12810 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
595 : MBEDTLS_ASN1_OCTET_STRING)) != 0) {
596 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
597 : }
598 :
599 12810 : subject_key_id->len = len;
600 12810 : subject_key_id->tag = MBEDTLS_ASN1_OCTET_STRING;
601 12810 : subject_key_id->p = *p;
602 12810 : *p += len;
603 :
604 12810 : if (*p != end) {
605 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
606 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
607 : }
608 :
609 12810 : return 0;
610 : }
611 :
612 : /*
613 : * AuthorityKeyIdentifier ::= SEQUENCE {
614 : * keyIdentifier [0] KeyIdentifier OPTIONAL,
615 : * authorityCertIssuer [1] GeneralNames OPTIONAL,
616 : * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
617 : *
618 : * KeyIdentifier ::= OCTET STRING
619 : */
620 2310 : static int x509_get_authority_key_id(unsigned char **p,
621 : unsigned char *end,
622 : mbedtls_x509_authority *authority_key_id)
623 : {
624 2310 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
625 2310 : size_t len = 0u;
626 :
627 2310 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
628 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
629 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
630 : }
631 :
632 2310 : if (*p + len != end) {
633 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
634 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
635 : }
636 :
637 2310 : ret = mbedtls_asn1_get_tag(p, end, &len,
638 : MBEDTLS_ASN1_CONTEXT_SPECIFIC);
639 :
640 : /* KeyIdentifier is an OPTIONAL field */
641 2310 : if (ret == 0) {
642 2310 : authority_key_id->keyIdentifier.len = len;
643 2310 : authority_key_id->keyIdentifier.p = *p;
644 : /* Setting tag of the keyIdentfier intentionally to 0x04.
645 : * Although the .keyIdentfier field is CONTEXT_SPECIFIC ([0] OPTIONAL),
646 : * its tag with the content is the payload of on OCTET STRING primitive */
647 2310 : authority_key_id->keyIdentifier.tag = MBEDTLS_ASN1_OCTET_STRING;
648 :
649 2310 : *p += len;
650 0 : } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
651 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
652 : }
653 :
654 2310 : if (*p < end) {
655 : /* Getting authorityCertIssuer using the required specific class tag [1] */
656 0 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
657 : MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
658 : 1)) != 0) {
659 : /* authorityCertIssuer and authorityCertSerialNumber MUST both
660 : be present or both be absent. At this point we expect to have both. */
661 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
662 : }
663 : /* "end" also includes the CertSerialNumber field so "len" shall be used */
664 0 : ret = mbedtls_x509_get_subject_alt_name_ext(p,
665 0 : (*p+len),
666 : &authority_key_id->authorityCertIssuer);
667 0 : if (ret != 0) {
668 0 : return ret;
669 : }
670 :
671 : /* Getting authorityCertSerialNumber using the required specific class tag [2] */
672 0 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
673 : MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2)) != 0) {
674 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
675 : }
676 0 : authority_key_id->authorityCertSerialNumber.len = len;
677 0 : authority_key_id->authorityCertSerialNumber.p = *p;
678 0 : authority_key_id->authorityCertSerialNumber.tag = MBEDTLS_ASN1_INTEGER;
679 0 : *p += len;
680 : }
681 :
682 2310 : if (*p != end) {
683 0 : return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
684 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
685 : }
686 :
687 2310 : return 0;
688 : }
689 :
690 : /*
691 : * id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
692 : *
693 : * anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
694 : *
695 : * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
696 : *
697 : * PolicyInformation ::= SEQUENCE {
698 : * policyIdentifier CertPolicyId,
699 : * policyQualifiers SEQUENCE SIZE (1..MAX) OF
700 : * PolicyQualifierInfo OPTIONAL }
701 : *
702 : * CertPolicyId ::= OBJECT IDENTIFIER
703 : *
704 : * PolicyQualifierInfo ::= SEQUENCE {
705 : * policyQualifierId PolicyQualifierId,
706 : * qualifier ANY DEFINED BY policyQualifierId }
707 : *
708 : * -- policyQualifierIds for Internet policy qualifiers
709 : *
710 : * id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
711 : * id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
712 : * id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
713 : *
714 : * PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
715 : *
716 : * Qualifier ::= CHOICE {
717 : * cPSuri CPSuri,
718 : * userNotice UserNotice }
719 : *
720 : * CPSuri ::= IA5String
721 : *
722 : * UserNotice ::= SEQUENCE {
723 : * noticeRef NoticeReference OPTIONAL,
724 : * explicitText DisplayText OPTIONAL }
725 : *
726 : * NoticeReference ::= SEQUENCE {
727 : * organization DisplayText,
728 : * noticeNumbers SEQUENCE OF INTEGER }
729 : *
730 : * DisplayText ::= CHOICE {
731 : * ia5String IA5String (SIZE (1..200)),
732 : * visibleString VisibleString (SIZE (1..200)),
733 : * bmpString BMPString (SIZE (1..200)),
734 : * utf8String UTF8String (SIZE (1..200)) }
735 : *
736 : * NOTE: we only parse and use anyPolicy without qualifiers at this point
737 : * as defined in RFC 5280.
738 : */
739 40 : static int x509_get_certificate_policies(unsigned char **p,
740 : const unsigned char *end,
741 : mbedtls_x509_sequence *certificate_policies)
742 : {
743 40 : int ret, parse_ret = 0;
744 : size_t len;
745 : mbedtls_asn1_buf *buf;
746 40 : mbedtls_asn1_sequence *cur = certificate_policies;
747 :
748 : /* Get main sequence tag */
749 40 : ret = mbedtls_asn1_get_tag(p, end, &len,
750 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
751 40 : if (ret != 0) {
752 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
753 : }
754 :
755 40 : if (*p + len != end) {
756 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
757 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
758 : }
759 :
760 : /*
761 : * Cannot be an empty sequence.
762 : */
763 40 : if (len == 0) {
764 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
765 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
766 : }
767 :
768 100 : while (*p < end) {
769 : mbedtls_x509_buf policy_oid;
770 : const unsigned char *policy_end;
771 :
772 : /*
773 : * Get the policy sequence
774 : */
775 60 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
776 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
777 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
778 : }
779 :
780 60 : policy_end = *p + len;
781 :
782 60 : if ((ret = mbedtls_asn1_get_tag(p, policy_end, &len,
783 : MBEDTLS_ASN1_OID)) != 0) {
784 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
785 : }
786 :
787 60 : policy_oid.tag = MBEDTLS_ASN1_OID;
788 60 : policy_oid.len = len;
789 60 : policy_oid.p = *p;
790 :
791 : /*
792 : * Only AnyPolicy is currently supported when enforcing policy.
793 : */
794 60 : if (MBEDTLS_OID_CMP(MBEDTLS_OID_ANY_POLICY, &policy_oid) != 0) {
795 : /*
796 : * Set the parsing return code but continue parsing, in case this
797 : * extension is critical.
798 : */
799 60 : parse_ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
800 : }
801 :
802 : /* Allocate and assign next pointer */
803 60 : if (cur->buf.p != NULL) {
804 20 : if (cur->next != NULL) {
805 0 : return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
806 : }
807 :
808 20 : cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
809 :
810 20 : if (cur->next == NULL) {
811 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
812 : MBEDTLS_ERR_ASN1_ALLOC_FAILED);
813 : }
814 :
815 20 : cur = cur->next;
816 : }
817 :
818 60 : buf = &(cur->buf);
819 60 : buf->tag = policy_oid.tag;
820 60 : buf->p = policy_oid.p;
821 60 : buf->len = policy_oid.len;
822 :
823 60 : *p += len;
824 :
825 : /*
826 : * If there is an optional qualifier, then *p < policy_end
827 : * Check the Qualifier len to verify it doesn't exceed policy_end.
828 : */
829 60 : if (*p < policy_end) {
830 30 : if ((ret = mbedtls_asn1_get_tag(p, policy_end, &len,
831 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) !=
832 : 0) {
833 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
834 : }
835 : /*
836 : * Skip the optional policy qualifiers.
837 : */
838 30 : *p += len;
839 : }
840 :
841 60 : if (*p != policy_end) {
842 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
843 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
844 : }
845 : }
846 :
847 : /* Set final sequence entry's next pointer to NULL */
848 40 : cur->next = NULL;
849 :
850 40 : if (*p != end) {
851 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
852 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
853 : }
854 :
855 40 : return parse_ret;
856 : }
857 :
858 : /*
859 : * X.509 v3 extensions
860 : *
861 : */
862 12810 : static int x509_get_crt_ext(unsigned char **p,
863 : const unsigned char *end,
864 : mbedtls_x509_crt *crt,
865 : mbedtls_x509_crt_ext_cb_t cb,
866 : void *p_ctx)
867 : {
868 12810 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
869 : size_t len;
870 : unsigned char *end_ext_data, *start_ext_octet, *end_ext_octet;
871 :
872 12810 : if (*p == end) {
873 0 : return 0;
874 : }
875 :
876 12810 : if ((ret = mbedtls_x509_get_ext(p, end, &crt->v3_ext, 3)) != 0) {
877 0 : return ret;
878 : }
879 :
880 12810 : end = crt->v3_ext.p + crt->v3_ext.len;
881 79095 : while (*p < end) {
882 : /*
883 : * Extension ::= SEQUENCE {
884 : * extnID OBJECT IDENTIFIER,
885 : * critical BOOLEAN DEFAULT FALSE,
886 : * extnValue OCTET STRING }
887 : */
888 66285 : mbedtls_x509_buf extn_oid = { 0, 0, NULL };
889 66285 : int is_critical = 0; /* DEFAULT FALSE */
890 66285 : int ext_type = 0;
891 :
892 66285 : if ((ret = mbedtls_asn1_get_tag(p, end, &len,
893 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
894 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
895 : }
896 :
897 66285 : end_ext_data = *p + len;
898 :
899 : /* Get extension ID */
900 66285 : if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &extn_oid.len,
901 : MBEDTLS_ASN1_OID)) != 0) {
902 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
903 : }
904 :
905 66285 : extn_oid.tag = MBEDTLS_ASN1_OID;
906 66285 : extn_oid.p = *p;
907 66285 : *p += extn_oid.len;
908 :
909 : /* Get optional critical */
910 66285 : if ((ret = mbedtls_asn1_get_bool(p, end_ext_data, &is_critical)) != 0 &&
911 : (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
912 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
913 : }
914 :
915 : /* Data should be octet string type */
916 66285 : if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
917 : MBEDTLS_ASN1_OCTET_STRING)) != 0) {
918 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
919 : }
920 :
921 66285 : start_ext_octet = *p;
922 66285 : end_ext_octet = *p + len;
923 :
924 66285 : if (end_ext_octet != end_ext_data) {
925 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
926 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
927 : }
928 :
929 : /*
930 : * Detect supported extensions
931 : */
932 66285 : ret = mbedtls_oid_get_x509_ext_type(&extn_oid, &ext_type);
933 :
934 66285 : if (ret != 0) {
935 : /* Give the callback (if any) a chance to handle the extension */
936 8617 : if (cb != NULL) {
937 0 : ret = cb(p_ctx, crt, &extn_oid, is_critical, *p, end_ext_octet);
938 0 : if (ret != 0 && is_critical) {
939 0 : return ret;
940 : }
941 0 : *p = end_ext_octet;
942 8617 : continue;
943 : }
944 :
945 : /* No parser found, skip extension */
946 8617 : *p = end_ext_octet;
947 :
948 8617 : if (is_critical) {
949 : /* Data is marked as critical: fail */
950 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
951 : MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
952 : }
953 8617 : continue;
954 : }
955 :
956 : /* Forbid repeated extensions */
957 57668 : if ((crt->ext_types & ext_type) != 0) {
958 0 : return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
959 : }
960 :
961 57668 : crt->ext_types |= ext_type;
962 :
963 57668 : switch (ext_type) {
964 12790 : case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS:
965 : /* Parse basic constraints */
966 12790 : if ((ret = x509_get_basic_constraints(p, end_ext_octet,
967 : &crt->ca_istrue, &crt->max_pathlen)) != 0) {
968 0 : return ret;
969 : }
970 12790 : break;
971 :
972 10540 : case MBEDTLS_X509_EXT_KEY_USAGE:
973 : /* Parse key usage */
974 10540 : if ((ret = mbedtls_x509_get_key_usage(p, end_ext_octet,
975 : &crt->key_usage)) != 0) {
976 0 : return ret;
977 : }
978 10540 : break;
979 :
980 10540 : case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE:
981 : /* Parse extended key usage */
982 10540 : if ((ret = x509_get_ext_key_usage(p, end_ext_octet,
983 : &crt->ext_key_usage)) != 0) {
984 0 : return ret;
985 : }
986 10540 : break;
987 :
988 12810 : case MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER:
989 : /* Parse subject key identifier */
990 12810 : if ((ret = x509_get_subject_key_id(p, end_ext_data,
991 : &crt->subject_key_id)) != 0) {
992 0 : return ret;
993 : }
994 12810 : break;
995 :
996 2310 : case MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER:
997 : /* Parse authority key identifier */
998 2310 : if ((ret = x509_get_authority_key_id(p, end_ext_octet,
999 : &crt->authority_key_id)) != 0) {
1000 0 : return ret;
1001 : }
1002 2310 : break;
1003 8638 : case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
1004 : /* Parse subject alt name
1005 : * SubjectAltName ::= GeneralNames
1006 : */
1007 8638 : if ((ret = mbedtls_x509_get_subject_alt_name(p, end_ext_octet,
1008 : &crt->subject_alt_names)) != 0) {
1009 0 : return ret;
1010 : }
1011 8638 : break;
1012 :
1013 0 : case MBEDTLS_X509_EXT_NS_CERT_TYPE:
1014 : /* Parse netscape certificate type */
1015 0 : if ((ret = mbedtls_x509_get_ns_cert_type(p, end_ext_octet,
1016 : &crt->ns_cert_type)) != 0) {
1017 0 : return ret;
1018 : }
1019 0 : break;
1020 :
1021 40 : case MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES:
1022 : /* Parse certificate policies type */
1023 40 : if ((ret = x509_get_certificate_policies(p, end_ext_octet,
1024 : &crt->certificate_policies)) != 0) {
1025 : /* Give the callback (if any) a chance to handle the extension
1026 : * if it contains unsupported policies */
1027 40 : if (ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE && cb != NULL &&
1028 0 : cb(p_ctx, crt, &extn_oid, is_critical,
1029 : start_ext_octet, end_ext_octet) == 0) {
1030 0 : break;
1031 : }
1032 :
1033 40 : if (is_critical) {
1034 0 : return ret;
1035 : } else
1036 : /*
1037 : * If MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE is returned, then we
1038 : * cannot interpret or enforce the policy. However, it is up to
1039 : * the user to choose how to enforce the policies,
1040 : * unless the extension is critical.
1041 : */
1042 40 : if (ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
1043 0 : return ret;
1044 : }
1045 : }
1046 40 : break;
1047 :
1048 0 : default:
1049 : /*
1050 : * If this is a non-critical extension, which the oid layer
1051 : * supports, but there isn't an x509 parser for it,
1052 : * skip the extension.
1053 : */
1054 0 : if (is_critical) {
1055 0 : return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
1056 : } else {
1057 0 : *p = end_ext_octet;
1058 : }
1059 : }
1060 : }
1061 :
1062 12810 : if (*p != end) {
1063 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1064 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1065 : }
1066 :
1067 12810 : return 0;
1068 : }
1069 :
1070 : /*
1071 : * Parse and fill a single X.509 certificate in DER format
1072 : */
1073 12810 : static int x509_crt_parse_der_core(mbedtls_x509_crt *crt,
1074 : const unsigned char *buf,
1075 : size_t buflen,
1076 : int make_copy,
1077 : mbedtls_x509_crt_ext_cb_t cb,
1078 : void *p_ctx)
1079 : {
1080 12810 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1081 : size_t len;
1082 : unsigned char *p, *end, *crt_end;
1083 : mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
1084 :
1085 12810 : memset(&sig_params1, 0, sizeof(mbedtls_x509_buf));
1086 12810 : memset(&sig_params2, 0, sizeof(mbedtls_x509_buf));
1087 12810 : memset(&sig_oid2, 0, sizeof(mbedtls_x509_buf));
1088 :
1089 : /*
1090 : * Check for valid input
1091 : */
1092 12810 : if (crt == NULL || buf == NULL) {
1093 0 : return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1094 : }
1095 :
1096 : /* Use the original buffer until we figure out actual length. */
1097 12810 : p = (unsigned char *) buf;
1098 12810 : len = buflen;
1099 12810 : end = p + len;
1100 :
1101 : /*
1102 : * Certificate ::= SEQUENCE {
1103 : * tbsCertificate TBSCertificate,
1104 : * signatureAlgorithm AlgorithmIdentifier,
1105 : * signatureValue BIT STRING }
1106 : */
1107 12810 : if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
1108 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
1109 0 : mbedtls_x509_crt_free(crt);
1110 0 : return MBEDTLS_ERR_X509_INVALID_FORMAT;
1111 : }
1112 :
1113 12810 : end = crt_end = p + len;
1114 12810 : crt->raw.len = (size_t) (crt_end - buf);
1115 12810 : if (make_copy != 0) {
1116 : /* Create and populate a new buffer for the raw field. */
1117 12810 : crt->raw.p = p = mbedtls_calloc(1, crt->raw.len);
1118 12810 : if (crt->raw.p == NULL) {
1119 0 : return MBEDTLS_ERR_X509_ALLOC_FAILED;
1120 : }
1121 :
1122 12810 : memcpy(crt->raw.p, buf, crt->raw.len);
1123 12810 : crt->own_buffer = 1;
1124 :
1125 12810 : p += crt->raw.len - len;
1126 12810 : end = crt_end = p + len;
1127 : } else {
1128 0 : crt->raw.p = (unsigned char *) buf;
1129 0 : crt->own_buffer = 0;
1130 : }
1131 :
1132 : /*
1133 : * TBSCertificate ::= SEQUENCE {
1134 : */
1135 12810 : crt->tbs.p = p;
1136 :
1137 12810 : if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
1138 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
1139 0 : mbedtls_x509_crt_free(crt);
1140 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
1141 : }
1142 :
1143 12810 : end = p + len;
1144 12810 : crt->tbs.len = (size_t) (end - crt->tbs.p);
1145 :
1146 : /*
1147 : * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1148 : *
1149 : * CertificateSerialNumber ::= INTEGER
1150 : *
1151 : * signature AlgorithmIdentifier
1152 : */
1153 25620 : if ((ret = x509_get_version(&p, end, &crt->version)) != 0 ||
1154 25620 : (ret = mbedtls_x509_get_serial(&p, end, &crt->serial)) != 0 ||
1155 12810 : (ret = mbedtls_x509_get_alg(&p, end, &crt->sig_oid,
1156 : &sig_params1)) != 0) {
1157 0 : mbedtls_x509_crt_free(crt);
1158 0 : return ret;
1159 : }
1160 :
1161 12810 : if (crt->version < 0 || crt->version > 2) {
1162 0 : mbedtls_x509_crt_free(crt);
1163 0 : return MBEDTLS_ERR_X509_UNKNOWN_VERSION;
1164 : }
1165 :
1166 12810 : crt->version++;
1167 :
1168 12810 : if ((ret = mbedtls_x509_get_sig_alg(&crt->sig_oid, &sig_params1,
1169 : &crt->sig_md, &crt->sig_pk,
1170 : &crt->sig_opts)) != 0) {
1171 0 : mbedtls_x509_crt_free(crt);
1172 0 : return ret;
1173 : }
1174 :
1175 : /*
1176 : * issuer Name
1177 : */
1178 12810 : crt->issuer_raw.p = p;
1179 :
1180 12810 : if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
1181 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
1182 0 : mbedtls_x509_crt_free(crt);
1183 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
1184 : }
1185 :
1186 12810 : if ((ret = mbedtls_x509_get_name(&p, p + len, &crt->issuer)) != 0) {
1187 0 : mbedtls_x509_crt_free(crt);
1188 0 : return ret;
1189 : }
1190 :
1191 12810 : crt->issuer_raw.len = (size_t) (p - crt->issuer_raw.p);
1192 :
1193 : /*
1194 : * Validity ::= SEQUENCE {
1195 : * notBefore Time,
1196 : * notAfter Time }
1197 : *
1198 : */
1199 12810 : if ((ret = x509_get_dates(&p, end, &crt->valid_from,
1200 : &crt->valid_to)) != 0) {
1201 0 : mbedtls_x509_crt_free(crt);
1202 0 : return ret;
1203 : }
1204 :
1205 : /*
1206 : * subject Name
1207 : */
1208 12810 : crt->subject_raw.p = p;
1209 :
1210 12810 : if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
1211 : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
1212 0 : mbedtls_x509_crt_free(crt);
1213 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
1214 : }
1215 :
1216 12810 : if (len && (ret = mbedtls_x509_get_name(&p, p + len, &crt->subject)) != 0) {
1217 0 : mbedtls_x509_crt_free(crt);
1218 0 : return ret;
1219 : }
1220 :
1221 12810 : crt->subject_raw.len = (size_t) (p - crt->subject_raw.p);
1222 :
1223 : /*
1224 : * SubjectPublicKeyInfo
1225 : */
1226 12810 : crt->pk_raw.p = p;
1227 12810 : if ((ret = mbedtls_pk_parse_subpubkey(&p, end, &crt->pk)) != 0) {
1228 0 : mbedtls_x509_crt_free(crt);
1229 0 : return ret;
1230 : }
1231 12810 : crt->pk_raw.len = (size_t) (p - crt->pk_raw.p);
1232 :
1233 : /*
1234 : * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1235 : * -- If present, version shall be v2 or v3
1236 : * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1237 : * -- If present, version shall be v2 or v3
1238 : * extensions [3] EXPLICIT Extensions OPTIONAL
1239 : * -- If present, version shall be v3
1240 : */
1241 12810 : if (crt->version == 2 || crt->version == 3) {
1242 12810 : ret = x509_get_uid(&p, end, &crt->issuer_id, 1);
1243 12810 : if (ret != 0) {
1244 0 : mbedtls_x509_crt_free(crt);
1245 0 : return ret;
1246 : }
1247 : }
1248 :
1249 12810 : if (crt->version == 2 || crt->version == 3) {
1250 12810 : ret = x509_get_uid(&p, end, &crt->subject_id, 2);
1251 12810 : if (ret != 0) {
1252 0 : mbedtls_x509_crt_free(crt);
1253 0 : return ret;
1254 : }
1255 : }
1256 :
1257 12810 : if (crt->version == 3) {
1258 12810 : ret = x509_get_crt_ext(&p, end, crt, cb, p_ctx);
1259 12810 : if (ret != 0) {
1260 0 : mbedtls_x509_crt_free(crt);
1261 0 : return ret;
1262 : }
1263 : }
1264 :
1265 12810 : if (p != end) {
1266 0 : mbedtls_x509_crt_free(crt);
1267 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
1268 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1269 : }
1270 :
1271 12810 : end = crt_end;
1272 :
1273 : /*
1274 : * }
1275 : * -- end of TBSCertificate
1276 : *
1277 : * signatureAlgorithm AlgorithmIdentifier,
1278 : * signatureValue BIT STRING
1279 : */
1280 12810 : if ((ret = mbedtls_x509_get_alg(&p, end, &sig_oid2, &sig_params2)) != 0) {
1281 0 : mbedtls_x509_crt_free(crt);
1282 0 : return ret;
1283 : }
1284 :
1285 12810 : if (crt->sig_oid.len != sig_oid2.len ||
1286 12810 : memcmp(crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len) != 0 ||
1287 12810 : sig_params1.tag != sig_params2.tag ||
1288 12810 : sig_params1.len != sig_params2.len ||
1289 12810 : (sig_params1.len != 0 &&
1290 0 : memcmp(sig_params1.p, sig_params2.p, sig_params1.len) != 0)) {
1291 0 : mbedtls_x509_crt_free(crt);
1292 0 : return MBEDTLS_ERR_X509_SIG_MISMATCH;
1293 : }
1294 :
1295 12810 : if ((ret = mbedtls_x509_get_sig(&p, end, &crt->sig)) != 0) {
1296 0 : mbedtls_x509_crt_free(crt);
1297 0 : return ret;
1298 : }
1299 :
1300 12810 : if (p != end) {
1301 0 : mbedtls_x509_crt_free(crt);
1302 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
1303 : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1304 : }
1305 :
1306 12810 : return 0;
1307 : }
1308 :
1309 : /*
1310 : * Parse one X.509 certificate in DER format from a buffer and add them to a
1311 : * chained list
1312 : */
1313 12810 : static int mbedtls_x509_crt_parse_der_internal(mbedtls_x509_crt *chain,
1314 : const unsigned char *buf,
1315 : size_t buflen,
1316 : int make_copy,
1317 : mbedtls_x509_crt_ext_cb_t cb,
1318 : void *p_ctx)
1319 : {
1320 12810 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1321 12810 : mbedtls_x509_crt *crt = chain, *prev = NULL;
1322 :
1323 : /*
1324 : * Check for valid input
1325 : */
1326 12810 : if (crt == NULL || buf == NULL) {
1327 0 : return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1328 : }
1329 :
1330 12810 : while (crt->version != 0 && crt->next != NULL) {
1331 0 : prev = crt;
1332 0 : crt = crt->next;
1333 : }
1334 :
1335 : /*
1336 : * Add new certificate on the end of the chain if needed.
1337 : */
1338 12810 : if (crt->version != 0 && crt->next == NULL) {
1339 0 : crt->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
1340 :
1341 0 : if (crt->next == NULL) {
1342 0 : return MBEDTLS_ERR_X509_ALLOC_FAILED;
1343 : }
1344 :
1345 0 : prev = crt;
1346 0 : mbedtls_x509_crt_init(crt->next);
1347 0 : crt = crt->next;
1348 : }
1349 :
1350 12810 : ret = x509_crt_parse_der_core(crt, buf, buflen, make_copy, cb, p_ctx);
1351 12810 : if (ret != 0) {
1352 0 : if (prev) {
1353 0 : prev->next = NULL;
1354 : }
1355 :
1356 0 : if (crt != chain) {
1357 0 : mbedtls_free(crt);
1358 : }
1359 :
1360 0 : return ret;
1361 : }
1362 :
1363 12810 : return 0;
1364 : }
1365 :
1366 0 : int mbedtls_x509_crt_parse_der_nocopy(mbedtls_x509_crt *chain,
1367 : const unsigned char *buf,
1368 : size_t buflen)
1369 : {
1370 0 : return mbedtls_x509_crt_parse_der_internal(chain, buf, buflen, 0, NULL, NULL);
1371 : }
1372 :
1373 0 : int mbedtls_x509_crt_parse_der_with_ext_cb(mbedtls_x509_crt *chain,
1374 : const unsigned char *buf,
1375 : size_t buflen,
1376 : int make_copy,
1377 : mbedtls_x509_crt_ext_cb_t cb,
1378 : void *p_ctx)
1379 : {
1380 0 : return mbedtls_x509_crt_parse_der_internal(chain, buf, buflen, make_copy, cb, p_ctx);
1381 : }
1382 :
1383 12810 : int mbedtls_x509_crt_parse_der(mbedtls_x509_crt *chain,
1384 : const unsigned char *buf,
1385 : size_t buflen)
1386 : {
1387 12810 : return mbedtls_x509_crt_parse_der_internal(chain, buf, buflen, 1, NULL, NULL);
1388 : }
1389 :
1390 : /*
1391 : * Parse one or more PEM certificates from a buffer and add them to the chained
1392 : * list
1393 : */
1394 0 : int mbedtls_x509_crt_parse(mbedtls_x509_crt *chain,
1395 : const unsigned char *buf,
1396 : size_t buflen)
1397 : {
1398 : #if defined(MBEDTLS_PEM_PARSE_C)
1399 0 : int success = 0, first_error = 0, total_failed = 0;
1400 0 : int buf_format = MBEDTLS_X509_FORMAT_DER;
1401 : #endif
1402 :
1403 : /*
1404 : * Check for valid input
1405 : */
1406 0 : if (chain == NULL || buf == NULL) {
1407 0 : return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1408 : }
1409 :
1410 : /*
1411 : * Determine buffer content. Buffer contains either one DER certificate or
1412 : * one or more PEM certificates.
1413 : */
1414 : #if defined(MBEDTLS_PEM_PARSE_C)
1415 0 : if (buflen != 0 && buf[buflen - 1] == '\0' &&
1416 0 : strstr((const char *) buf, "-----BEGIN CERTIFICATE-----") != NULL) {
1417 0 : buf_format = MBEDTLS_X509_FORMAT_PEM;
1418 : }
1419 :
1420 0 : if (buf_format == MBEDTLS_X509_FORMAT_DER) {
1421 0 : return mbedtls_x509_crt_parse_der(chain, buf, buflen);
1422 : }
1423 : #else
1424 : return mbedtls_x509_crt_parse_der(chain, buf, buflen);
1425 : #endif
1426 :
1427 : #if defined(MBEDTLS_PEM_PARSE_C)
1428 0 : if (buf_format == MBEDTLS_X509_FORMAT_PEM) {
1429 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1430 : mbedtls_pem_context pem;
1431 :
1432 : /* 1 rather than 0 since the terminating NULL byte is counted in */
1433 0 : while (buflen > 1) {
1434 : size_t use_len;
1435 0 : mbedtls_pem_init(&pem);
1436 :
1437 : /* If we get there, we know the string is null-terminated */
1438 0 : ret = mbedtls_pem_read_buffer(&pem,
1439 : "-----BEGIN CERTIFICATE-----",
1440 : "-----END CERTIFICATE-----",
1441 : buf, NULL, 0, &use_len);
1442 :
1443 0 : if (ret == 0) {
1444 : /*
1445 : * Was PEM encoded
1446 : */
1447 0 : buflen -= use_len;
1448 0 : buf += use_len;
1449 0 : } else if (ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA) {
1450 0 : return ret;
1451 0 : } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
1452 0 : mbedtls_pem_free(&pem);
1453 :
1454 : /*
1455 : * PEM header and footer were found
1456 : */
1457 0 : buflen -= use_len;
1458 0 : buf += use_len;
1459 :
1460 0 : if (first_error == 0) {
1461 0 : first_error = ret;
1462 : }
1463 :
1464 0 : total_failed++;
1465 0 : continue;
1466 : } else {
1467 0 : break;
1468 : }
1469 :
1470 0 : ret = mbedtls_x509_crt_parse_der(chain, pem.buf, pem.buflen);
1471 :
1472 0 : mbedtls_pem_free(&pem);
1473 :
1474 0 : if (ret != 0) {
1475 : /*
1476 : * Quit parsing on a memory error
1477 : */
1478 0 : if (ret == MBEDTLS_ERR_X509_ALLOC_FAILED) {
1479 0 : return ret;
1480 : }
1481 :
1482 0 : if (first_error == 0) {
1483 0 : first_error = ret;
1484 : }
1485 :
1486 0 : total_failed++;
1487 0 : continue;
1488 : }
1489 :
1490 0 : success = 1;
1491 : }
1492 : }
1493 :
1494 0 : if (success) {
1495 0 : return total_failed;
1496 0 : } else if (first_error) {
1497 0 : return first_error;
1498 : } else {
1499 0 : return MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT;
1500 : }
1501 : #endif /* MBEDTLS_PEM_PARSE_C */
1502 : }
1503 :
1504 : #if defined(MBEDTLS_FS_IO)
1505 : /*
1506 : * Load one or more certificates and add them to the chained list
1507 : */
1508 : int mbedtls_x509_crt_parse_file(mbedtls_x509_crt *chain, const char *path)
1509 : {
1510 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1511 : size_t n;
1512 : unsigned char *buf;
1513 :
1514 : if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) {
1515 : return ret;
1516 : }
1517 :
1518 : ret = mbedtls_x509_crt_parse(chain, buf, n);
1519 :
1520 : mbedtls_zeroize_and_free(buf, n);
1521 :
1522 : return ret;
1523 : }
1524 :
1525 : int mbedtls_x509_crt_parse_path(mbedtls_x509_crt *chain, const char *path)
1526 : {
1527 : int ret = 0;
1528 : #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
1529 : int w_ret;
1530 : WCHAR szDir[MAX_PATH];
1531 : char filename[MAX_PATH];
1532 : char *p;
1533 : size_t len = strlen(path);
1534 :
1535 : WIN32_FIND_DATAW file_data;
1536 : HANDLE hFind;
1537 :
1538 : if (len > MAX_PATH - 3) {
1539 : return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1540 : }
1541 :
1542 : memset(szDir, 0, sizeof(szDir));
1543 : memset(filename, 0, MAX_PATH);
1544 : memcpy(filename, path, len);
1545 : filename[len++] = '\\';
1546 : p = filename + len;
1547 : filename[len++] = '*';
1548 :
1549 : /*
1550 : * Note this function uses the code page CP_ACP which is the system default
1551 : * ANSI codepage. The input string is always described in BYTES and the
1552 : * output length is described in WCHARs.
1553 : */
1554 : w_ret = MultiByteToWideChar(CP_ACP, 0, filename, (int) len, szDir,
1555 : MAX_PATH - 3);
1556 : if (w_ret == 0) {
1557 : return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1558 : }
1559 :
1560 : hFind = FindFirstFileW(szDir, &file_data);
1561 : if (hFind == INVALID_HANDLE_VALUE) {
1562 : return MBEDTLS_ERR_X509_FILE_IO_ERROR;
1563 : }
1564 :
1565 : len = MAX_PATH - len;
1566 : do {
1567 : memset(p, 0, len);
1568 :
1569 : if (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1570 : continue;
1571 : }
1572 : w_ret = WideCharToMultiByte(CP_ACP, 0, file_data.cFileName,
1573 : -1, p, (int) len, NULL, NULL);
1574 : if (w_ret == 0) {
1575 : ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
1576 : goto cleanup;
1577 : }
1578 :
1579 : w_ret = mbedtls_x509_crt_parse_file(chain, filename);
1580 : if (w_ret < 0) {
1581 : ret++;
1582 : } else {
1583 : ret += w_ret;
1584 : }
1585 : } while (FindNextFileW(hFind, &file_data) != 0);
1586 :
1587 : if (GetLastError() != ERROR_NO_MORE_FILES) {
1588 : ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
1589 : }
1590 :
1591 : cleanup:
1592 : FindClose(hFind);
1593 : #else /* _WIN32 */
1594 : int t_ret;
1595 : int snp_ret;
1596 : struct stat sb;
1597 : struct dirent *entry;
1598 : char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN];
1599 : DIR *dir = opendir(path);
1600 :
1601 : if (dir == NULL) {
1602 : return MBEDTLS_ERR_X509_FILE_IO_ERROR;
1603 : }
1604 :
1605 : #if defined(MBEDTLS_THREADING_C)
1606 : if ((ret = mbedtls_mutex_lock(&mbedtls_threading_readdir_mutex)) != 0) {
1607 : closedir(dir);
1608 : return ret;
1609 : }
1610 : #endif /* MBEDTLS_THREADING_C */
1611 :
1612 : memset(&sb, 0, sizeof(sb));
1613 :
1614 : while ((entry = readdir(dir)) != NULL) {
1615 : snp_ret = mbedtls_snprintf(entry_name, sizeof(entry_name),
1616 : "%s/%s", path, entry->d_name);
1617 :
1618 : if (snp_ret < 0 || (size_t) snp_ret >= sizeof(entry_name)) {
1619 : ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
1620 : goto cleanup;
1621 : } else if (stat(entry_name, &sb) == -1) {
1622 : if (errno == ENOENT) {
1623 : /* Broken symbolic link - ignore this entry.
1624 : stat(2) will return this error for either (a) a dangling
1625 : symlink or (b) a missing file.
1626 : Given that we have just obtained the filename from readdir,
1627 : assume that it does exist and therefore treat this as a
1628 : dangling symlink. */
1629 : continue;
1630 : } else {
1631 : /* Some other file error; report the error. */
1632 : ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
1633 : goto cleanup;
1634 : }
1635 : }
1636 :
1637 : if (!S_ISREG(sb.st_mode)) {
1638 : continue;
1639 : }
1640 :
1641 : // Ignore parse errors
1642 : //
1643 : t_ret = mbedtls_x509_crt_parse_file(chain, entry_name);
1644 : if (t_ret < 0) {
1645 : ret++;
1646 : } else {
1647 : ret += t_ret;
1648 : }
1649 : }
1650 :
1651 : cleanup:
1652 : closedir(dir);
1653 :
1654 : #if defined(MBEDTLS_THREADING_C)
1655 : if (mbedtls_mutex_unlock(&mbedtls_threading_readdir_mutex) != 0) {
1656 : ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
1657 : }
1658 : #endif /* MBEDTLS_THREADING_C */
1659 :
1660 : #endif /* _WIN32 */
1661 :
1662 : return ret;
1663 : }
1664 : #endif /* MBEDTLS_FS_IO */
1665 :
1666 : #if !defined(MBEDTLS_X509_REMOVE_INFO)
1667 : #define PRINT_ITEM(i) \
1668 : do { \
1669 : ret = mbedtls_snprintf(p, n, "%s" i, sep); \
1670 : MBEDTLS_X509_SAFE_SNPRINTF; \
1671 : sep = ", "; \
1672 : } while (0)
1673 :
1674 : #define CERT_TYPE(type, name) \
1675 : do { \
1676 : if (ns_cert_type & (type)) { \
1677 : PRINT_ITEM(name); \
1678 : } \
1679 : } while (0)
1680 :
1681 : #define KEY_USAGE(code, name) \
1682 : do { \
1683 : if (key_usage & (code)) { \
1684 : PRINT_ITEM(name); \
1685 : } \
1686 : } while (0)
1687 :
1688 0 : static int x509_info_ext_key_usage(char **buf, size_t *size,
1689 : const mbedtls_x509_sequence *extended_key_usage)
1690 : {
1691 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1692 : const char *desc;
1693 0 : size_t n = *size;
1694 0 : char *p = *buf;
1695 0 : const mbedtls_x509_sequence *cur = extended_key_usage;
1696 0 : const char *sep = "";
1697 :
1698 0 : while (cur != NULL) {
1699 0 : if (mbedtls_oid_get_extended_key_usage(&cur->buf, &desc) != 0) {
1700 0 : desc = "???";
1701 : }
1702 :
1703 0 : ret = mbedtls_snprintf(p, n, "%s%s", sep, desc);
1704 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1705 :
1706 0 : sep = ", ";
1707 :
1708 0 : cur = cur->next;
1709 : }
1710 :
1711 0 : *size = n;
1712 0 : *buf = p;
1713 :
1714 0 : return 0;
1715 : }
1716 :
1717 0 : static int x509_info_cert_policies(char **buf, size_t *size,
1718 : const mbedtls_x509_sequence *certificate_policies)
1719 : {
1720 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1721 : const char *desc;
1722 0 : size_t n = *size;
1723 0 : char *p = *buf;
1724 0 : const mbedtls_x509_sequence *cur = certificate_policies;
1725 0 : const char *sep = "";
1726 :
1727 0 : while (cur != NULL) {
1728 0 : if (mbedtls_oid_get_certificate_policies(&cur->buf, &desc) != 0) {
1729 0 : desc = "???";
1730 : }
1731 :
1732 0 : ret = mbedtls_snprintf(p, n, "%s%s", sep, desc);
1733 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1734 :
1735 0 : sep = ", ";
1736 :
1737 0 : cur = cur->next;
1738 : }
1739 :
1740 0 : *size = n;
1741 0 : *buf = p;
1742 :
1743 0 : return 0;
1744 : }
1745 :
1746 : /*
1747 : * Return an informational string about the certificate.
1748 : */
1749 : #define BEFORE_COLON 18
1750 : #define BC "18"
1751 0 : int mbedtls_x509_crt_info(char *buf, size_t size, const char *prefix,
1752 : const mbedtls_x509_crt *crt)
1753 : {
1754 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1755 : size_t n;
1756 : char *p;
1757 : char key_size_str[BEFORE_COLON];
1758 :
1759 0 : p = buf;
1760 0 : n = size;
1761 :
1762 0 : if (NULL == crt) {
1763 0 : ret = mbedtls_snprintf(p, n, "\nCertificate is uninitialised!\n");
1764 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1765 :
1766 0 : return (int) (size - n);
1767 : }
1768 :
1769 0 : ret = mbedtls_snprintf(p, n, "%scert. version : %d\n",
1770 0 : prefix, crt->version);
1771 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1772 0 : ret = mbedtls_snprintf(p, n, "%sserial number : ",
1773 : prefix);
1774 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1775 :
1776 0 : ret = mbedtls_x509_serial_gets(p, n, &crt->serial);
1777 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1778 :
1779 0 : ret = mbedtls_snprintf(p, n, "\n%sissuer name : ", prefix);
1780 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1781 0 : ret = mbedtls_x509_dn_gets(p, n, &crt->issuer);
1782 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1783 :
1784 0 : ret = mbedtls_snprintf(p, n, "\n%ssubject name : ", prefix);
1785 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1786 0 : ret = mbedtls_x509_dn_gets(p, n, &crt->subject);
1787 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1788 :
1789 0 : ret = mbedtls_snprintf(p, n, "\n%sissued on : " \
1790 : "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1791 0 : crt->valid_from.year, crt->valid_from.mon,
1792 0 : crt->valid_from.day, crt->valid_from.hour,
1793 0 : crt->valid_from.min, crt->valid_from.sec);
1794 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1795 :
1796 0 : ret = mbedtls_snprintf(p, n, "\n%sexpires on : " \
1797 : "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1798 0 : crt->valid_to.year, crt->valid_to.mon,
1799 0 : crt->valid_to.day, crt->valid_to.hour,
1800 0 : crt->valid_to.min, crt->valid_to.sec);
1801 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1802 :
1803 0 : ret = mbedtls_snprintf(p, n, "\n%ssigned using : ", prefix);
1804 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1805 :
1806 0 : ret = mbedtls_x509_sig_alg_gets(p, n, &crt->sig_oid, crt->sig_pk,
1807 0 : crt->sig_md, crt->sig_opts);
1808 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1809 :
1810 : /* Key size */
1811 0 : if ((ret = mbedtls_x509_key_size_helper(key_size_str, BEFORE_COLON,
1812 : mbedtls_pk_get_name(&crt->pk))) != 0) {
1813 0 : return ret;
1814 : }
1815 :
1816 0 : ret = mbedtls_snprintf(p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
1817 0 : (int) mbedtls_pk_get_bitlen(&crt->pk));
1818 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1819 :
1820 : /*
1821 : * Optional extensions
1822 : */
1823 :
1824 0 : if (crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS) {
1825 0 : ret = mbedtls_snprintf(p, n, "\n%sbasic constraints : CA=%s", prefix,
1826 0 : crt->ca_istrue ? "true" : "false");
1827 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1828 :
1829 0 : if (crt->max_pathlen > 0) {
1830 0 : ret = mbedtls_snprintf(p, n, ", max_pathlen=%d", crt->max_pathlen - 1);
1831 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1832 : }
1833 : }
1834 :
1835 0 : if (crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
1836 0 : ret = mbedtls_snprintf(p, n, "\n%ssubject alt name :", prefix);
1837 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1838 :
1839 0 : if ((ret = mbedtls_x509_info_subject_alt_name(&p, &n,
1840 : &crt->subject_alt_names,
1841 : prefix)) != 0) {
1842 0 : return ret;
1843 : }
1844 : }
1845 :
1846 0 : if (crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) {
1847 0 : ret = mbedtls_snprintf(p, n, "\n%scert. type : ", prefix);
1848 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1849 :
1850 0 : if ((ret = mbedtls_x509_info_cert_type(&p, &n, crt->ns_cert_type)) != 0) {
1851 0 : return ret;
1852 : }
1853 : }
1854 :
1855 0 : if (crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) {
1856 0 : ret = mbedtls_snprintf(p, n, "\n%skey usage : ", prefix);
1857 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1858 :
1859 0 : if ((ret = mbedtls_x509_info_key_usage(&p, &n, crt->key_usage)) != 0) {
1860 0 : return ret;
1861 : }
1862 : }
1863 :
1864 0 : if (crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE) {
1865 0 : ret = mbedtls_snprintf(p, n, "\n%sext key usage : ", prefix);
1866 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1867 :
1868 0 : if ((ret = x509_info_ext_key_usage(&p, &n,
1869 : &crt->ext_key_usage)) != 0) {
1870 0 : return ret;
1871 : }
1872 : }
1873 :
1874 0 : if (crt->ext_types & MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES) {
1875 0 : ret = mbedtls_snprintf(p, n, "\n%scertificate policies : ", prefix);
1876 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1877 :
1878 0 : if ((ret = x509_info_cert_policies(&p, &n,
1879 : &crt->certificate_policies)) != 0) {
1880 0 : return ret;
1881 : }
1882 : }
1883 :
1884 0 : ret = mbedtls_snprintf(p, n, "\n");
1885 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1886 :
1887 0 : return (int) (size - n);
1888 : }
1889 :
1890 : struct x509_crt_verify_string {
1891 : int code;
1892 : const char *string;
1893 : };
1894 :
1895 : #define X509_CRT_ERROR_INFO(err, err_str, info) { err, info },
1896 : static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
1897 : MBEDTLS_X509_CRT_ERROR_INFO_LIST
1898 : { 0, NULL }
1899 : };
1900 : #undef X509_CRT_ERROR_INFO
1901 :
1902 0 : int mbedtls_x509_crt_verify_info(char *buf, size_t size, const char *prefix,
1903 : uint32_t flags)
1904 : {
1905 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1906 : const struct x509_crt_verify_string *cur;
1907 0 : char *p = buf;
1908 0 : size_t n = size;
1909 :
1910 0 : for (cur = x509_crt_verify_strings; cur->string != NULL; cur++) {
1911 0 : if ((flags & cur->code) == 0) {
1912 0 : continue;
1913 : }
1914 :
1915 0 : ret = mbedtls_snprintf(p, n, "%s%s\n", prefix, cur->string);
1916 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1917 0 : flags ^= cur->code;
1918 : }
1919 :
1920 0 : if (flags != 0) {
1921 0 : ret = mbedtls_snprintf(p, n, "%sUnknown reason "
1922 : "(this should not happen)\n", prefix);
1923 0 : MBEDTLS_X509_SAFE_SNPRINTF;
1924 : }
1925 :
1926 0 : return (int) (size - n);
1927 : }
1928 : #endif /* MBEDTLS_X509_REMOVE_INFO */
1929 :
1930 1668 : int mbedtls_x509_crt_check_key_usage(const mbedtls_x509_crt *crt,
1931 : unsigned int usage)
1932 : {
1933 : unsigned int usage_must, usage_may;
1934 1668 : unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY
1935 : | MBEDTLS_X509_KU_DECIPHER_ONLY;
1936 :
1937 1668 : if ((crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) == 0) {
1938 744 : return 0;
1939 : }
1940 :
1941 924 : usage_must = usage & ~may_mask;
1942 :
1943 924 : if (((crt->key_usage & ~may_mask) & usage_must) != usage_must) {
1944 0 : return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1945 : }
1946 :
1947 924 : usage_may = usage & may_mask;
1948 :
1949 924 : if (((crt->key_usage & may_mask) | usage_may) != usage_may) {
1950 0 : return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1951 : }
1952 :
1953 924 : return 0;
1954 : }
1955 :
1956 0 : int mbedtls_x509_crt_check_extended_key_usage(const mbedtls_x509_crt *crt,
1957 : const char *usage_oid,
1958 : size_t usage_len)
1959 : {
1960 : const mbedtls_x509_sequence *cur;
1961 :
1962 : /* Extension is not mandatory, absent means no restriction */
1963 0 : if ((crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE) == 0) {
1964 0 : return 0;
1965 : }
1966 :
1967 : /*
1968 : * Look for the requested usage (or wildcard ANY) in our list
1969 : */
1970 0 : for (cur = &crt->ext_key_usage; cur != NULL; cur = cur->next) {
1971 0 : const mbedtls_x509_buf *cur_oid = &cur->buf;
1972 :
1973 0 : if (cur_oid->len == usage_len &&
1974 0 : memcmp(cur_oid->p, usage_oid, usage_len) == 0) {
1975 0 : return 0;
1976 : }
1977 :
1978 0 : if (MBEDTLS_OID_CMP(MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid) == 0) {
1979 0 : return 0;
1980 : }
1981 : }
1982 :
1983 0 : return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1984 : }
1985 :
1986 : #if defined(MBEDTLS_X509_CRL_PARSE_C)
1987 : /*
1988 : * Return 1 if the certificate is revoked, or 0 otherwise.
1989 : */
1990 0 : int mbedtls_x509_crt_is_revoked(const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl)
1991 : {
1992 0 : const mbedtls_x509_crl_entry *cur = &crl->entry;
1993 :
1994 0 : while (cur != NULL && cur->serial.len != 0) {
1995 0 : if (crt->serial.len == cur->serial.len &&
1996 0 : memcmp(crt->serial.p, cur->serial.p, crt->serial.len) == 0) {
1997 0 : return 1;
1998 : }
1999 :
2000 0 : cur = cur->next;
2001 : }
2002 :
2003 0 : return 0;
2004 : }
2005 :
2006 : /*
2007 : * Check that the given certificate is not revoked according to the CRL.
2008 : * Skip validation if no CRL for the given CA is present.
2009 : */
2010 1666 : static int x509_crt_verifycrl(mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
2011 : mbedtls_x509_crl *crl_list,
2012 : const mbedtls_x509_crt_profile *profile,
2013 : const mbedtls_x509_time *now)
2014 : {
2015 1666 : int flags = 0;
2016 : unsigned char hash[MBEDTLS_MD_MAX_SIZE];
2017 : #if defined(MBEDTLS_USE_PSA_CRYPTO)
2018 : psa_algorithm_t psa_algorithm;
2019 : #else
2020 : const mbedtls_md_info_t *md_info;
2021 : #endif /* MBEDTLS_USE_PSA_CRYPTO */
2022 : size_t hash_length;
2023 :
2024 1666 : if (ca == NULL) {
2025 0 : return flags;
2026 : }
2027 :
2028 1666 : while (crl_list != NULL) {
2029 0 : if (crl_list->version == 0 ||
2030 0 : x509_name_cmp(&crl_list->issuer, &ca->subject) != 0) {
2031 0 : crl_list = crl_list->next;
2032 0 : continue;
2033 : }
2034 :
2035 : /*
2036 : * Check if the CA is configured to sign CRLs
2037 : */
2038 0 : if (mbedtls_x509_crt_check_key_usage(ca,
2039 : MBEDTLS_X509_KU_CRL_SIGN) != 0) {
2040 0 : flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
2041 0 : break;
2042 : }
2043 :
2044 : /*
2045 : * Check if CRL is correctly signed by the trusted CA
2046 : */
2047 0 : if (x509_profile_check_md_alg(profile, crl_list->sig_md) != 0) {
2048 0 : flags |= MBEDTLS_X509_BADCRL_BAD_MD;
2049 : }
2050 :
2051 0 : if (x509_profile_check_pk_alg(profile, crl_list->sig_pk) != 0) {
2052 0 : flags |= MBEDTLS_X509_BADCRL_BAD_PK;
2053 : }
2054 :
2055 : #if defined(MBEDTLS_USE_PSA_CRYPTO)
2056 : psa_algorithm = mbedtls_md_psa_alg_from_type(crl_list->sig_md);
2057 : if (psa_hash_compute(psa_algorithm,
2058 : crl_list->tbs.p,
2059 : crl_list->tbs.len,
2060 : hash,
2061 : sizeof(hash),
2062 : &hash_length) != PSA_SUCCESS) {
2063 : /* Note: this can't happen except after an internal error */
2064 : flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
2065 : break;
2066 : }
2067 : #else
2068 0 : md_info = mbedtls_md_info_from_type(crl_list->sig_md);
2069 0 : hash_length = mbedtls_md_get_size(md_info);
2070 0 : if (mbedtls_md(md_info,
2071 0 : crl_list->tbs.p,
2072 : crl_list->tbs.len,
2073 : hash) != 0) {
2074 : /* Note: this can't happen except after an internal error */
2075 0 : flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
2076 0 : break;
2077 : }
2078 : #endif /* MBEDTLS_USE_PSA_CRYPTO */
2079 :
2080 0 : if (x509_profile_check_key(profile, &ca->pk) != 0) {
2081 0 : flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
2082 : }
2083 :
2084 0 : if (mbedtls_pk_verify_ext(crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
2085 : crl_list->sig_md, hash, hash_length,
2086 0 : crl_list->sig.p, crl_list->sig.len) != 0) {
2087 0 : flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
2088 0 : break;
2089 : }
2090 :
2091 : #if defined(MBEDTLS_HAVE_TIME_DATE)
2092 : /*
2093 : * Check for validity of CRL (Do not drop out)
2094 : */
2095 0 : if (mbedtls_x509_time_cmp(&crl_list->next_update, now) < 0) {
2096 0 : flags |= MBEDTLS_X509_BADCRL_EXPIRED;
2097 : }
2098 :
2099 0 : if (mbedtls_x509_time_cmp(&crl_list->this_update, now) > 0) {
2100 0 : flags |= MBEDTLS_X509_BADCRL_FUTURE;
2101 : }
2102 : #else
2103 : ((void) now);
2104 : #endif
2105 :
2106 : /*
2107 : * Check if certificate is revoked
2108 : */
2109 0 : if (mbedtls_x509_crt_is_revoked(crt, crl_list)) {
2110 0 : flags |= MBEDTLS_X509_BADCERT_REVOKED;
2111 0 : break;
2112 : }
2113 :
2114 0 : crl_list = crl_list->next;
2115 : }
2116 :
2117 1666 : return flags;
2118 : }
2119 : #endif /* MBEDTLS_X509_CRL_PARSE_C */
2120 :
2121 : /*
2122 : * Check the signature of a certificate by its parent
2123 : */
2124 1668 : static int x509_crt_check_signature(const mbedtls_x509_crt *child,
2125 : mbedtls_x509_crt *parent,
2126 : mbedtls_x509_crt_restart_ctx *rs_ctx)
2127 : {
2128 : size_t hash_len;
2129 : unsigned char hash[MBEDTLS_MD_MAX_SIZE];
2130 : #if !defined(MBEDTLS_USE_PSA_CRYPTO)
2131 : const mbedtls_md_info_t *md_info;
2132 1668 : md_info = mbedtls_md_info_from_type(child->sig_md);
2133 1668 : hash_len = mbedtls_md_get_size(md_info);
2134 :
2135 : /* Note: hash errors can happen only after an internal error */
2136 1668 : if (mbedtls_md(md_info, child->tbs.p, child->tbs.len, hash) != 0) {
2137 0 : return -1;
2138 : }
2139 : #else
2140 : psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(child->sig_md);
2141 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2142 :
2143 : status = psa_hash_compute(hash_alg,
2144 : child->tbs.p,
2145 : child->tbs.len,
2146 : hash,
2147 : sizeof(hash),
2148 : &hash_len);
2149 : if (status != PSA_SUCCESS) {
2150 : return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
2151 : }
2152 :
2153 : #endif /* MBEDTLS_USE_PSA_CRYPTO */
2154 : /* Skip expensive computation on obvious mismatch */
2155 1668 : if (!mbedtls_pk_can_do(&parent->pk, child->sig_pk)) {
2156 0 : return -1;
2157 : }
2158 :
2159 : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2160 1668 : if (rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA) {
2161 0 : return mbedtls_pk_verify_restartable(&parent->pk,
2162 0 : child->sig_md, hash, hash_len,
2163 0 : child->sig.p, child->sig.len, &rs_ctx->pk);
2164 : }
2165 : #else
2166 : (void) rs_ctx;
2167 : #endif
2168 :
2169 1668 : return mbedtls_pk_verify_ext(child->sig_pk, child->sig_opts, &parent->pk,
2170 1668 : child->sig_md, hash, hash_len,
2171 1668 : child->sig.p, child->sig.len);
2172 : }
2173 :
2174 : /*
2175 : * Check if 'parent' is a suitable parent (signing CA) for 'child'.
2176 : * Return 0 if yes, -1 if not.
2177 : *
2178 : * top means parent is a locally-trusted certificate
2179 : */
2180 1668 : static int x509_crt_check_parent(const mbedtls_x509_crt *child,
2181 : const mbedtls_x509_crt *parent,
2182 : int top)
2183 : {
2184 : int need_ca_bit;
2185 :
2186 : /* Parent must be the issuer */
2187 1668 : if (x509_name_cmp(&child->issuer, &parent->subject) != 0) {
2188 0 : return -1;
2189 : }
2190 :
2191 : /* Parent must have the basicConstraints CA bit set as a general rule */
2192 1668 : need_ca_bit = 1;
2193 :
2194 : /* Exception: v1/v2 certificates that are locally trusted. */
2195 1668 : if (top && parent->version < 3) {
2196 0 : need_ca_bit = 0;
2197 : }
2198 :
2199 1668 : if (need_ca_bit && !parent->ca_istrue) {
2200 0 : return -1;
2201 : }
2202 :
2203 3336 : if (need_ca_bit &&
2204 1668 : mbedtls_x509_crt_check_key_usage(parent, MBEDTLS_X509_KU_KEY_CERT_SIGN) != 0) {
2205 0 : return -1;
2206 : }
2207 :
2208 1668 : return 0;
2209 : }
2210 :
2211 : /*
2212 : * Find a suitable parent for child in candidates, or return NULL.
2213 : *
2214 : * Here suitable is defined as:
2215 : * 1. subject name matches child's issuer
2216 : * 2. if necessary, the CA bit is set and key usage allows signing certs
2217 : * 3. for trusted roots, the signature is correct
2218 : * (for intermediates, the signature is checked and the result reported)
2219 : * 4. pathlen constraints are satisfied
2220 : *
2221 : * If there's a suitable candidate which is also time-valid, return the first
2222 : * such. Otherwise, return the first suitable candidate (or NULL if there is
2223 : * none).
2224 : *
2225 : * The rationale for this rule is that someone could have a list of trusted
2226 : * roots with two versions on the same root with different validity periods.
2227 : * (At least one user reported having such a list and wanted it to just work.)
2228 : * The reason we don't just require time-validity is that generally there is
2229 : * only one version, and if it's expired we want the flags to state that
2230 : * rather than NOT_TRUSTED, as would be the case if we required it here.
2231 : *
2232 : * The rationale for rule 3 (signature for trusted roots) is that users might
2233 : * have two versions of the same CA with different keys in their list, and the
2234 : * way we select the correct one is by checking the signature (as we don't
2235 : * rely on key identifier extensions). (This is one way users might choose to
2236 : * handle key rollover, another relies on self-issued certs, see [SIRO].)
2237 : *
2238 : * Arguments:
2239 : * - [in] child: certificate for which we're looking for a parent
2240 : * - [in] candidates: chained list of potential parents
2241 : * - [out] r_parent: parent found (or NULL)
2242 : * - [out] r_signature_is_good: 1 if child signature by parent is valid, or 0
2243 : * - [in] top: 1 if candidates consists of trusted roots, ie we're at the top
2244 : * of the chain, 0 otherwise
2245 : * - [in] path_cnt: number of intermediates seen so far
2246 : * - [in] self_cnt: number of self-signed intermediates seen so far
2247 : * (will never be greater than path_cnt)
2248 : * - [in-out] rs_ctx: context for restarting operations
2249 : *
2250 : * Return value:
2251 : * - 0 on success
2252 : * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise
2253 : */
2254 1670 : static int x509_crt_find_parent_in(
2255 : mbedtls_x509_crt *child,
2256 : mbedtls_x509_crt *candidates,
2257 : mbedtls_x509_crt **r_parent,
2258 : int *r_signature_is_good,
2259 : int top,
2260 : unsigned path_cnt,
2261 : unsigned self_cnt,
2262 : mbedtls_x509_crt_restart_ctx *rs_ctx,
2263 : const mbedtls_x509_time *now)
2264 : {
2265 1670 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2266 : mbedtls_x509_crt *parent, *fallback_parent;
2267 1670 : int signature_is_good = 0, fallback_signature_is_good;
2268 :
2269 : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2270 : /* did we have something in progress? */
2271 1670 : if (rs_ctx != NULL && rs_ctx->parent != NULL) {
2272 : /* restore saved state */
2273 0 : parent = rs_ctx->parent;
2274 0 : fallback_parent = rs_ctx->fallback_parent;
2275 0 : fallback_signature_is_good = rs_ctx->fallback_signature_is_good;
2276 :
2277 : /* clear saved state */
2278 0 : rs_ctx->parent = NULL;
2279 0 : rs_ctx->fallback_parent = NULL;
2280 0 : rs_ctx->fallback_signature_is_good = 0;
2281 :
2282 : /* resume where we left */
2283 0 : goto check_signature;
2284 : }
2285 : #endif
2286 :
2287 1670 : fallback_parent = NULL;
2288 1670 : fallback_signature_is_good = 0;
2289 :
2290 1673 : for (parent = candidates; parent != NULL; parent = parent->next) {
2291 : /* basic parenting skills (name, CA bit, key usage) */
2292 1668 : if (x509_crt_check_parent(child, parent, top) != 0) {
2293 0 : continue;
2294 : }
2295 :
2296 : /* +1 because stored max_pathlen is 1 higher that the actual value */
2297 1668 : if (parent->max_pathlen > 0 &&
2298 0 : (size_t) parent->max_pathlen < 1 + path_cnt - self_cnt) {
2299 0 : continue;
2300 : }
2301 :
2302 : /* Signature */
2303 : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2304 1668 : check_signature:
2305 : #endif
2306 1668 : ret = x509_crt_check_signature(child, parent, rs_ctx);
2307 :
2308 : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2309 1668 : if (rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2310 : /* save state */
2311 0 : rs_ctx->parent = parent;
2312 0 : rs_ctx->fallback_parent = fallback_parent;
2313 0 : rs_ctx->fallback_signature_is_good = fallback_signature_is_good;
2314 :
2315 0 : return ret;
2316 : }
2317 : #else
2318 : (void) ret;
2319 : #endif
2320 :
2321 1668 : signature_is_good = ret == 0;
2322 1668 : if (top && !signature_is_good) {
2323 2 : continue;
2324 : }
2325 :
2326 : #if defined(MBEDTLS_HAVE_TIME_DATE)
2327 : /* optional time check */
2328 3331 : if (mbedtls_x509_time_cmp(&parent->valid_to, now) < 0 || /* past */
2329 1665 : mbedtls_x509_time_cmp(&parent->valid_from, now) > 0) { /* future */
2330 1 : if (fallback_parent == NULL) {
2331 1 : fallback_parent = parent;
2332 1 : fallback_signature_is_good = signature_is_good;
2333 : }
2334 :
2335 1 : continue;
2336 : }
2337 : #else
2338 : ((void) now);
2339 : #endif
2340 :
2341 1665 : *r_parent = parent;
2342 1665 : *r_signature_is_good = signature_is_good;
2343 :
2344 1665 : break;
2345 : }
2346 :
2347 1670 : if (parent == NULL) {
2348 5 : *r_parent = fallback_parent;
2349 5 : *r_signature_is_good = fallback_signature_is_good;
2350 : }
2351 :
2352 1670 : return 0;
2353 : }
2354 :
2355 : /*
2356 : * Find a parent in trusted CAs or the provided chain, or return NULL.
2357 : *
2358 : * Searches in trusted CAs first, and return the first suitable parent found
2359 : * (see find_parent_in() for definition of suitable).
2360 : *
2361 : * Arguments:
2362 : * - [in] child: certificate for which we're looking for a parent, followed
2363 : * by a chain of possible intermediates
2364 : * - [in] trust_ca: list of locally trusted certificates
2365 : * - [out] parent: parent found (or NULL)
2366 : * - [out] parent_is_trusted: 1 if returned `parent` is trusted, or 0
2367 : * - [out] signature_is_good: 1 if child signature by parent is valid, or 0
2368 : * - [in] path_cnt: number of links in the chain so far (EE -> ... -> child)
2369 : * - [in] self_cnt: number of self-signed certs in the chain so far
2370 : * (will always be no greater than path_cnt)
2371 : * - [in-out] rs_ctx: context for restarting operations
2372 : *
2373 : * Return value:
2374 : * - 0 on success
2375 : * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise
2376 : */
2377 1668 : static int x509_crt_find_parent(
2378 : mbedtls_x509_crt *child,
2379 : mbedtls_x509_crt *trust_ca,
2380 : mbedtls_x509_crt **parent,
2381 : int *parent_is_trusted,
2382 : int *signature_is_good,
2383 : unsigned path_cnt,
2384 : unsigned self_cnt,
2385 : mbedtls_x509_crt_restart_ctx *rs_ctx,
2386 : const mbedtls_x509_time *now)
2387 : {
2388 1668 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2389 : mbedtls_x509_crt *search_list;
2390 :
2391 1668 : *parent_is_trusted = 1;
2392 :
2393 : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2394 : /* restore then clear saved state if we have some stored */
2395 1668 : if (rs_ctx != NULL && rs_ctx->parent_is_trusted != -1) {
2396 0 : *parent_is_trusted = rs_ctx->parent_is_trusted;
2397 0 : rs_ctx->parent_is_trusted = -1;
2398 : }
2399 : #endif
2400 :
2401 : while (1) {
2402 1670 : search_list = *parent_is_trusted ? trust_ca : child->next;
2403 :
2404 1670 : ret = x509_crt_find_parent_in(child, search_list,
2405 : parent, signature_is_good,
2406 : *parent_is_trusted,
2407 : path_cnt, self_cnt, rs_ctx, now);
2408 :
2409 : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2410 1670 : if (rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2411 : /* save state */
2412 0 : rs_ctx->parent_is_trusted = *parent_is_trusted;
2413 0 : return ret;
2414 : }
2415 : #else
2416 : (void) ret;
2417 : #endif
2418 :
2419 : /* stop here if found or already in second iteration */
2420 1670 : if (*parent != NULL || *parent_is_trusted == 0) {
2421 : break;
2422 : }
2423 :
2424 : /* prepare second iteration */
2425 2 : *parent_is_trusted = 0;
2426 : }
2427 :
2428 : /* extra precaution against mistakes in the caller */
2429 1668 : if (*parent == NULL) {
2430 2 : *parent_is_trusted = 0;
2431 2 : *signature_is_good = 0;
2432 : }
2433 :
2434 1668 : return 0;
2435 : }
2436 :
2437 : /*
2438 : * Check if an end-entity certificate is locally trusted
2439 : *
2440 : * Currently we require such certificates to be self-signed (actually only
2441 : * check for self-issued as self-signatures are not checked)
2442 : */
2443 2375 : static int x509_crt_check_ee_locally_trusted(
2444 : mbedtls_x509_crt *crt,
2445 : mbedtls_x509_crt *trust_ca)
2446 : {
2447 : mbedtls_x509_crt *cur;
2448 :
2449 : /* must be self-issued */
2450 2375 : if (x509_name_cmp(&crt->issuer, &crt->subject) != 0) {
2451 1668 : return -1;
2452 : }
2453 :
2454 : /* look for an exact match with trusted cert */
2455 707 : for (cur = trust_ca; cur != NULL; cur = cur->next) {
2456 707 : if (crt->raw.len == cur->raw.len &&
2457 707 : memcmp(crt->raw.p, cur->raw.p, crt->raw.len) == 0) {
2458 707 : return 0;
2459 : }
2460 : }
2461 :
2462 : /* too bad */
2463 0 : return -1;
2464 : }
2465 :
2466 : /*
2467 : * Build and verify a certificate chain
2468 : *
2469 : * Given a peer-provided list of certificates EE, C1, ..., Cn and
2470 : * a list of trusted certs R1, ... Rp, try to build and verify a chain
2471 : * EE, Ci1, ... Ciq [, Rj]
2472 : * such that every cert in the chain is a child of the next one,
2473 : * jumping to a trusted root as early as possible.
2474 : *
2475 : * Verify that chain and return it with flags for all issues found.
2476 : *
2477 : * Special cases:
2478 : * - EE == Rj -> return a one-element list containing it
2479 : * - EE, Ci1, ..., Ciq cannot be continued with a trusted root
2480 : * -> return that chain with NOT_TRUSTED set on Ciq
2481 : *
2482 : * Tests for (aspects of) this function should include at least:
2483 : * - trusted EE
2484 : * - EE -> trusted root
2485 : * - EE -> intermediate CA -> trusted root
2486 : * - if relevant: EE untrusted
2487 : * - if relevant: EE -> intermediate, untrusted
2488 : * with the aspect under test checked at each relevant level (EE, int, root).
2489 : * For some aspects longer chains are required, but usually length 2 is
2490 : * enough (but length 1 is not in general).
2491 : *
2492 : * Arguments:
2493 : * - [in] crt: the cert list EE, C1, ..., Cn
2494 : * - [in] trust_ca: the trusted list R1, ..., Rp
2495 : * - [in] ca_crl, profile: as in verify_with_profile()
2496 : * - [out] ver_chain: the built and verified chain
2497 : * Only valid when return value is 0, may contain garbage otherwise!
2498 : * Restart note: need not be the same when calling again to resume.
2499 : * - [in-out] rs_ctx: context for restarting operations
2500 : *
2501 : * Return value:
2502 : * - non-zero if the chain could not be fully built and examined
2503 : * - 0 is the chain was successfully built and examined,
2504 : * even if it was found to be invalid
2505 : */
2506 2375 : static int x509_crt_verify_chain(
2507 : mbedtls_x509_crt *crt,
2508 : mbedtls_x509_crt *trust_ca,
2509 : mbedtls_x509_crl *ca_crl,
2510 : mbedtls_x509_crt_ca_cb_t f_ca_cb,
2511 : void *p_ca_cb,
2512 : const mbedtls_x509_crt_profile *profile,
2513 : mbedtls_x509_crt_verify_chain *ver_chain,
2514 : mbedtls_x509_crt_restart_ctx *rs_ctx)
2515 : {
2516 : /* Don't initialize any of those variables here, so that the compiler can
2517 : * catch potential issues with jumping ahead when restarting */
2518 2375 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2519 : uint32_t *flags;
2520 : mbedtls_x509_crt_verify_chain_item *cur;
2521 : mbedtls_x509_crt *child;
2522 : mbedtls_x509_crt *parent;
2523 : int parent_is_trusted;
2524 : int child_is_trusted;
2525 : int signature_is_good;
2526 : unsigned self_cnt;
2527 2375 : mbedtls_x509_crt *cur_trust_ca = NULL;
2528 : mbedtls_x509_time now;
2529 :
2530 : #if defined(MBEDTLS_HAVE_TIME_DATE)
2531 2375 : if (mbedtls_x509_time_gmtime(mbedtls_time(NULL), &now) != 0) {
2532 0 : return MBEDTLS_ERR_X509_FATAL_ERROR;
2533 : }
2534 : #endif
2535 :
2536 : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2537 : /* resume if we had an operation in progress */
2538 2375 : if (rs_ctx != NULL && rs_ctx->in_progress == x509_crt_rs_find_parent) {
2539 : /* restore saved state */
2540 0 : *ver_chain = rs_ctx->ver_chain; /* struct copy */
2541 0 : self_cnt = rs_ctx->self_cnt;
2542 :
2543 : /* restore derived state */
2544 0 : cur = &ver_chain->items[ver_chain->len - 1];
2545 0 : child = cur->crt;
2546 0 : flags = &cur->flags;
2547 :
2548 0 : goto find_parent;
2549 : }
2550 : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
2551 :
2552 2375 : child = crt;
2553 2375 : self_cnt = 0;
2554 2375 : parent_is_trusted = 0;
2555 2375 : child_is_trusted = 0;
2556 :
2557 : while (1) {
2558 : /* Add certificate to the verification chain */
2559 4041 : cur = &ver_chain->items[ver_chain->len];
2560 4041 : cur->crt = child;
2561 4041 : cur->flags = 0;
2562 4041 : ver_chain->len++;
2563 4041 : flags = &cur->flags;
2564 :
2565 : #if defined(MBEDTLS_HAVE_TIME_DATE)
2566 : /* Check time-validity (all certificates) */
2567 4041 : if (mbedtls_x509_time_cmp(&child->valid_to, &now) < 0) {
2568 2 : *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
2569 : }
2570 :
2571 4041 : if (mbedtls_x509_time_cmp(&child->valid_from, &now) > 0) {
2572 0 : *flags |= MBEDTLS_X509_BADCERT_FUTURE;
2573 : }
2574 : #endif
2575 :
2576 : /* Stop here for trusted roots (but not for trusted EE certs) */
2577 4041 : if (child_is_trusted) {
2578 1666 : return 0;
2579 : }
2580 :
2581 : /* Check signature algorithm: MD & PK algs */
2582 2375 : if (x509_profile_check_md_alg(profile, child->sig_md) != 0) {
2583 0 : *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
2584 : }
2585 :
2586 2375 : if (x509_profile_check_pk_alg(profile, child->sig_pk) != 0) {
2587 0 : *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
2588 : }
2589 :
2590 : /* Special case: EE certs that are locally trusted */
2591 4750 : if (ver_chain->len == 1 &&
2592 2375 : x509_crt_check_ee_locally_trusted(child, trust_ca) == 0) {
2593 707 : return 0;
2594 : }
2595 :
2596 : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2597 1668 : find_parent:
2598 : #endif
2599 :
2600 : /* Obtain list of potential trusted signers from CA callback,
2601 : * or use statically provided list. */
2602 : #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
2603 : if (f_ca_cb != NULL) {
2604 : mbedtls_x509_crt_free(ver_chain->trust_ca_cb_result);
2605 : mbedtls_free(ver_chain->trust_ca_cb_result);
2606 : ver_chain->trust_ca_cb_result = NULL;
2607 :
2608 : ret = f_ca_cb(p_ca_cb, child, &ver_chain->trust_ca_cb_result);
2609 : if (ret != 0) {
2610 : return MBEDTLS_ERR_X509_FATAL_ERROR;
2611 : }
2612 :
2613 : cur_trust_ca = ver_chain->trust_ca_cb_result;
2614 : } else
2615 : #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
2616 : {
2617 : ((void) f_ca_cb);
2618 : ((void) p_ca_cb);
2619 1668 : cur_trust_ca = trust_ca;
2620 : }
2621 :
2622 : /* Look for a parent in trusted CAs or up the chain */
2623 1668 : ret = x509_crt_find_parent(child, cur_trust_ca, &parent,
2624 : &parent_is_trusted, &signature_is_good,
2625 1668 : ver_chain->len - 1, self_cnt, rs_ctx,
2626 : &now);
2627 :
2628 : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2629 1668 : if (rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2630 : /* save state */
2631 0 : rs_ctx->in_progress = x509_crt_rs_find_parent;
2632 0 : rs_ctx->self_cnt = self_cnt;
2633 0 : rs_ctx->ver_chain = *ver_chain; /* struct copy */
2634 :
2635 0 : return ret;
2636 : }
2637 : #else
2638 : (void) ret;
2639 : #endif
2640 :
2641 : /* No parent? We're done here */
2642 1668 : if (parent == NULL) {
2643 2 : *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
2644 2 : return 0;
2645 : }
2646 :
2647 : /* Count intermediate self-issued (not necessarily self-signed) certs.
2648 : * These can occur with some strategies for key rollover, see [SIRO],
2649 : * and should be excluded from max_pathlen checks. */
2650 1666 : if (ver_chain->len != 1 &&
2651 0 : x509_name_cmp(&child->issuer, &child->subject) == 0) {
2652 0 : self_cnt++;
2653 : }
2654 :
2655 : /* path_cnt is 0 for the first intermediate CA,
2656 : * and if parent is trusted it's not an intermediate CA */
2657 1666 : if (!parent_is_trusted &&
2658 0 : ver_chain->len > MBEDTLS_X509_MAX_INTERMEDIATE_CA) {
2659 : /* return immediately to avoid overflow the chain array */
2660 0 : return MBEDTLS_ERR_X509_FATAL_ERROR;
2661 : }
2662 :
2663 : /* signature was checked while searching parent */
2664 1666 : if (!signature_is_good) {
2665 0 : *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
2666 : }
2667 :
2668 : /* check size of signing key */
2669 1666 : if (x509_profile_check_key(profile, &parent->pk) != 0) {
2670 0 : *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
2671 : }
2672 :
2673 : #if defined(MBEDTLS_X509_CRL_PARSE_C)
2674 : /* Check trusted CA's CRL for the given crt */
2675 1666 : *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile, &now);
2676 : #else
2677 : (void) ca_crl;
2678 : #endif
2679 :
2680 : /* prepare for next iteration */
2681 1666 : child = parent;
2682 1666 : parent = NULL;
2683 1666 : child_is_trusted = parent_is_trusted;
2684 1666 : signature_is_good = 0;
2685 : }
2686 : }
2687 :
2688 : #ifdef _WIN32
2689 : #ifdef _MSC_VER
2690 : #pragma comment(lib, "ws2_32.lib")
2691 : #include <winsock2.h>
2692 : #include <ws2tcpip.h>
2693 : #elif (defined(__MINGW32__) || defined(__MINGW64__)) && _WIN32_WINNT >= 0x0600
2694 : #include <winsock2.h>
2695 : #include <ws2tcpip.h>
2696 : #else
2697 : /* inet_pton() is not supported, fallback to software version */
2698 : #define MBEDTLS_TEST_SW_INET_PTON
2699 : #endif
2700 : #elif defined(__sun)
2701 : /* Solaris requires -lsocket -lnsl for inet_pton() */
2702 : #elif defined(__has_include)
2703 : #if __has_include(<sys/socket.h>)
2704 : #include <sys/socket.h>
2705 : #endif
2706 : #if __has_include(<arpa/inet.h>)
2707 : #include <arpa/inet.h>
2708 : #endif
2709 : #endif
2710 :
2711 : /* Use whether or not AF_INET6 is defined to indicate whether or not to use
2712 : * the platform inet_pton() or a local implementation (below). The local
2713 : * implementation may be used even in cases where the platform provides
2714 : * inet_pton(), e.g. when there are different includes required and/or the
2715 : * platform implementation requires dependencies on additional libraries.
2716 : * Specifically, Windows requires custom includes and additional link
2717 : * dependencies, and Solaris requires additional link dependencies.
2718 : * Also, as a coarse heuristic, use the local implementation if the compiler
2719 : * does not support __has_include(), or if the definition of AF_INET6 is not
2720 : * provided by headers included (or not) via __has_include() above.
2721 : * MBEDTLS_TEST_SW_INET_PTON is a bypass define to force testing of this code //no-check-names
2722 : * despite having a platform that has inet_pton. */
2723 : #if !defined(AF_INET6) || defined(MBEDTLS_TEST_SW_INET_PTON) //no-check-names
2724 : /* Definition located further below to possibly reduce compiler inlining */
2725 : static int x509_inet_pton_ipv4(const char *src, void *dst);
2726 :
2727 : #define li_cton(c, n) \
2728 : (((n) = (c) - '0') <= 9 || (((n) = ((c)&0xdf) - 'A') <= 5 ? ((n) += 10) : 0))
2729 :
2730 : static int x509_inet_pton_ipv6(const char *src, void *dst)
2731 : {
2732 : const unsigned char *p = (const unsigned char *) src;
2733 : int nonzero_groups = 0, num_digits, zero_group_start = -1;
2734 : uint16_t addr[8];
2735 : do {
2736 : /* note: allows excess leading 0's, e.g. 1:0002:3:... */
2737 : uint16_t group = num_digits = 0;
2738 : for (uint8_t digit; num_digits < 4; num_digits++) {
2739 : if (li_cton(*p, digit) == 0) {
2740 : break;
2741 : }
2742 : group = (group << 4) | digit;
2743 : p++;
2744 : }
2745 : if (num_digits != 0) {
2746 : MBEDTLS_PUT_UINT16_BE(group, addr, nonzero_groups);
2747 : nonzero_groups++;
2748 : if (*p == '\0') {
2749 : break;
2750 : } else if (*p == '.') {
2751 : /* Don't accept IPv4 too early or late */
2752 : if ((nonzero_groups == 0 && zero_group_start == -1) ||
2753 : nonzero_groups >= 7) {
2754 : break;
2755 : }
2756 :
2757 : /* Walk back to prior ':', then parse as IPv4-mapped */
2758 : int steps = 4;
2759 : do {
2760 : p--;
2761 : steps--;
2762 : } while (*p != ':' && steps > 0);
2763 :
2764 : if (*p != ':') {
2765 : break;
2766 : }
2767 : p++;
2768 : nonzero_groups--;
2769 : if (x509_inet_pton_ipv4((const char *) p,
2770 : addr + nonzero_groups) != 0) {
2771 : break;
2772 : }
2773 :
2774 : nonzero_groups += 2;
2775 : p = (const unsigned char *) "";
2776 : break;
2777 : } else if (*p != ':') {
2778 : return -1;
2779 : }
2780 : } else {
2781 : /* Don't accept a second zero group or an invalid delimiter */
2782 : if (zero_group_start != -1 || *p != ':') {
2783 : return -1;
2784 : }
2785 : zero_group_start = nonzero_groups;
2786 :
2787 : /* Accept a zero group at start, but it has to be a double colon */
2788 : if (zero_group_start == 0 && *++p != ':') {
2789 : return -1;
2790 : }
2791 :
2792 : if (p[1] == '\0') {
2793 : ++p;
2794 : break;
2795 : }
2796 : }
2797 : ++p;
2798 : } while (nonzero_groups < 8);
2799 :
2800 : if (*p != '\0') {
2801 : return -1;
2802 : }
2803 :
2804 : if (zero_group_start != -1) {
2805 : if (nonzero_groups > 6) {
2806 : return -1;
2807 : }
2808 : int zero_groups = 8 - nonzero_groups;
2809 : int groups_after_zero = nonzero_groups - zero_group_start;
2810 :
2811 : /* Move the non-zero part to after the zeroes */
2812 : if (groups_after_zero) {
2813 : memmove(addr + zero_group_start + zero_groups,
2814 : addr + zero_group_start,
2815 : groups_after_zero * sizeof(*addr));
2816 : }
2817 : memset(addr + zero_group_start, 0, zero_groups * sizeof(*addr));
2818 : } else {
2819 : if (nonzero_groups != 8) {
2820 : return -1;
2821 : }
2822 : }
2823 : memcpy(dst, addr, sizeof(addr));
2824 : return 0;
2825 : }
2826 :
2827 : static int x509_inet_pton_ipv4(const char *src, void *dst)
2828 : {
2829 : const unsigned char *p = (const unsigned char *) src;
2830 : uint8_t *res = (uint8_t *) dst;
2831 : uint8_t digit, num_digits = 0;
2832 : uint8_t num_octets = 0;
2833 : uint16_t octet;
2834 :
2835 : do {
2836 : octet = num_digits = 0;
2837 : do {
2838 : digit = *p - '0';
2839 : if (digit > 9) {
2840 : break;
2841 : }
2842 :
2843 : /* Don't allow leading zeroes. These might mean octal format,
2844 : * which this implementation does not support. */
2845 : if (octet == 0 && num_digits > 0) {
2846 : return -1;
2847 : }
2848 :
2849 : octet = octet * 10 + digit;
2850 : num_digits++;
2851 : p++;
2852 : } while (num_digits < 3);
2853 :
2854 : if (octet >= 256 || num_digits > 3 || num_digits == 0) {
2855 : return -1;
2856 : }
2857 : *res++ = (uint8_t) octet;
2858 : num_octets++;
2859 : } while (num_octets < 4 && *p++ == '.');
2860 : return num_octets == 4 && *p == '\0' ? 0 : -1;
2861 : }
2862 :
2863 : #else
2864 :
2865 0 : static int x509_inet_pton_ipv6(const char *src, void *dst)
2866 : {
2867 0 : return inet_pton(AF_INET6, src, dst) == 1 ? 0 : -1;
2868 : }
2869 :
2870 0 : static int x509_inet_pton_ipv4(const char *src, void *dst)
2871 : {
2872 0 : return inet_pton(AF_INET, src, dst) == 1 ? 0 : -1;
2873 : }
2874 :
2875 : #endif /* !AF_INET6 || MBEDTLS_TEST_SW_INET_PTON */ //no-check-names
2876 :
2877 0 : size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst)
2878 : {
2879 0 : return strchr(cn, ':') == NULL
2880 0 : ? x509_inet_pton_ipv4(cn, dst) == 0 ? 4 : 0
2881 0 : : x509_inet_pton_ipv6(cn, dst) == 0 ? 16 : 0;
2882 : }
2883 :
2884 : /*
2885 : * Check for CN match
2886 : */
2887 0 : static int x509_crt_check_cn(const mbedtls_x509_buf *name,
2888 : const char *cn, size_t cn_len)
2889 : {
2890 : /* try exact match */
2891 0 : if (name->len == cn_len &&
2892 0 : x509_memcasecmp(cn, name->p, cn_len) == 0) {
2893 0 : return 0;
2894 : }
2895 :
2896 : /* try wildcard match */
2897 0 : if (x509_check_wildcard(cn, name) == 0) {
2898 0 : return 0;
2899 : }
2900 :
2901 0 : return -1;
2902 : }
2903 :
2904 0 : static int x509_crt_check_san_ip(const mbedtls_x509_sequence *san,
2905 : const char *cn, size_t cn_len)
2906 : {
2907 : uint32_t ip[4];
2908 0 : cn_len = mbedtls_x509_crt_parse_cn_inet_pton(cn, ip);
2909 0 : if (cn_len == 0) {
2910 0 : return -1;
2911 : }
2912 :
2913 0 : for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) {
2914 0 : const unsigned char san_type = (unsigned char) cur->buf.tag &
2915 : MBEDTLS_ASN1_TAG_VALUE_MASK;
2916 0 : if (san_type == MBEDTLS_X509_SAN_IP_ADDRESS &&
2917 0 : cur->buf.len == cn_len && memcmp(cur->buf.p, ip, cn_len) == 0) {
2918 0 : return 0;
2919 : }
2920 : }
2921 :
2922 0 : return -1;
2923 : }
2924 :
2925 0 : static int x509_crt_check_san_uri(const mbedtls_x509_sequence *san,
2926 : const char *cn, size_t cn_len)
2927 : {
2928 0 : for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) {
2929 0 : const unsigned char san_type = (unsigned char) cur->buf.tag &
2930 : MBEDTLS_ASN1_TAG_VALUE_MASK;
2931 0 : if (san_type == MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER &&
2932 0 : cur->buf.len == cn_len && memcmp(cur->buf.p, cn, cn_len) == 0) {
2933 0 : return 0;
2934 : }
2935 : }
2936 :
2937 0 : return -1;
2938 : }
2939 :
2940 : /*
2941 : * Check for SAN match, see RFC 5280 Section 4.2.1.6
2942 : */
2943 0 : static int x509_crt_check_san(const mbedtls_x509_sequence *san,
2944 : const char *cn, size_t cn_len)
2945 : {
2946 0 : int san_ip = 0;
2947 0 : int san_uri = 0;
2948 : /* Prioritize DNS name over other subtypes due to popularity */
2949 0 : for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) {
2950 0 : switch ((unsigned char) cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) {
2951 0 : case MBEDTLS_X509_SAN_DNS_NAME:
2952 0 : if (x509_crt_check_cn(&cur->buf, cn, cn_len) == 0) {
2953 0 : return 0;
2954 : }
2955 0 : break;
2956 0 : case MBEDTLS_X509_SAN_IP_ADDRESS:
2957 0 : san_ip = 1;
2958 0 : break;
2959 0 : case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
2960 0 : san_uri = 1;
2961 0 : break;
2962 : /* (We may handle other types here later.) */
2963 0 : default: /* Unrecognized type */
2964 0 : break;
2965 : }
2966 : }
2967 0 : if (san_ip) {
2968 0 : if (x509_crt_check_san_ip(san, cn, cn_len) == 0) {
2969 0 : return 0;
2970 : }
2971 : }
2972 0 : if (san_uri) {
2973 0 : if (x509_crt_check_san_uri(san, cn, cn_len) == 0) {
2974 0 : return 0;
2975 : }
2976 : }
2977 :
2978 0 : return -1;
2979 : }
2980 :
2981 : /*
2982 : * Verify the requested CN - only call this if cn is not NULL!
2983 : */
2984 0 : static void x509_crt_verify_name(const mbedtls_x509_crt *crt,
2985 : const char *cn,
2986 : uint32_t *flags)
2987 : {
2988 : const mbedtls_x509_name *name;
2989 0 : size_t cn_len = strlen(cn);
2990 :
2991 0 : if (crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
2992 0 : if (x509_crt_check_san(&crt->subject_alt_names, cn, cn_len) == 0) {
2993 0 : return;
2994 : }
2995 : } else {
2996 0 : for (name = &crt->subject; name != NULL; name = name->next) {
2997 0 : if (MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0 &&
2998 0 : x509_crt_check_cn(&name->val, cn, cn_len) == 0) {
2999 0 : return;
3000 : }
3001 : }
3002 :
3003 : }
3004 :
3005 0 : *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
3006 : }
3007 :
3008 : /*
3009 : * Merge the flags for all certs in the chain, after calling callback
3010 : */
3011 2375 : static int x509_crt_merge_flags_with_cb(
3012 : uint32_t *flags,
3013 : const mbedtls_x509_crt_verify_chain *ver_chain,
3014 : int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
3015 : void *p_vrfy)
3016 : {
3017 2375 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3018 : unsigned i;
3019 : uint32_t cur_flags;
3020 : const mbedtls_x509_crt_verify_chain_item *cur;
3021 :
3022 6416 : for (i = ver_chain->len; i != 0; --i) {
3023 4041 : cur = &ver_chain->items[i-1];
3024 4041 : cur_flags = cur->flags;
3025 :
3026 4041 : if (NULL != f_vrfy) {
3027 0 : if ((ret = f_vrfy(p_vrfy, cur->crt, (int) i-1, &cur_flags)) != 0) {
3028 0 : return ret;
3029 : }
3030 : }
3031 :
3032 4041 : *flags |= cur_flags;
3033 : }
3034 :
3035 2375 : return 0;
3036 : }
3037 :
3038 : /*
3039 : * Verify the certificate validity, with profile, restartable version
3040 : *
3041 : * This function:
3042 : * - checks the requested CN (if any)
3043 : * - checks the type and size of the EE cert's key,
3044 : * as that isn't done as part of chain building/verification currently
3045 : * - builds and verifies the chain
3046 : * - then calls the callback and merges the flags
3047 : *
3048 : * The parameters pairs `trust_ca`, `ca_crl` and `f_ca_cb`, `p_ca_cb`
3049 : * are mutually exclusive: If `f_ca_cb != NULL`, it will be used by the
3050 : * verification routine to search for trusted signers, and CRLs will
3051 : * be disabled. Otherwise, `trust_ca` will be used as the static list
3052 : * of trusted signers, and `ca_crl` will be use as the static list
3053 : * of CRLs.
3054 : */
3055 2375 : static int x509_crt_verify_restartable_ca_cb(mbedtls_x509_crt *crt,
3056 : mbedtls_x509_crt *trust_ca,
3057 : mbedtls_x509_crl *ca_crl,
3058 : mbedtls_x509_crt_ca_cb_t f_ca_cb,
3059 : void *p_ca_cb,
3060 : const mbedtls_x509_crt_profile *profile,
3061 : const char *cn, uint32_t *flags,
3062 : int (*f_vrfy)(void *,
3063 : mbedtls_x509_crt *,
3064 : int,
3065 : uint32_t *),
3066 : void *p_vrfy,
3067 : mbedtls_x509_crt_restart_ctx *rs_ctx)
3068 : {
3069 2375 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3070 : mbedtls_pk_type_t pk_type;
3071 : mbedtls_x509_crt_verify_chain ver_chain;
3072 : uint32_t ee_flags;
3073 :
3074 2375 : *flags = 0;
3075 2375 : ee_flags = 0;
3076 2375 : x509_crt_verify_chain_reset(&ver_chain);
3077 :
3078 2375 : if (profile == NULL) {
3079 0 : ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
3080 0 : goto exit;
3081 : }
3082 :
3083 : /* check name if requested */
3084 2375 : if (cn != NULL) {
3085 0 : x509_crt_verify_name(crt, cn, &ee_flags);
3086 : }
3087 :
3088 : /* Check the type and size of the key */
3089 2375 : pk_type = mbedtls_pk_get_type(&crt->pk);
3090 :
3091 2375 : if (x509_profile_check_pk_alg(profile, pk_type) != 0) {
3092 0 : ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK;
3093 : }
3094 :
3095 2375 : if (x509_profile_check_key(profile, &crt->pk) != 0) {
3096 0 : ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
3097 : }
3098 :
3099 : /* Check the chain */
3100 2375 : ret = x509_crt_verify_chain(crt, trust_ca, ca_crl,
3101 : f_ca_cb, p_ca_cb, profile,
3102 : &ver_chain, rs_ctx);
3103 :
3104 2375 : if (ret != 0) {
3105 0 : goto exit;
3106 : }
3107 :
3108 : /* Merge end-entity flags */
3109 2375 : ver_chain.items[0].flags |= ee_flags;
3110 :
3111 : /* Build final flags, calling callback on the way if any */
3112 2375 : ret = x509_crt_merge_flags_with_cb(flags, &ver_chain, f_vrfy, p_vrfy);
3113 :
3114 2375 : exit:
3115 :
3116 : #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
3117 : mbedtls_x509_crt_free(ver_chain.trust_ca_cb_result);
3118 : mbedtls_free(ver_chain.trust_ca_cb_result);
3119 : ver_chain.trust_ca_cb_result = NULL;
3120 : #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
3121 :
3122 : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
3123 2375 : if (rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
3124 0 : mbedtls_x509_crt_restart_free(rs_ctx);
3125 : }
3126 : #endif
3127 :
3128 : /* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by
3129 : * the SSL module for authmode optional, but non-zero return from the
3130 : * callback means a fatal error so it shouldn't be ignored */
3131 2375 : if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
3132 0 : ret = MBEDTLS_ERR_X509_FATAL_ERROR;
3133 : }
3134 :
3135 2375 : if (ret != 0) {
3136 0 : *flags = (uint32_t) -1;
3137 0 : return ret;
3138 : }
3139 :
3140 2375 : if (*flags != 0) {
3141 3 : return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
3142 : }
3143 :
3144 2372 : return 0;
3145 : }
3146 :
3147 :
3148 : /*
3149 : * Verify the certificate validity (default profile, not restartable)
3150 : */
3151 0 : int mbedtls_x509_crt_verify(mbedtls_x509_crt *crt,
3152 : mbedtls_x509_crt *trust_ca,
3153 : mbedtls_x509_crl *ca_crl,
3154 : const char *cn, uint32_t *flags,
3155 : int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
3156 : void *p_vrfy)
3157 : {
3158 0 : return x509_crt_verify_restartable_ca_cb(crt, trust_ca, ca_crl,
3159 : NULL, NULL,
3160 : &mbedtls_x509_crt_profile_default,
3161 : cn, flags,
3162 : f_vrfy, p_vrfy, NULL);
3163 : }
3164 :
3165 : /*
3166 : * Verify the certificate validity (user-chosen profile, not restartable)
3167 : */
3168 2375 : int mbedtls_x509_crt_verify_with_profile(mbedtls_x509_crt *crt,
3169 : mbedtls_x509_crt *trust_ca,
3170 : mbedtls_x509_crl *ca_crl,
3171 : const mbedtls_x509_crt_profile *profile,
3172 : const char *cn, uint32_t *flags,
3173 : int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
3174 : void *p_vrfy)
3175 : {
3176 2375 : return x509_crt_verify_restartable_ca_cb(crt, trust_ca, ca_crl,
3177 : NULL, NULL,
3178 : profile, cn, flags,
3179 : f_vrfy, p_vrfy, NULL);
3180 : }
3181 :
3182 : #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
3183 : /*
3184 : * Verify the certificate validity (user-chosen profile, CA callback,
3185 : * not restartable).
3186 : */
3187 : int mbedtls_x509_crt_verify_with_ca_cb(mbedtls_x509_crt *crt,
3188 : mbedtls_x509_crt_ca_cb_t f_ca_cb,
3189 : void *p_ca_cb,
3190 : const mbedtls_x509_crt_profile *profile,
3191 : const char *cn, uint32_t *flags,
3192 : int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
3193 : void *p_vrfy)
3194 : {
3195 : return x509_crt_verify_restartable_ca_cb(crt, NULL, NULL,
3196 : f_ca_cb, p_ca_cb,
3197 : profile, cn, flags,
3198 : f_vrfy, p_vrfy, NULL);
3199 : }
3200 : #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
3201 :
3202 0 : int mbedtls_x509_crt_verify_restartable(mbedtls_x509_crt *crt,
3203 : mbedtls_x509_crt *trust_ca,
3204 : mbedtls_x509_crl *ca_crl,
3205 : const mbedtls_x509_crt_profile *profile,
3206 : const char *cn, uint32_t *flags,
3207 : int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
3208 : void *p_vrfy,
3209 : mbedtls_x509_crt_restart_ctx *rs_ctx)
3210 : {
3211 0 : return x509_crt_verify_restartable_ca_cb(crt, trust_ca, ca_crl,
3212 : NULL, NULL,
3213 : profile, cn, flags,
3214 : f_vrfy, p_vrfy, rs_ctx);
3215 : }
3216 :
3217 :
3218 : /*
3219 : * Initialize a certificate chain
3220 : */
3221 12810 : void mbedtls_x509_crt_init(mbedtls_x509_crt *crt)
3222 : {
3223 12810 : memset(crt, 0, sizeof(mbedtls_x509_crt));
3224 12810 : }
3225 :
3226 : /*
3227 : * Unallocate all certificate data
3228 : */
3229 12804 : void mbedtls_x509_crt_free(mbedtls_x509_crt *crt)
3230 : {
3231 12804 : mbedtls_x509_crt *cert_cur = crt;
3232 : mbedtls_x509_crt *cert_prv;
3233 :
3234 25608 : while (cert_cur != NULL) {
3235 12804 : mbedtls_pk_free(&cert_cur->pk);
3236 :
3237 : #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
3238 12804 : mbedtls_free(cert_cur->sig_opts);
3239 : #endif
3240 :
3241 12804 : mbedtls_asn1_free_named_data_list_shallow(cert_cur->issuer.next);
3242 12804 : mbedtls_asn1_free_named_data_list_shallow(cert_cur->subject.next);
3243 12804 : mbedtls_asn1_sequence_free(cert_cur->ext_key_usage.next);
3244 12804 : mbedtls_asn1_sequence_free(cert_cur->subject_alt_names.next);
3245 12804 : mbedtls_asn1_sequence_free(cert_cur->certificate_policies.next);
3246 12804 : mbedtls_asn1_sequence_free(cert_cur->authority_key_id.authorityCertIssuer.next);
3247 :
3248 12804 : if (cert_cur->raw.p != NULL && cert_cur->own_buffer) {
3249 12804 : mbedtls_zeroize_and_free(cert_cur->raw.p, cert_cur->raw.len);
3250 : }
3251 :
3252 12804 : cert_prv = cert_cur;
3253 12804 : cert_cur = cert_cur->next;
3254 :
3255 12804 : mbedtls_platform_zeroize(cert_prv, sizeof(mbedtls_x509_crt));
3256 12804 : if (cert_prv != crt) {
3257 0 : mbedtls_free(cert_prv);
3258 : }
3259 : }
3260 12804 : }
3261 :
3262 : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
3263 : /*
3264 : * Initialize a restart context
3265 : */
3266 0 : void mbedtls_x509_crt_restart_init(mbedtls_x509_crt_restart_ctx *ctx)
3267 : {
3268 0 : mbedtls_pk_restart_init(&ctx->pk);
3269 :
3270 0 : ctx->parent = NULL;
3271 0 : ctx->fallback_parent = NULL;
3272 0 : ctx->fallback_signature_is_good = 0;
3273 :
3274 0 : ctx->parent_is_trusted = -1;
3275 :
3276 0 : ctx->in_progress = x509_crt_rs_none;
3277 0 : ctx->self_cnt = 0;
3278 0 : x509_crt_verify_chain_reset(&ctx->ver_chain);
3279 0 : }
3280 :
3281 : /*
3282 : * Free the components of a restart context
3283 : */
3284 0 : void mbedtls_x509_crt_restart_free(mbedtls_x509_crt_restart_ctx *ctx)
3285 : {
3286 0 : if (ctx == NULL) {
3287 0 : return;
3288 : }
3289 :
3290 0 : mbedtls_pk_restart_free(&ctx->pk);
3291 0 : mbedtls_x509_crt_restart_init(ctx);
3292 : }
3293 : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
3294 :
3295 0 : int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt)
3296 : {
3297 0 : if ((crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS) != 0) {
3298 0 : return crt->MBEDTLS_PRIVATE(ca_istrue);
3299 : }
3300 0 : return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
3301 : }
3302 :
3303 : #endif /* MBEDTLS_X509_CRT_PARSE_C */
|