Branch data 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 : 0 : static int x509_profile_check_md_alg(const mbedtls_x509_crt_profile *profile,
174 : : mbedtls_md_type_t md_alg)
175 : : {
176 [ # # ]: 0 : if (md_alg == MBEDTLS_MD_NONE) {
177 : : return -1;
178 : : }
179 : :
180 [ # # ]: 0 : if ((profile->allowed_mds & MBEDTLS_X509_ID_FLAG(md_alg)) != 0) {
181 : 0 : return 0;
182 : : }
183 : :
184 : : 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 : 0 : static int x509_profile_check_pk_alg(const mbedtls_x509_crt_profile *profile,
192 : : mbedtls_pk_type_t pk_alg)
193 : : {
194 [ # # ]: 0 : if (pk_alg == MBEDTLS_PK_NONE) {
195 : : return -1;
196 : : }
197 : :
198 [ # # ]: 0 : if ((profile->allowed_pks & MBEDTLS_X509_ID_FLAG(pk_alg)) != 0) {
199 : 0 : return 0;
200 : : }
201 : :
202 : : return -1;
203 : : }
204 : :
205 : : /*
206 : : * Check key against profile
207 : : * Return 0 if pk is acceptable for this profile, -1 otherwise
208 : : */
209 : 0 : static int x509_profile_check_key(const mbedtls_x509_crt_profile *profile,
210 : : const mbedtls_pk_context *pk)
211 : : {
212 : 0 : const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(pk);
213 : :
214 : : #if defined(MBEDTLS_RSA_C)
215 : : if (pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS) {
216 : : if (mbedtls_pk_get_bitlen(pk) >= profile->rsa_min_bitlen) {
217 : : return 0;
218 : : }
219 : :
220 : : return -1;
221 : : }
222 : : #endif /* MBEDTLS_RSA_C */
223 : :
224 : : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
225 : 0 : if (pk_alg == MBEDTLS_PK_ECDSA ||
226 [ # # # # ]: 0 : pk_alg == MBEDTLS_PK_ECKEY ||
227 : : pk_alg == MBEDTLS_PK_ECKEY_DH) {
228 : 0 : const mbedtls_ecp_group_id gid = mbedtls_pk_get_ec_group_id(pk);
229 : :
230 [ # # ]: 0 : if (gid == MBEDTLS_ECP_DP_NONE) {
231 : : return -1;
232 : : }
233 : :
234 [ # # ]: 0 : if ((profile->allowed_curves & MBEDTLS_X509_ID_FLAG(gid)) != 0) {
235 : : return 0;
236 : : }
237 : :
238 : : return -1;
239 : : }
240 : : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
241 : :
242 : : return -1;
243 : : }
244 : :
245 : : /*
246 : : * Like memcmp, but case-insensitive and always returns -1 if different
247 : : */
248 : 0 : static int x509_memcasecmp(const void *s1, const void *s2, size_t len)
249 : : {
250 : 0 : size_t i;
251 : 0 : unsigned char diff;
252 : 0 : const unsigned char *n1 = s1, *n2 = s2;
253 : :
254 [ # # ]: 0 : for (i = 0; i < len; i++) {
255 : 0 : diff = n1[i] ^ n2[i];
256 : :
257 [ # # ]: 0 : if (diff == 0) {
258 : 0 : continue;
259 : : }
260 : :
261 [ # # ]: 0 : if (diff == 32 &&
262 [ # # ]: 0 : ((n1[i] >= 'a' && n1[i] <= 'z') ||
263 : : (n1[i] >= 'A' && n1[i] <= 'Z'))) {
264 : 0 : continue;
265 : : }
266 : :
267 : : return -1;
268 : : }
269 : :
270 : : 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 : 0 : 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 : : return -1;
284 : : }
285 : :
286 [ # # ]: 0 : for (i = 0; i < cn_len; ++i) {
287 [ # # ]: 0 : if (cn[i] == '.') {
288 : : cn_idx = i;
289 : : break;
290 : : }
291 : : }
292 : :
293 [ # # ]: 0 : if (cn_idx == 0) {
294 : : 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 : : 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 : 0 : static int x509_string_cmp(const mbedtls_x509_buf *a, const mbedtls_x509_buf *b)
312 : : {
313 [ # # ]: 0 : if (a->tag == b->tag &&
314 [ # # ]: 0 : a->len == b->len &&
315 [ # # ]: 0 : memcmp(a->p, b->p, b->len) == 0) {
316 : : return 0;
317 : : }
318 : :
319 [ # # ]: 0 : if ((a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING) &&
320 [ # # ]: 0 : (b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING) &&
321 [ # # ]: 0 : a->len == b->len &&
322 [ # # ]: 0 : x509_memcasecmp(a->p, b->p, b->len) == 0) {
323 : 0 : return 0;
324 : : }
325 : :
326 : : 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 : 0 : 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 [ # # ]: 0 : while (a != NULL || b != NULL) {
343 [ # # ]: 0 : if (a == NULL || b == NULL) {
344 : : return -1;
345 : : }
346 : :
347 : : /* type */
348 [ # # ]: 0 : if (a->oid.tag != b->oid.tag ||
349 [ # # ]: 0 : a->oid.len != b->oid.len ||
350 [ # # ]: 0 : memcmp(a->oid.p, b->oid.p, b->oid.len) != 0) {
351 : : return -1;
352 : : }
353 : :
354 : : /* value */
355 [ # # ]: 0 : if (x509_string_cmp(&a->val, &b->val) != 0) {
356 : : return -1;
357 : : }
358 : :
359 : : /* structure of the list of sets */
360 [ # # ]: 0 : if (a->next_merged != b->next_merged) {
361 : : return -1;
362 : : }
363 : :
364 : 0 : a = a->next;
365 : 0 : b = b->next;
366 : : }
367 : :
368 : : /* a == NULL == b */
369 : : return 0;
370 : : }
371 : :
372 : : /*
373 : : * Reset (init or clear) a verify_chain
374 : : */
375 : 0 : static void x509_crt_verify_chain_reset(
376 : : mbedtls_x509_crt_verify_chain *ver_chain)
377 : : {
378 : 0 : size_t i;
379 : :
380 [ # # ]: 0 : for (i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++) {
381 : 0 : ver_chain->items[i].crt = NULL;
382 : 0 : ver_chain->items[i].flags = (uint32_t) -1;
383 : : }
384 : :
385 : 0 : 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 : 0 : }
391 : :
392 : : /*
393 : : * Version ::= INTEGER { v1(0), v2(1), v3(2) }
394 : : */
395 : 4 : static int x509_get_version(unsigned char **p,
396 : : const unsigned char *end,
397 : : int *ver)
398 : : {
399 : 4 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
400 : 4 : size_t len;
401 : :
402 [ - + ]: 4 : 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 : 4 : end = *p + len;
414 : :
415 [ - + ]: 4 : 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 [ + - ]: 4 : if (*p != end) {
420 : 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION,
421 : : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
422 : : }
423 : :
424 : : return 0;
425 : : }
426 : :
427 : : /*
428 : : * Validity ::= SEQUENCE {
429 : : * notBefore Time,
430 : : * notAfter Time }
431 : : */
432 : 4 : 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 : 4 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
438 : 4 : size_t len;
439 : :
440 [ - + ]: 4 : 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 : 4 : end = *p + len;
446 : :
447 [ + - ]: 4 : if ((ret = mbedtls_x509_get_time(p, end, from)) != 0) {
448 : : return ret;
449 : : }
450 : :
451 [ + - ]: 4 : if ((ret = mbedtls_x509_get_time(p, end, to)) != 0) {
452 : : return ret;
453 : : }
454 : :
455 [ - + ]: 4 : if (*p != end) {
456 : 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
457 : : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
458 : : }
459 : :
460 : : return 0;
461 : : }
462 : :
463 : : /*
464 : : * X.509 v2/v3 unique identifier (not parsed)
465 : : */
466 : 8 : static int x509_get_uid(unsigned char **p,
467 : : const unsigned char *end,
468 : : mbedtls_x509_buf *uid, int n)
469 : : {
470 : 8 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
471 : :
472 [ + - ]: 8 : if (*p == end) {
473 : : return 0;
474 : : }
475 : :
476 : 0 : uid->tag = **p;
477 : :
478 [ # # ]: 0 : if ((ret = mbedtls_asn1_get_tag(p, end, &uid->len,
479 : : MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
480 : : n)) != 0) {
481 [ # # ]: 0 : if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
482 : : 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 : 0 : static int x509_get_basic_constraints(unsigned char **p,
495 : : const unsigned char *end,
496 : : int *ca_istrue,
497 : : int *max_pathlen)
498 : : {
499 : 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
500 : 0 : size_t len;
501 : :
502 : : /*
503 : : * BasicConstraints ::= SEQUENCE {
504 : : * cA BOOLEAN DEFAULT FALSE,
505 : : * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
506 : : */
507 : 0 : *ca_istrue = 0; /* DEFAULT FALSE */
508 : 0 : *max_pathlen = 0; /* endless */
509 : :
510 [ # # ]: 0 : 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 [ # # ]: 0 : if (*p == end) {
516 : : return 0;
517 : : }
518 : :
519 [ # # ]: 0 : 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 [ # # ]: 0 : if (*p == end) {
534 : : 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 : 0 : static int x509_get_ext_key_usage(unsigned char **p,
564 : : const unsigned char *end,
565 : : mbedtls_x509_sequence *ext_key_usage)
566 : : {
567 : 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
568 : :
569 [ # # ]: 0 : 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 [ # # ]: 0 : 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 : : return 0;
580 : : }
581 : :
582 : : /*
583 : : * SubjectKeyIdentifier ::= KeyIdentifier
584 : : *
585 : : * KeyIdentifier ::= OCTET STRING
586 : : */
587 : 0 : static int x509_get_subject_key_id(unsigned char **p,
588 : : const unsigned char *end,
589 : : mbedtls_x509_buf *subject_key_id)
590 : : {
591 : 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
592 : 0 : size_t len = 0u;
593 : :
594 [ # # ]: 0 : 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 : 0 : subject_key_id->len = len;
600 : 0 : subject_key_id->tag = MBEDTLS_ASN1_OCTET_STRING;
601 : 0 : subject_key_id->p = *p;
602 : 0 : *p += len;
603 : :
604 [ # # ]: 0 : if (*p != end) {
605 : 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
606 : : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
607 : : }
608 : :
609 : : 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 : 0 : static int x509_get_authority_key_id(unsigned char **p,
621 : : unsigned char *end,
622 : : mbedtls_x509_authority *authority_key_id)
623 : : {
624 : 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
625 : 0 : size_t len = 0u;
626 : :
627 [ # # ]: 0 : 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 [ # # ]: 0 : if (*p + len != end) {
633 : 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
634 : : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
635 : : }
636 : :
637 : 0 : ret = mbedtls_asn1_get_tag(p, end, &len,
638 : : MBEDTLS_ASN1_CONTEXT_SPECIFIC);
639 : :
640 : : /* KeyIdentifier is an OPTIONAL field */
641 [ # # ]: 0 : if (ret == 0) {
642 : 0 : authority_key_id->keyIdentifier.len = len;
643 : 0 : 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 : 0 : authority_key_id->keyIdentifier.tag = MBEDTLS_ASN1_OCTET_STRING;
648 : :
649 : 0 : *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 [ # # ]: 0 : 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 : : 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 [ # # ]: 0 : if (*p != end) {
683 : 0 : return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
684 : : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
685 : : }
686 : :
687 : : 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 : 0 : static int x509_get_certificate_policies(unsigned char **p,
740 : : const unsigned char *end,
741 : : mbedtls_x509_sequence *certificate_policies)
742 : : {
743 : 0 : int ret, parse_ret = 0;
744 : 0 : size_t len;
745 : 0 : mbedtls_asn1_buf *buf;
746 : 0 : mbedtls_asn1_sequence *cur = certificate_policies;
747 : :
748 : : /* Get main sequence tag */
749 : 0 : ret = mbedtls_asn1_get_tag(p, end, &len,
750 : : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
751 [ # # ]: 0 : if (ret != 0) {
752 : 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
753 : : }
754 : :
755 [ # # ]: 0 : 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 [ # # ]: 0 : if (len == 0) {
764 : 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
765 : : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
766 : : }
767 : :
768 [ # # ]: 0 : while (*p < end) {
769 : 0 : mbedtls_x509_buf policy_oid;
770 : 0 : const unsigned char *policy_end;
771 : :
772 : : /*
773 : : * Get the policy sequence
774 : : */
775 [ # # ]: 0 : 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 : 0 : policy_end = *p + len;
781 : :
782 [ # # ]: 0 : 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 : 0 : policy_oid.tag = MBEDTLS_ASN1_OID;
788 : 0 : policy_oid.len = len;
789 : 0 : policy_oid.p = *p;
790 : :
791 : : /*
792 : : * Only AnyPolicy is currently supported when enforcing policy.
793 : : */
794 [ # # # # ]: 0 : 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 : : parse_ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
800 : : }
801 : :
802 : : /* Allocate and assign next pointer */
803 [ # # ]: 0 : if (cur->buf.p != NULL) {
804 [ # # ]: 0 : if (cur->next != NULL) {
805 : : return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
806 : : }
807 : :
808 : 0 : cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
809 : :
810 [ # # ]: 0 : if (cur->next == NULL) {
811 : 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
812 : : MBEDTLS_ERR_ASN1_ALLOC_FAILED);
813 : : }
814 : :
815 : : cur = cur->next;
816 : : }
817 : :
818 : 0 : buf = &(cur->buf);
819 : 0 : buf->tag = policy_oid.tag;
820 : 0 : buf->p = policy_oid.p;
821 : 0 : buf->len = policy_oid.len;
822 : :
823 : 0 : *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 [ # # ]: 0 : if (*p < policy_end) {
830 [ # # ]: 0 : 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 : 0 : *p += len;
839 : : }
840 : :
841 [ # # ]: 0 : 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 : 0 : cur->next = NULL;
849 : :
850 [ # # ]: 0 : if (*p != end) {
851 : 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
852 : : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
853 : : }
854 : :
855 : : return parse_ret;
856 : : }
857 : :
858 : : /*
859 : : * X.509 v3 extensions
860 : : *
861 : : */
862 : 4 : 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 : 4 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
869 : 4 : size_t len;
870 : 4 : unsigned char *end_ext_data, *start_ext_octet, *end_ext_octet;
871 : :
872 [ + - ]: 4 : if (*p == end) {
873 : : return 0;
874 : : }
875 : :
876 [ # # ]: 0 : if ((ret = mbedtls_x509_get_ext(p, end, &crt->v3_ext, 3)) != 0) {
877 : : return ret;
878 : : }
879 : :
880 : 0 : end = crt->v3_ext.p + crt->v3_ext.len;
881 [ # # ]: 0 : while (*p < end) {
882 : : /*
883 : : * Extension ::= SEQUENCE {
884 : : * extnID OBJECT IDENTIFIER,
885 : : * critical BOOLEAN DEFAULT FALSE,
886 : : * extnValue OCTET STRING }
887 : : */
888 : 0 : mbedtls_x509_buf extn_oid = { 0, 0, NULL };
889 : 0 : int is_critical = 0; /* DEFAULT FALSE */
890 : 0 : int ext_type = 0;
891 : :
892 [ # # ]: 0 : 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 : 0 : end_ext_data = *p + len;
898 : :
899 : : /* Get extension ID */
900 [ # # ]: 0 : 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 : 0 : extn_oid.tag = MBEDTLS_ASN1_OID;
906 : 0 : extn_oid.p = *p;
907 : 0 : *p += extn_oid.len;
908 : :
909 : : /* Get optional critical */
910 [ # # # # ]: 0 : 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 [ # # ]: 0 : 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 : 0 : start_ext_octet = *p;
922 : 0 : end_ext_octet = *p + len;
923 : :
924 [ # # ]: 0 : 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 : 0 : ret = mbedtls_oid_get_x509_ext_type(&extn_oid, &ext_type);
933 : :
934 [ # # ]: 0 : if (ret != 0) {
935 : : /* Give the callback (if any) a chance to handle the extension */
936 [ # # ]: 0 : 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 : 0 : continue;
943 : : }
944 : :
945 : : /* No parser found, skip extension */
946 : 0 : *p = end_ext_octet;
947 : :
948 [ # # ]: 0 : 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 : 0 : continue;
954 : : }
955 : :
956 : : /* Forbid repeated extensions */
957 [ # # ]: 0 : if ((crt->ext_types & ext_type) != 0) {
958 : : return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
959 : : }
960 : :
961 : 0 : crt->ext_types |= ext_type;
962 : :
963 [ # # # # : 0 : switch (ext_type) {
# # # #
# ]
964 : 0 : case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS:
965 : : /* Parse basic constraints */
966 [ # # ]: 0 : if ((ret = x509_get_basic_constraints(p, end_ext_octet,
967 : : &crt->ca_istrue, &crt->max_pathlen)) != 0) {
968 : 0 : return ret;
969 : : }
970 : : break;
971 : :
972 : 0 : case MBEDTLS_X509_EXT_KEY_USAGE:
973 : : /* Parse key usage */
974 [ # # ]: 0 : if ((ret = mbedtls_x509_get_key_usage(p, end_ext_octet,
975 : : &crt->key_usage)) != 0) {
976 : 0 : return ret;
977 : : }
978 : : break;
979 : :
980 : 0 : case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE:
981 : : /* Parse extended key usage */
982 [ # # ]: 0 : if ((ret = x509_get_ext_key_usage(p, end_ext_octet,
983 : : &crt->ext_key_usage)) != 0) {
984 : 0 : return ret;
985 : : }
986 : : break;
987 : :
988 : 0 : case MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER:
989 : : /* Parse subject key identifier */
990 [ # # ]: 0 : if ((ret = x509_get_subject_key_id(p, end_ext_data,
991 : : &crt->subject_key_id)) != 0) {
992 : 0 : return ret;
993 : : }
994 : : break;
995 : :
996 : 0 : case MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER:
997 : : /* Parse authority key identifier */
998 [ # # ]: 0 : if ((ret = x509_get_authority_key_id(p, end_ext_octet,
999 : : &crt->authority_key_id)) != 0) {
1000 : 0 : return ret;
1001 : : }
1002 : : break;
1003 : 0 : case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
1004 : : /* Parse subject alt name
1005 : : * SubjectAltName ::= GeneralNames
1006 : : */
1007 [ # # ]: 0 : if ((ret = mbedtls_x509_get_subject_alt_name(p, end_ext_octet,
1008 : : &crt->subject_alt_names)) != 0) {
1009 : 0 : return ret;
1010 : : }
1011 : : 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 : : break;
1020 : :
1021 : 0 : case MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES:
1022 : : /* Parse certificate policies type */
1023 [ # # ]: 0 : 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 [ # # # # ]: 0 : 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 : : break;
1031 : : }
1032 : :
1033 [ # # ]: 0 : 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 [ # # ]: 0 : if (ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
1043 : 0 : return ret;
1044 : : }
1045 : : }
1046 : : 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 : : return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
1056 : : } else {
1057 : 0 : *p = end_ext_octet;
1058 : : }
1059 : : }
1060 : : }
1061 : :
1062 [ # # ]: 0 : if (*p != end) {
1063 : 0 : return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1064 : : MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1065 : : }
1066 : :
1067 : : return 0;
1068 : : }
1069 : :
1070 : : /*
1071 : : * Parse and fill a single X.509 certificate in DER format
1072 : : */
1073 : 4 : 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 : 4 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1081 : 4 : size_t len;
1082 : 4 : unsigned char *p, *end, *crt_end;
1083 : 4 : mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
1084 : :
1085 [ + - ]: 4 : memset(&sig_params1, 0, sizeof(mbedtls_x509_buf));
1086 : 4 : memset(&sig_params2, 0, sizeof(mbedtls_x509_buf));
1087 : 4 : memset(&sig_oid2, 0, sizeof(mbedtls_x509_buf));
1088 : :
1089 : : /*
1090 : : * Check for valid input
1091 : : */
1092 [ + - ]: 4 : if (crt == NULL || buf == NULL) {
1093 : : return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1094 : : }
1095 : :
1096 : : /* Use the original buffer until we figure out actual length. */
1097 : 4 : p = (unsigned char *) buf;
1098 : 4 : len = buflen;
1099 : 4 : end = p + len;
1100 : :
1101 : : /*
1102 : : * Certificate ::= SEQUENCE {
1103 : : * tbsCertificate TBSCertificate,
1104 : : * signatureAlgorithm AlgorithmIdentifier,
1105 : : * signatureValue BIT STRING }
1106 : : */
1107 [ - + ]: 4 : 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 : 4 : end = crt_end = p + len;
1114 : 4 : crt->raw.len = (size_t) (crt_end - buf);
1115 [ - + ]: 4 : if (make_copy != 0) {
1116 : : /* Create and populate a new buffer for the raw field. */
1117 : 0 : crt->raw.p = p = mbedtls_calloc(1, crt->raw.len);
1118 [ # # ]: 0 : if (crt->raw.p == NULL) {
1119 : : return MBEDTLS_ERR_X509_ALLOC_FAILED;
1120 : : }
1121 : :
1122 : 0 : memcpy(crt->raw.p, buf, crt->raw.len);
1123 : 0 : crt->own_buffer = 1;
1124 : :
1125 : 0 : p += crt->raw.len - len;
1126 : 0 : end = crt_end = p + len;
1127 : : } else {
1128 : 4 : crt->raw.p = (unsigned char *) buf;
1129 : 4 : crt->own_buffer = 0;
1130 : : }
1131 : :
1132 : : /*
1133 : : * TBSCertificate ::= SEQUENCE {
1134 : : */
1135 : 4 : crt->tbs.p = p;
1136 : :
1137 [ - + ]: 4 : 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 : 4 : end = p + len;
1144 : 4 : 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 [ + - ]: 4 : if ((ret = x509_get_version(&p, end, &crt->version)) != 0 ||
1154 [ + - ]: 4 : (ret = mbedtls_x509_get_serial(&p, end, &crt->serial)) != 0 ||
1155 [ - + ]: 4 : (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 [ - + ]: 4 : 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 : 4 : crt->version++;
1167 : :
1168 [ - + ]: 4 : 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 : 4 : crt->issuer_raw.p = p;
1179 : :
1180 [ - + ]: 4 : 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 [ - + ]: 4 : 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 : 4 : 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 [ - + ]: 4 : 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 : 4 : crt->subject_raw.p = p;
1209 : :
1210 [ - + ]: 4 : 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 [ + - - + ]: 4 : 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 : 4 : crt->subject_raw.len = (size_t) (p - crt->subject_raw.p);
1222 : :
1223 : : /*
1224 : : * SubjectPublicKeyInfo
1225 : : */
1226 : 4 : crt->pk_raw.p = p;
1227 [ - + ]: 4 : if ((ret = mbedtls_pk_parse_subpubkey(&p, end, &crt->pk)) != 0) {
1228 : 0 : mbedtls_x509_crt_free(crt);
1229 : 0 : return ret;
1230 : : }
1231 : 4 : 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 [ + - ]: 4 : if (crt->version == 2 || crt->version == 3) {
1242 : 4 : ret = x509_get_uid(&p, end, &crt->issuer_id, 1);
1243 [ - + ]: 4 : if (ret != 0) {
1244 : 0 : mbedtls_x509_crt_free(crt);
1245 : 0 : return ret;
1246 : : }
1247 : : }
1248 : :
1249 [ + - ]: 4 : if (crt->version == 2 || crt->version == 3) {
1250 : 4 : ret = x509_get_uid(&p, end, &crt->subject_id, 2);
1251 [ - + ]: 4 : if (ret != 0) {
1252 : 0 : mbedtls_x509_crt_free(crt);
1253 : 0 : return ret;
1254 : : }
1255 : : }
1256 : :
1257 [ + - ]: 4 : if (crt->version == 3) {
1258 : 4 : ret = x509_get_crt_ext(&p, end, crt, cb, p_ctx);
1259 [ - + ]: 4 : if (ret != 0) {
1260 : 0 : mbedtls_x509_crt_free(crt);
1261 : 0 : return ret;
1262 : : }
1263 : : }
1264 : :
1265 [ - + ]: 4 : 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 : 4 : end = crt_end;
1272 : :
1273 : : /*
1274 : : * }
1275 : : * -- end of TBSCertificate
1276 : : *
1277 : : * signatureAlgorithm AlgorithmIdentifier,
1278 : : * signatureValue BIT STRING
1279 : : */
1280 [ - + ]: 4 : 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 [ + - ]: 4 : if (crt->sig_oid.len != sig_oid2.len ||
1286 [ + - ]: 4 : memcmp(crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len) != 0 ||
1287 [ + - ]: 4 : sig_params1.tag != sig_params2.tag ||
1288 [ + - - + ]: 4 : sig_params1.len != sig_params2.len ||
1289 : 0 : (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 [ - + ]: 4 : 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 [ - + ]: 4 : 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 : : 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 : 4 : 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 : 4 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1321 : 4 : mbedtls_x509_crt *crt = chain, *prev = NULL;
1322 : :
1323 : : /*
1324 : : * Check for valid input
1325 : : */
1326 [ + - ]: 4 : if (crt == NULL || buf == NULL) {
1327 : : return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1328 : : }
1329 : :
1330 [ - + - - ]: 4 : while (crt->version != 0 && crt->next != NULL) {
1331 : : prev = crt;
1332 : : crt = crt->next;
1333 : : }
1334 : :
1335 : : /*
1336 : : * Add new certificate on the end of the chain if needed.
1337 : : */
1338 [ - + - - ]: 4 : 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 : : 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 : 4 : ret = x509_crt_parse_der_core(crt, buf, buflen, make_copy, cb, p_ctx);
1351 [ - + ]: 4 : 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 : : return 0;
1364 : : }
1365 : :
1366 : 4 : int mbedtls_x509_crt_parse_der_nocopy(mbedtls_x509_crt *chain,
1367 : : const unsigned char *buf,
1368 : : size_t buflen)
1369 : : {
1370 : 4 : 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 : 0 : int mbedtls_x509_crt_parse_der(mbedtls_x509_crt *chain,
1384 : : const unsigned char *buf,
1385 : : size_t buflen)
1386 : : {
1387 : 0 : 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 : : int success = 0, first_error = 0, total_failed = 0;
1400 : : 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 : : 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 : : if (buflen != 0 && buf[buflen - 1] == '\0' &&
1416 : : strstr((const char *) buf, "-----BEGIN CERTIFICATE-----") != NULL) {
1417 : : buf_format = MBEDTLS_X509_FORMAT_PEM;
1418 : : }
1419 : :
1420 : : if (buf_format == MBEDTLS_X509_FORMAT_DER) {
1421 : : return mbedtls_x509_crt_parse_der(chain, buf, buflen);
1422 : : }
1423 : : #else
1424 : 0 : return mbedtls_x509_crt_parse_der(chain, buf, buflen);
1425 : : #endif
1426 : :
1427 : : #if defined(MBEDTLS_PEM_PARSE_C)
1428 : : if (buf_format == MBEDTLS_X509_FORMAT_PEM) {
1429 : : 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 : : while (buflen > 1) {
1434 : : size_t use_len;
1435 : : mbedtls_pem_init(&pem);
1436 : :
1437 : : /* If we get there, we know the string is null-terminated */
1438 : : ret = mbedtls_pem_read_buffer(&pem,
1439 : : "-----BEGIN CERTIFICATE-----",
1440 : : "-----END CERTIFICATE-----",
1441 : : buf, NULL, 0, &use_len);
1442 : :
1443 : : if (ret == 0) {
1444 : : /*
1445 : : * Was PEM encoded
1446 : : */
1447 : : buflen -= use_len;
1448 : : buf += use_len;
1449 : : } else if (ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA) {
1450 : : return ret;
1451 : : } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
1452 : : mbedtls_pem_free(&pem);
1453 : :
1454 : : /*
1455 : : * PEM header and footer were found
1456 : : */
1457 : : buflen -= use_len;
1458 : : buf += use_len;
1459 : :
1460 : : if (first_error == 0) {
1461 : : first_error = ret;
1462 : : }
1463 : :
1464 : : total_failed++;
1465 : : continue;
1466 : : } else {
1467 : : break;
1468 : : }
1469 : :
1470 : : ret = mbedtls_x509_crt_parse_der(chain, pem.buf, pem.buflen);
1471 : :
1472 : : mbedtls_pem_free(&pem);
1473 : :
1474 : : if (ret != 0) {
1475 : : /*
1476 : : * Quit parsing on a memory error
1477 : : */
1478 : : if (ret == MBEDTLS_ERR_X509_ALLOC_FAILED) {
1479 : : return ret;
1480 : : }
1481 : :
1482 : : if (first_error == 0) {
1483 : : first_error = ret;
1484 : : }
1485 : :
1486 : : total_failed++;
1487 : : continue;
1488 : : }
1489 : :
1490 : : success = 1;
1491 : : }
1492 : : }
1493 : :
1494 : : if (success) {
1495 : : return total_failed;
1496 : : } else if (first_error) {
1497 : : return first_error;
1498 : : } else {
1499 : : 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 : 0 : 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 : 0 : 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 : 0 : size_t n;
1756 : 0 : char *p;
1757 : 0 : 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 : : 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 : : 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 : : 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 : : 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 : : 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 : : 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 : 0 : 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 : 0 : int mbedtls_x509_crt_check_key_usage(const mbedtls_x509_crt *crt,
1931 : : unsigned int usage)
1932 : : {
1933 : 0 : unsigned int usage_must, usage_may;
1934 : 0 : unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY
1935 : : | MBEDTLS_X509_KU_DECIPHER_ONLY;
1936 : :
1937 [ # # ]: 0 : if ((crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) == 0) {
1938 : : return 0;
1939 : : }
1940 : :
1941 : 0 : usage_must = usage & ~may_mask;
1942 : :
1943 [ # # ]: 0 : if (((crt->key_usage & ~may_mask) & usage_must) != usage_must) {
1944 : : return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1945 : : }
1946 : :
1947 : 0 : usage_may = usage & may_mask;
1948 : :
1949 [ # # ]: 0 : if (((crt->key_usage & may_mask) | usage_may) != usage_may) {
1950 : 0 : return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1951 : : }
1952 : :
1953 : : 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 : 0 : 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 : : 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 : : return 0;
1976 : : }
1977 : :
1978 [ # # # # ]: 0 : if (MBEDTLS_OID_CMP(MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid) == 0) {
1979 : : return 0;
1980 : : }
1981 : : }
1982 : :
1983 : : 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 : : int mbedtls_x509_crt_is_revoked(const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl)
1991 : : {
1992 : : const mbedtls_x509_crl_entry *cur = &crl->entry;
1993 : :
1994 : : while (cur != NULL && cur->serial.len != 0) {
1995 : : if (crt->serial.len == cur->serial.len &&
1996 : : memcmp(crt->serial.p, cur->serial.p, crt->serial.len) == 0) {
1997 : : return 1;
1998 : : }
1999 : :
2000 : : cur = cur->next;
2001 : : }
2002 : :
2003 : : 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 : : 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 : : 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 : : if (ca == NULL) {
2025 : : return flags;
2026 : : }
2027 : :
2028 : : while (crl_list != NULL) {
2029 : : if (crl_list->version == 0 ||
2030 : : x509_name_cmp(&crl_list->issuer, &ca->subject) != 0) {
2031 : : crl_list = crl_list->next;
2032 : : continue;
2033 : : }
2034 : :
2035 : : /*
2036 : : * Check if the CA is configured to sign CRLs
2037 : : */
2038 : : if (mbedtls_x509_crt_check_key_usage(ca,
2039 : : MBEDTLS_X509_KU_CRL_SIGN) != 0) {
2040 : : flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
2041 : : break;
2042 : : }
2043 : :
2044 : : /*
2045 : : * Check if CRL is correctly signed by the trusted CA
2046 : : */
2047 : : if (x509_profile_check_md_alg(profile, crl_list->sig_md) != 0) {
2048 : : flags |= MBEDTLS_X509_BADCRL_BAD_MD;
2049 : : }
2050 : :
2051 : : if (x509_profile_check_pk_alg(profile, crl_list->sig_pk) != 0) {
2052 : : 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 : : md_info = mbedtls_md_info_from_type(crl_list->sig_md);
2069 : : hash_length = mbedtls_md_get_size(md_info);
2070 : : if (mbedtls_md(md_info,
2071 : : crl_list->tbs.p,
2072 : : crl_list->tbs.len,
2073 : : hash) != 0) {
2074 : : /* Note: this can't happen except after an internal error */
2075 : : flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
2076 : : break;
2077 : : }
2078 : : #endif /* MBEDTLS_USE_PSA_CRYPTO */
2079 : :
2080 : : if (x509_profile_check_key(profile, &ca->pk) != 0) {
2081 : : flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
2082 : : }
2083 : :
2084 : : if (mbedtls_pk_verify_ext(crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
2085 : : crl_list->sig_md, hash, hash_length,
2086 : : crl_list->sig.p, crl_list->sig.len) != 0) {
2087 : : flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
2088 : : break;
2089 : : }
2090 : :
2091 : : #if defined(MBEDTLS_HAVE_TIME_DATE)
2092 : : /*
2093 : : * Check for validity of CRL (Do not drop out)
2094 : : */
2095 : : if (mbedtls_x509_time_cmp(&crl_list->next_update, now) < 0) {
2096 : : flags |= MBEDTLS_X509_BADCRL_EXPIRED;
2097 : : }
2098 : :
2099 : : if (mbedtls_x509_time_cmp(&crl_list->this_update, now) > 0) {
2100 : : flags |= MBEDTLS_X509_BADCRL_FUTURE;
2101 : : }
2102 : : #else
2103 : : ((void) now);
2104 : : #endif
2105 : :
2106 : : /*
2107 : : * Check if certificate is revoked
2108 : : */
2109 : : if (mbedtls_x509_crt_is_revoked(crt, crl_list)) {
2110 : : flags |= MBEDTLS_X509_BADCERT_REVOKED;
2111 : : break;
2112 : : }
2113 : :
2114 : : crl_list = crl_list->next;
2115 : : }
2116 : :
2117 : : return flags;
2118 : : }
2119 : : #endif /* MBEDTLS_X509_CRL_PARSE_C */
2120 : :
2121 : : /*
2122 : : * Check the signature of a certificate by its parent
2123 : : */
2124 : 0 : 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 : 0 : size_t hash_len;
2129 : 0 : unsigned char hash[MBEDTLS_MD_MAX_SIZE];
2130 : : #if !defined(MBEDTLS_USE_PSA_CRYPTO)
2131 : 0 : const mbedtls_md_info_t *md_info;
2132 : 0 : md_info = mbedtls_md_info_from_type(child->sig_md);
2133 : 0 : hash_len = mbedtls_md_get_size(md_info);
2134 : :
2135 : : /* Note: hash errors can happen only after an internal error */
2136 [ # # ]: 0 : if (mbedtls_md(md_info, child->tbs.p, child->tbs.len, hash) != 0) {
2137 : : 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 [ # # ]: 0 : if (!mbedtls_pk_can_do(&parent->pk, child->sig_pk)) {
2156 : : return -1;
2157 : : }
2158 : :
2159 : : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2160 : : if (rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA) {
2161 : : return mbedtls_pk_verify_restartable(&parent->pk,
2162 : : child->sig_md, hash, hash_len,
2163 : : child->sig.p, child->sig.len, &rs_ctx->pk);
2164 : : }
2165 : : #else
2166 : 0 : (void) rs_ctx;
2167 : : #endif
2168 : :
2169 : 0 : return mbedtls_pk_verify_ext(child->sig_pk, child->sig_opts, &parent->pk,
2170 : 0 : child->sig_md, hash, hash_len,
2171 : 0 : 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 : 0 : static int x509_crt_check_parent(const mbedtls_x509_crt *child,
2181 : : const mbedtls_x509_crt *parent,
2182 : : int top)
2183 : : {
2184 : 0 : int need_ca_bit;
2185 : :
2186 : : /* Parent must be the issuer */
2187 [ # # ]: 0 : if (x509_name_cmp(&child->issuer, &parent->subject) != 0) {
2188 : : return -1;
2189 : : }
2190 : :
2191 : : /* Parent must have the basicConstraints CA bit set as a general rule */
2192 : 0 : need_ca_bit = 1;
2193 : :
2194 : : /* Exception: v1/v2 certificates that are locally trusted. */
2195 [ # # # # ]: 0 : if (top && parent->version < 3) {
2196 : : need_ca_bit = 0;
2197 : : }
2198 : :
2199 [ # # ]: 0 : if (need_ca_bit && !parent->ca_istrue) {
2200 : : return -1;
2201 : : }
2202 : :
2203 : 0 : if (need_ca_bit &&
2204 [ # # ]: 0 : mbedtls_x509_crt_check_key_usage(parent, MBEDTLS_X509_KU_KEY_CERT_SIGN) != 0) {
2205 : 0 : return -1;
2206 : : }
2207 : :
2208 : : 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 : 0 : 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 : 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2266 : 0 : mbedtls_x509_crt *parent, *fallback_parent;
2267 : 0 : 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 : : if (rs_ctx != NULL && rs_ctx->parent != NULL) {
2272 : : /* restore saved state */
2273 : : parent = rs_ctx->parent;
2274 : : fallback_parent = rs_ctx->fallback_parent;
2275 : : fallback_signature_is_good = rs_ctx->fallback_signature_is_good;
2276 : :
2277 : : /* clear saved state */
2278 : : rs_ctx->parent = NULL;
2279 : : rs_ctx->fallback_parent = NULL;
2280 : : rs_ctx->fallback_signature_is_good = 0;
2281 : :
2282 : : /* resume where we left */
2283 : : goto check_signature;
2284 : : }
2285 : : #endif
2286 : :
2287 : 0 : fallback_parent = NULL;
2288 : 0 : fallback_signature_is_good = 0;
2289 : :
2290 [ # # ]: 0 : for (parent = candidates; parent != NULL; parent = parent->next) {
2291 : : /* basic parenting skills (name, CA bit, key usage) */
2292 [ # # ]: 0 : 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 [ # # ]: 0 : 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 : : check_signature:
2305 : : #endif
2306 : 0 : ret = x509_crt_check_signature(child, parent, rs_ctx);
2307 : :
2308 : : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2309 : : if (rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2310 : : /* save state */
2311 : : rs_ctx->parent = parent;
2312 : : rs_ctx->fallback_parent = fallback_parent;
2313 : : rs_ctx->fallback_signature_is_good = fallback_signature_is_good;
2314 : :
2315 : : return ret;
2316 : : }
2317 : : #else
2318 : 0 : (void) ret;
2319 : : #endif
2320 : :
2321 : 0 : signature_is_good = ret == 0;
2322 [ # # ]: 0 : if (top && !signature_is_good) {
2323 : 0 : continue;
2324 : : }
2325 : :
2326 : : #if defined(MBEDTLS_HAVE_TIME_DATE)
2327 : : /* optional time check */
2328 : : if (mbedtls_x509_time_cmp(&parent->valid_to, now) < 0 || /* past */
2329 : : mbedtls_x509_time_cmp(&parent->valid_from, now) > 0) { /* future */
2330 : : if (fallback_parent == NULL) {
2331 : : fallback_parent = parent;
2332 : : fallback_signature_is_good = signature_is_good;
2333 : : }
2334 : :
2335 : : continue;
2336 : : }
2337 : : #else
2338 : 0 : ((void) now);
2339 : : #endif
2340 : :
2341 : 0 : *r_parent = parent;
2342 : 0 : *r_signature_is_good = signature_is_good;
2343 : :
2344 : 0 : break;
2345 : : }
2346 : :
2347 [ # # ]: 0 : if (parent == NULL) {
2348 : 0 : *r_parent = fallback_parent;
2349 : 0 : *r_signature_is_good = fallback_signature_is_good;
2350 : : }
2351 : :
2352 : 0 : 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 : 0 : 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 : 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2389 : 0 : mbedtls_x509_crt *search_list;
2390 : :
2391 : 0 : *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 : : if (rs_ctx != NULL && rs_ctx->parent_is_trusted != -1) {
2396 : : *parent_is_trusted = rs_ctx->parent_is_trusted;
2397 : : rs_ctx->parent_is_trusted = -1;
2398 : : }
2399 : : #endif
2400 : :
2401 : 0 : while (1) {
2402 [ # # ]: 0 : search_list = *parent_is_trusted ? trust_ca : child->next;
2403 : :
2404 : 0 : 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 : : if (rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2411 : : /* save state */
2412 : : rs_ctx->parent_is_trusted = *parent_is_trusted;
2413 : : return ret;
2414 : : }
2415 : : #else
2416 : 0 : (void) ret;
2417 : : #endif
2418 : :
2419 : : /* stop here if found or already in second iteration */
2420 [ # # # # ]: 0 : if (*parent != NULL || *parent_is_trusted == 0) {
2421 : : break;
2422 : : }
2423 : :
2424 : : /* prepare second iteration */
2425 : 0 : *parent_is_trusted = 0;
2426 : : }
2427 : :
2428 : : /* extra precaution against mistakes in the caller */
2429 [ # # ]: 0 : if (*parent == NULL) {
2430 : 0 : *parent_is_trusted = 0;
2431 : 0 : *signature_is_good = 0;
2432 : : }
2433 : :
2434 : 0 : 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 : 0 : static int x509_crt_check_ee_locally_trusted(
2444 : : mbedtls_x509_crt *crt,
2445 : : mbedtls_x509_crt *trust_ca)
2446 : : {
2447 : 0 : mbedtls_x509_crt *cur;
2448 : :
2449 : : /* must be self-issued */
2450 [ # # ]: 0 : if (x509_name_cmp(&crt->issuer, &crt->subject) != 0) {
2451 : : return -1;
2452 : : }
2453 : :
2454 : : /* look for an exact match with trusted cert */
2455 [ # # ]: 0 : for (cur = trust_ca; cur != NULL; cur = cur->next) {
2456 [ # # ]: 0 : if (crt->raw.len == cur->raw.len &&
2457 [ # # ]: 0 : memcmp(crt->raw.p, cur->raw.p, crt->raw.len) == 0) {
2458 : : return 0;
2459 : : }
2460 : : }
2461 : :
2462 : : /* too bad */
2463 : : 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 : 0 : 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 : 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2519 : 0 : uint32_t *flags;
2520 : 0 : mbedtls_x509_crt_verify_chain_item *cur;
2521 : 0 : mbedtls_x509_crt *child;
2522 : 0 : mbedtls_x509_crt *parent;
2523 : 0 : int parent_is_trusted;
2524 : 0 : int child_is_trusted;
2525 : 0 : int signature_is_good;
2526 : 0 : unsigned self_cnt;
2527 : 0 : mbedtls_x509_crt *cur_trust_ca = NULL;
2528 : 0 : mbedtls_x509_time now;
2529 : :
2530 : : #if defined(MBEDTLS_HAVE_TIME_DATE)
2531 : : if (mbedtls_x509_time_gmtime(mbedtls_time(NULL), &now) != 0) {
2532 : : 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 : : if (rs_ctx != NULL && rs_ctx->in_progress == x509_crt_rs_find_parent) {
2539 : : /* restore saved state */
2540 : : *ver_chain = rs_ctx->ver_chain; /* struct copy */
2541 : : self_cnt = rs_ctx->self_cnt;
2542 : :
2543 : : /* restore derived state */
2544 : : cur = &ver_chain->items[ver_chain->len - 1];
2545 : : child = cur->crt;
2546 : : flags = &cur->flags;
2547 : :
2548 : : goto find_parent;
2549 : : }
2550 : : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
2551 : :
2552 : 0 : child = crt;
2553 : 0 : self_cnt = 0;
2554 : 0 : parent_is_trusted = 0;
2555 : 0 : child_is_trusted = 0;
2556 : :
2557 : 0 : while (1) {
2558 : : /* Add certificate to the verification chain */
2559 : 0 : cur = &ver_chain->items[ver_chain->len];
2560 : 0 : cur->crt = child;
2561 : 0 : cur->flags = 0;
2562 : 0 : ver_chain->len++;
2563 : 0 : flags = &cur->flags;
2564 : :
2565 : : #if defined(MBEDTLS_HAVE_TIME_DATE)
2566 : : /* Check time-validity (all certificates) */
2567 : : if (mbedtls_x509_time_cmp(&child->valid_to, &now) < 0) {
2568 : : *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
2569 : : }
2570 : :
2571 : : if (mbedtls_x509_time_cmp(&child->valid_from, &now) > 0) {
2572 : : *flags |= MBEDTLS_X509_BADCERT_FUTURE;
2573 : : }
2574 : : #endif
2575 : :
2576 : : /* Stop here for trusted roots (but not for trusted EE certs) */
2577 [ # # ]: 0 : if (child_is_trusted) {
2578 : : return 0;
2579 : : }
2580 : :
2581 : : /* Check signature algorithm: MD & PK algs */
2582 [ # # ]: 0 : if (x509_profile_check_md_alg(profile, child->sig_md) != 0) {
2583 : 0 : *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
2584 : : }
2585 : :
2586 [ # # ]: 0 : 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 [ # # # # ]: 0 : if (ver_chain->len == 1 &&
2592 : 0 : x509_crt_check_ee_locally_trusted(child, trust_ca) == 0) {
2593 : : return 0;
2594 : : }
2595 : :
2596 : : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2597 : : 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 : 0 : ((void) f_ca_cb);
2618 : 0 : ((void) p_ca_cb);
2619 : 0 : cur_trust_ca = trust_ca;
2620 : : }
2621 : :
2622 : : /* Look for a parent in trusted CAs or up the chain */
2623 : 0 : ret = x509_crt_find_parent(child, cur_trust_ca, &parent,
2624 : : &parent_is_trusted, &signature_is_good,
2625 : : ver_chain->len - 1, self_cnt, rs_ctx,
2626 : : &now);
2627 : :
2628 : : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2629 : : if (rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2630 : : /* save state */
2631 : : rs_ctx->in_progress = x509_crt_rs_find_parent;
2632 : : rs_ctx->self_cnt = self_cnt;
2633 : : rs_ctx->ver_chain = *ver_chain; /* struct copy */
2634 : :
2635 : : return ret;
2636 : : }
2637 : : #else
2638 : 0 : (void) ret;
2639 : : #endif
2640 : :
2641 : : /* No parent? We're done here */
2642 [ # # ]: 0 : if (parent == NULL) {
2643 : 0 : *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
2644 : 0 : 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 [ # # # # ]: 0 : 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 [ # # # # ]: 0 : if (!parent_is_trusted &&
2658 : : ver_chain->len > MBEDTLS_X509_MAX_INTERMEDIATE_CA) {
2659 : : /* return immediately to avoid overflow the chain array */
2660 : : return MBEDTLS_ERR_X509_FATAL_ERROR;
2661 : : }
2662 : :
2663 : : /* signature was checked while searching parent */
2664 [ # # ]: 0 : if (!signature_is_good) {
2665 : 0 : *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
2666 : : }
2667 : :
2668 : : /* check size of signing key */
2669 [ # # ]: 0 : 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 : : *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile, &now);
2676 : : #else
2677 : 0 : (void) ca_crl;
2678 : : #endif
2679 : :
2680 : : /* prepare for next iteration */
2681 : 0 : child = parent;
2682 : 0 : parent = NULL;
2683 : 0 : child_is_trusted = parent_is_trusted;
2684 : 0 : 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 : : return 0;
2894 : : }
2895 : :
2896 : : /* try wildcard match */
2897 [ # # ]: 0 : if (x509_check_wildcard(cn, name) == 0) {
2898 : : return 0;
2899 : : }
2900 : :
2901 : : 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 : 0 : uint32_t ip[4];
2908 : 0 : cn_len = mbedtls_x509_crt_parse_cn_inet_pton(cn, ip);
2909 [ # # ]: 0 : if (cn_len == 0) {
2910 : : 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 : : return 0;
2919 : : }
2920 : : }
2921 : :
2922 : : 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 : : return 0;
2934 : : }
2935 : : }
2936 : :
2937 : : 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 : : return 0;
2954 : : }
2955 : : 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 : : default: /* Unrecognized type */
2964 : : break;
2965 : : }
2966 : : }
2967 [ # # ]: 0 : if (san_ip) {
2968 [ # # ]: 0 : if (x509_crt_check_san_ip(san, cn, cn_len) == 0) {
2969 : : return 0;
2970 : : }
2971 : : }
2972 [ # # ]: 0 : if (san_uri) {
2973 [ # # ]: 0 : if (x509_crt_check_san_uri(san, cn, cn_len) == 0) {
2974 : : return 0;
2975 : : }
2976 : : }
2977 : :
2978 : : 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 : 0 : 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 : : 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 : : 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 : 0 : 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 : 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3018 : 0 : unsigned i;
3019 : 0 : uint32_t cur_flags;
3020 : 0 : const mbedtls_x509_crt_verify_chain_item *cur;
3021 : :
3022 [ # # ]: 0 : for (i = ver_chain->len; i != 0; --i) {
3023 : 0 : cur = &ver_chain->items[i-1];
3024 : 0 : cur_flags = cur->flags;
3025 : :
3026 [ # # ]: 0 : 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 : 0 : *flags |= cur_flags;
3033 : : }
3034 : :
3035 : : 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 : 0 : 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 : 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3070 : 0 : mbedtls_pk_type_t pk_type;
3071 : 0 : mbedtls_x509_crt_verify_chain ver_chain;
3072 : 0 : uint32_t ee_flags;
3073 : :
3074 : 0 : *flags = 0;
3075 : 0 : ee_flags = 0;
3076 : 0 : x509_crt_verify_chain_reset(&ver_chain);
3077 : :
3078 [ # # ]: 0 : if (profile == NULL) {
3079 : 0 : ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
3080 : 0 : goto exit;
3081 : : }
3082 : :
3083 : : /* check name if requested */
3084 [ # # ]: 0 : 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 : 0 : pk_type = mbedtls_pk_get_type(&crt->pk);
3090 : :
3091 [ # # ]: 0 : if (x509_profile_check_pk_alg(profile, pk_type) != 0) {
3092 : 0 : ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK;
3093 : : }
3094 : :
3095 [ # # ]: 0 : 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 : 0 : 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 [ # # ]: 0 : if (ret != 0) {
3105 : 0 : goto exit;
3106 : : }
3107 : :
3108 : : /* Merge end-entity flags */
3109 : 0 : ver_chain.items[0].flags |= ee_flags;
3110 : :
3111 : : /* Build final flags, calling callback on the way if any */
3112 : 0 : ret = x509_crt_merge_flags_with_cb(flags, &ver_chain, f_vrfy, p_vrfy);
3113 : :
3114 : 0 : 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 : : if (rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
3124 : : 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 [ # # ]: 0 : if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
3132 : : ret = MBEDTLS_ERR_X509_FATAL_ERROR;
3133 : : }
3134 : :
3135 [ # # ]: 0 : if (ret != 0) {
3136 : 0 : *flags = (uint32_t) -1;
3137 : 0 : return ret;
3138 : : }
3139 : :
3140 [ # # ]: 0 : if (*flags != 0) {
3141 : 0 : return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
3142 : : }
3143 : :
3144 : : 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 : 0 : 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 : 0 : 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 : 4 : void mbedtls_x509_crt_init(mbedtls_x509_crt *crt)
3222 : : {
3223 : 4 : memset(crt, 0, sizeof(mbedtls_x509_crt));
3224 : 4 : }
3225 : :
3226 : : /*
3227 : : * Unallocate all certificate data
3228 : : */
3229 : 4 : void mbedtls_x509_crt_free(mbedtls_x509_crt *crt)
3230 : : {
3231 : 4 : mbedtls_x509_crt *cert_cur = crt;
3232 : 4 : mbedtls_x509_crt *cert_prv;
3233 : :
3234 [ + + ]: 8 : while (cert_cur != NULL) {
3235 : 4 : mbedtls_pk_free(&cert_cur->pk);
3236 : :
3237 : : #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
3238 : : mbedtls_free(cert_cur->sig_opts);
3239 : : #endif
3240 : :
3241 : 4 : mbedtls_asn1_free_named_data_list_shallow(cert_cur->issuer.next);
3242 : 4 : mbedtls_asn1_free_named_data_list_shallow(cert_cur->subject.next);
3243 : 4 : mbedtls_asn1_sequence_free(cert_cur->ext_key_usage.next);
3244 : 4 : mbedtls_asn1_sequence_free(cert_cur->subject_alt_names.next);
3245 : 4 : mbedtls_asn1_sequence_free(cert_cur->certificate_policies.next);
3246 : 4 : mbedtls_asn1_sequence_free(cert_cur->authority_key_id.authorityCertIssuer.next);
3247 : :
3248 [ + - - + ]: 4 : if (cert_cur->raw.p != NULL && cert_cur->own_buffer) {
3249 : 0 : mbedtls_zeroize_and_free(cert_cur->raw.p, cert_cur->raw.len);
3250 : : }
3251 : :
3252 : 4 : cert_prv = cert_cur;
3253 : 4 : cert_cur = cert_cur->next;
3254 : :
3255 : 4 : mbedtls_platform_zeroize(cert_prv, sizeof(mbedtls_x509_crt));
3256 [ - + ]: 4 : if (cert_prv != crt) {
3257 : 0 : mbedtls_free(cert_prv);
3258 : : }
3259 : : }
3260 : 4 : }
3261 : :
3262 : : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
3263 : : /*
3264 : : * Initialize a restart context
3265 : : */
3266 : : void mbedtls_x509_crt_restart_init(mbedtls_x509_crt_restart_ctx *ctx)
3267 : : {
3268 : : mbedtls_pk_restart_init(&ctx->pk);
3269 : :
3270 : : ctx->parent = NULL;
3271 : : ctx->fallback_parent = NULL;
3272 : : ctx->fallback_signature_is_good = 0;
3273 : :
3274 : : ctx->parent_is_trusted = -1;
3275 : :
3276 : : ctx->in_progress = x509_crt_rs_none;
3277 : : ctx->self_cnt = 0;
3278 : : x509_crt_verify_chain_reset(&ctx->ver_chain);
3279 : : }
3280 : :
3281 : : /*
3282 : : * Free the components of a restart context
3283 : : */
3284 : : void mbedtls_x509_crt_restart_free(mbedtls_x509_crt_restart_ctx *ctx)
3285 : : {
3286 : : if (ctx == NULL) {
3287 : : return;
3288 : : }
3289 : :
3290 : : mbedtls_pk_restart_free(&ctx->pk);
3291 : : 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 : : return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
3301 : : }
3302 : :
3303 : : #endif /* MBEDTLS_X509_CRT_PARSE_C */
|