diff options
-rw-r--r-- | src/lib/libcrypto/ts/ts_rsp_sign.c | 10 | ||||
-rw-r--r-- | src/lib/libcrypto/ts/ts_rsp_verify.c | 11 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_cmp.c | 4 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_internal.h | 6 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_lcl.h | 12 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_purp.c | 10 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_verify.c | 172 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_verify.h | 3 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 56 |
9 files changed, 149 insertions, 135 deletions
diff --git a/src/lib/libcrypto/ts/ts_rsp_sign.c b/src/lib/libcrypto/ts/ts_rsp_sign.c index 828407aa4b..cbd7039abe 100644 --- a/src/lib/libcrypto/ts/ts_rsp_sign.c +++ b/src/lib/libcrypto/ts/ts_rsp_sign.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ts_rsp_sign.c,v 1.24 2021/11/01 20:53:08 tb Exp $ */ | 1 | /* $OpenBSD: ts_rsp_sign.c,v 1.25 2021/11/04 23:52:34 beck Exp $ */ |
2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | 2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL |
3 | * project 2002. | 3 | * project 2002. |
4 | */ | 4 | */ |
@@ -849,14 +849,18 @@ ESS_CERT_ID_new_init(X509 *cert, int issuer_needed) | |||
849 | { | 849 | { |
850 | ESS_CERT_ID *cid = NULL; | 850 | ESS_CERT_ID *cid = NULL; |
851 | GENERAL_NAME *name = NULL; | 851 | GENERAL_NAME *name = NULL; |
852 | unsigned char cert_hash[TS_HASH_LEN]; | ||
852 | 853 | ||
853 | /* Recompute SHA1 hash of certificate if necessary (side effect). */ | 854 | /* Recompute SHA1 hash of certificate if necessary (side effect). */ |
854 | X509_check_purpose(cert, -1, 0); | 855 | X509_check_purpose(cert, -1, 0); |
855 | 856 | ||
856 | if (!(cid = ESS_CERT_ID_new())) | 857 | if (!(cid = ESS_CERT_ID_new())) |
857 | goto err; | 858 | goto err; |
858 | if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash, | 859 | |
859 | sizeof(cert->sha1_hash))) | 860 | if (!X509_digest(cert, TS_HASH_EVP, cert_hash, NULL)) |
861 | goto err; | ||
862 | |||
863 | if (!ASN1_OCTET_STRING_set(cid->hash, cert_hash, sizeof(cert_hash))) | ||
860 | goto err; | 864 | goto err; |
861 | 865 | ||
862 | /* Setting the issuer/serial if requested. */ | 866 | /* Setting the issuer/serial if requested. */ |
diff --git a/src/lib/libcrypto/ts/ts_rsp_verify.c b/src/lib/libcrypto/ts/ts_rsp_verify.c index 2e72ff47ae..07578945cb 100644 --- a/src/lib/libcrypto/ts/ts_rsp_verify.c +++ b/src/lib/libcrypto/ts/ts_rsp_verify.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ts_rsp_verify.c,v 1.22 2021/11/01 20:53:08 tb Exp $ */ | 1 | /* $OpenBSD: ts_rsp_verify.c,v 1.23 2021/11/04 23:52:34 beck Exp $ */ |
2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | 2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL |
3 | * project 2002. | 3 | * project 2002. |
4 | */ | 4 | */ |
@@ -325,10 +325,14 @@ static int | |||
325 | TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) | 325 | TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) |
326 | { | 326 | { |
327 | int i; | 327 | int i; |
328 | unsigned char cert_hash[TS_HASH_LEN]; | ||
328 | 329 | ||
329 | if (!cert_ids || !cert) | 330 | if (!cert_ids || !cert) |
330 | return -1; | 331 | return -1; |
331 | 332 | ||
333 | if (!X509_digest(cert, TS_HASH_EVP, cert_hash, NULL)) | ||
334 | return -1; | ||
335 | |||
332 | /* Recompute SHA1 hash of certificate if necessary (side effect). */ | 336 | /* Recompute SHA1 hash of certificate if necessary (side effect). */ |
333 | X509_check_purpose(cert, -1, 0); | 337 | X509_check_purpose(cert, -1, 0); |
334 | 338 | ||
@@ -337,9 +341,8 @@ TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) | |||
337 | ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); | 341 | ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); |
338 | 342 | ||
339 | /* Check the SHA-1 hash first. */ | 343 | /* Check the SHA-1 hash first. */ |
340 | if (cid->hash->length == sizeof(cert->sha1_hash) && | 344 | if (cid->hash->length == TS_HASH_LEN && !memcmp(cid->hash->data, |
341 | !memcmp(cid->hash->data, cert->sha1_hash, | 345 | cert_hash, TS_HASH_LEN)) { |
342 | sizeof(cert->sha1_hash))) { | ||
343 | /* Check the issuer/serial as well if specified. */ | 346 | /* Check the issuer/serial as well if specified. */ |
344 | ESS_ISSUER_SERIAL *is = cid->issuer_serial; | 347 | ESS_ISSUER_SERIAL *is = cid->issuer_serial; |
345 | if (!is || !TS_issuer_serial_cmp(is, cert->cert_info)) | 348 | if (!is || !TS_issuer_serial_cmp(is, cert->cert_info)) |
diff --git a/src/lib/libcrypto/x509/x509_cmp.c b/src/lib/libcrypto/x509/x509_cmp.c index 134a082730..bc944b71d7 100644 --- a/src/lib/libcrypto/x509/x509_cmp.c +++ b/src/lib/libcrypto/x509/x509_cmp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_cmp.c,v 1.36 2021/11/01 20:53:08 tb Exp $ */ | 1 | /* $OpenBSD: x509_cmp.c,v 1.37 2021/11/04 23:52:34 beck Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -215,7 +215,7 @@ X509_cmp(const X509 *a, const X509 *b) | |||
215 | X509_check_purpose((X509 *)a, -1, 0); | 215 | X509_check_purpose((X509 *)a, -1, 0); |
216 | X509_check_purpose((X509 *)b, -1, 0); | 216 | X509_check_purpose((X509 *)b, -1, 0); |
217 | 217 | ||
218 | return memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); | 218 | return memcmp(a->hash, b->hash, X509_CERT_HASH_LEN); |
219 | } | 219 | } |
220 | #endif | 220 | #endif |
221 | 221 | ||
diff --git a/src/lib/libcrypto/x509/x509_internal.h b/src/lib/libcrypto/x509/x509_internal.h index 7ca67a853b..a9b584b13e 100644 --- a/src/lib/libcrypto/x509/x509_internal.h +++ b/src/lib/libcrypto/x509/x509_internal.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_internal.h,v 1.14 2021/11/01 20:53:08 tb Exp $ */ | 1 | /* $OpenBSD: x509_internal.h,v 1.15 2021/11/04 23:52:34 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
4 | * | 4 | * |
@@ -96,8 +96,7 @@ int x509_vfy_callback_indicate_success(X509_STORE_CTX *ctx); | |||
96 | void x509v3_cache_extensions(X509 *x); | 96 | void x509v3_cache_extensions(X509 *x); |
97 | X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x); | 97 | X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x); |
98 | 98 | ||
99 | int x509_verify_asn1_time_to_tm(const ASN1_TIME *atime, struct tm *tm, | 99 | time_t x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notafter); |
100 | int notafter); | ||
101 | 100 | ||
102 | struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc); | 101 | struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc); |
103 | 102 | ||
@@ -132,6 +131,7 @@ int x509_constraints_check(struct x509_constraints_names *names, | |||
132 | struct x509_constraints_names *excluded, int *error); | 131 | struct x509_constraints_names *excluded, int *error); |
133 | int x509_constraints_chain(STACK_OF(X509) *chain, int *error, | 132 | int x509_constraints_chain(STACK_OF(X509) *chain, int *error, |
134 | int *depth); | 133 | int *depth); |
134 | void x509_verify_cert_info_populate(X509 *cert); | ||
135 | 135 | ||
136 | __END_HIDDEN_DECLS | 136 | __END_HIDDEN_DECLS |
137 | 137 | ||
diff --git a/src/lib/libcrypto/x509/x509_lcl.h b/src/lib/libcrypto/x509/x509_lcl.h index 1b352aee78..804fff48fc 100644 --- a/src/lib/libcrypto/x509/x509_lcl.h +++ b/src/lib/libcrypto/x509/x509_lcl.h | |||
@@ -61,6 +61,12 @@ | |||
61 | 61 | ||
62 | __BEGIN_HIDDEN_DECLS | 62 | __BEGIN_HIDDEN_DECLS |
63 | 63 | ||
64 | #define TS_HASH_EVP EVP_sha1() | ||
65 | #define TS_HASH_LEN SHA_DIGEST_LENGTH | ||
66 | |||
67 | #define X509_CERT_HASH_EVP EVP_sha512() | ||
68 | #define X509_CERT_HASH_LEN SHA512_DIGEST_LENGTH | ||
69 | |||
64 | struct X509_pubkey_st { | 70 | struct X509_pubkey_st { |
65 | X509_ALGOR *algor; | 71 | X509_ALGOR *algor; |
66 | ASN1_BIT_STRING *public_key; | 72 | ASN1_BIT_STRING *public_key; |
@@ -177,9 +183,9 @@ struct x509_st { | |||
177 | STACK_OF(IPAddressFamily) *rfc3779_addr; | 183 | STACK_OF(IPAddressFamily) *rfc3779_addr; |
178 | struct ASIdentifiers_st *rfc3779_asid; | 184 | struct ASIdentifiers_st *rfc3779_asid; |
179 | #endif | 185 | #endif |
180 | #ifndef OPENSSL_NO_SHA | 186 | unsigned char hash[X509_CERT_HASH_LEN]; |
181 | unsigned char sha1_hash[SHA_DIGEST_LENGTH]; | 187 | time_t not_before; |
182 | #endif | 188 | time_t not_after; |
183 | X509_CERT_AUX *aux; | 189 | X509_CERT_AUX *aux; |
184 | } /* X509 */; | 190 | } /* X509 */; |
185 | 191 | ||
diff --git a/src/lib/libcrypto/x509/x509_purp.c b/src/lib/libcrypto/x509/x509_purp.c index 67a7b51fb1..a05c0388ac 100644 --- a/src/lib/libcrypto/x509/x509_purp.c +++ b/src/lib/libcrypto/x509/x509_purp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_purp.c,v 1.12 2021/11/01 20:53:08 tb Exp $ */ | 1 | /* $OpenBSD: x509_purp.c,v 1.13 2021/11/04 23:52:34 beck Exp $ */ |
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 | * project 2001. | 3 | * project 2001. |
4 | */ | 4 | */ |
@@ -65,6 +65,7 @@ | |||
65 | #include <openssl/x509v3.h> | 65 | #include <openssl/x509v3.h> |
66 | #include <openssl/x509_vfy.h> | 66 | #include <openssl/x509_vfy.h> |
67 | 67 | ||
68 | #include "x509_internal.h" | ||
68 | #include "x509_lcl.h" | 69 | #include "x509_lcl.h" |
69 | 70 | ||
70 | #define V1_ROOT (EXFLAG_V1|EXFLAG_SS) | 71 | #define V1_ROOT (EXFLAG_V1|EXFLAG_SS) |
@@ -449,9 +450,7 @@ x509v3_cache_extensions(X509 *x) | |||
449 | if (x->ex_flags & EXFLAG_SET) | 450 | if (x->ex_flags & EXFLAG_SET) |
450 | return; | 451 | return; |
451 | 452 | ||
452 | #ifndef OPENSSL_NO_SHA | 453 | X509_digest(x, X509_CERT_HASH_EVP, x->hash, NULL); |
453 | X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); | ||
454 | #endif | ||
455 | 454 | ||
456 | /* V1 should mean no extensions ... */ | 455 | /* V1 should mean no extensions ... */ |
457 | if (!X509_get_version(x)) | 456 | if (!X509_get_version(x)) |
@@ -618,6 +617,9 @@ x509v3_cache_extensions(X509 *x) | |||
618 | break; | 617 | break; |
619 | } | 618 | } |
620 | } | 619 | } |
620 | |||
621 | x509_verify_cert_info_populate(x); | ||
622 | |||
621 | x->ex_flags |= EXFLAG_SET; | 623 | x->ex_flags |= EXFLAG_SET; |
622 | } | 624 | } |
623 | 625 | ||
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c index 8bcc647149..b9ba2bee3c 100644 --- a/src/lib/libcrypto/x509/x509_verify.c +++ b/src/lib/libcrypto/x509/x509_verify.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_verify.c,v 1.50 2021/10/26 15:14:18 job Exp $ */ | 1 | /* $OpenBSD: x509_verify.c,v 1.51 2021/11/04 23:52:34 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> |
4 | * | 4 | * |
@@ -38,7 +38,58 @@ static int x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, | |||
38 | size_t depth, int error, int ok); | 38 | size_t depth, int error, int ok); |
39 | static void x509_verify_chain_free(struct x509_verify_chain *chain); | 39 | static void x509_verify_chain_free(struct x509_verify_chain *chain); |
40 | 40 | ||
41 | #define X509_VERIFY_CERT_HASH (EVP_sha512()) | 41 | /* |
42 | * Parse an asn1 to a representable time_t as per RFC 5280 rules. | ||
43 | * Returns -1 if that can't be done for any reason. | ||
44 | */ | ||
45 | time_t | ||
46 | x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notAfter) | ||
47 | { | ||
48 | struct tm tm = { 0 }; | ||
49 | int type; | ||
50 | |||
51 | type = ASN1_time_parse(atime->data, atime->length, &tm, atime->type); | ||
52 | if (type == -1) | ||
53 | return -1; | ||
54 | |||
55 | /* RFC 5280 section 4.1.2.5 */ | ||
56 | if (tm.tm_year < 150 && type != V_ASN1_UTCTIME) | ||
57 | return -1; | ||
58 | if (tm.tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME) | ||
59 | return -1; | ||
60 | |||
61 | if (notAfter) { | ||
62 | /* | ||
63 | * If we are a completely broken operating system with a | ||
64 | * 32 bit time_t, and we have been told this is a notAfter | ||
65 | * date, limit the date to a 32 bit representable value. | ||
66 | */ | ||
67 | if (!ASN1_time_tm_clamp_notafter(&tm)) | ||
68 | return -1; | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * Defensively fail if the time string is not representable as | ||
73 | * a time_t. A time_t must be sane if you care about times after | ||
74 | * Jan 19 2038. | ||
75 | */ | ||
76 | return timegm(&tm); | ||
77 | } | ||
78 | |||
79 | /* | ||
80 | * Cache certificate hash, and values parsed out of an X509. | ||
81 | * called from cache_extensions() | ||
82 | */ | ||
83 | void | ||
84 | x509_verify_cert_info_populate(X509 *cert) | ||
85 | { | ||
86 | /* | ||
87 | * Parse and save the cert times, or remember that they | ||
88 | * are unacceptable/unparsable. | ||
89 | */ | ||
90 | cert->not_before = x509_verify_asn1_time_to_time_t(X509_get_notBefore(cert), 0); | ||
91 | cert->not_after = x509_verify_asn1_time_to_time_t(X509_get_notAfter(cert), 1); | ||
92 | } | ||
42 | 93 | ||
43 | struct x509_verify_chain * | 94 | struct x509_verify_chain * |
44 | x509_verify_chain_new(void) | 95 | x509_verify_chain_new(void) |
@@ -194,6 +245,7 @@ x509_verify_cert_cache_extensions(X509 *cert) { | |||
194 | } | 245 | } |
195 | if (cert->ex_flags & EXFLAG_INVALID) | 246 | if (cert->ex_flags & EXFLAG_INVALID) |
196 | return 0; | 247 | return 0; |
248 | |||
197 | return (cert->ex_flags & EXFLAG_SET); | 249 | return (cert->ex_flags & EXFLAG_SET); |
198 | } | 250 | } |
199 | 251 | ||
@@ -455,22 +507,15 @@ x509_verify_potential_parent(struct x509_verify_ctx *ctx, X509 *parent, | |||
455 | } | 507 | } |
456 | 508 | ||
457 | static int | 509 | static int |
458 | x509_verify_parent_signature(X509 *parent, X509 *child, | 510 | x509_verify_parent_signature(X509 *parent, X509 *child, int *error) |
459 | unsigned char *child_md, int *error) | ||
460 | { | 511 | { |
461 | unsigned char parent_md[EVP_MAX_MD_SIZE] = { 0 }; | ||
462 | EVP_PKEY *pkey; | 512 | EVP_PKEY *pkey; |
463 | int cached; | 513 | int cached; |
464 | int ret = 0; | 514 | int ret = 0; |
465 | 515 | ||
466 | /* Use cached value if we have it */ | 516 | /* Use cached value if we have it */ |
467 | if (child_md != NULL) { | 517 | if ((cached = x509_issuer_cache_find(parent->hash, child->hash)) >= 0) |
468 | if (!X509_digest(parent, X509_VERIFY_CERT_HASH, parent_md, | 518 | return cached; |
469 | NULL)) | ||
470 | return 0; | ||
471 | if ((cached = x509_issuer_cache_find(parent_md, child_md)) >= 0) | ||
472 | return cached; | ||
473 | } | ||
474 | 519 | ||
475 | /* Check signature. Did parent sign child? */ | 520 | /* Check signature. Did parent sign child? */ |
476 | if ((pkey = X509_get_pubkey(parent)) == NULL) { | 521 | if ((pkey = X509_get_pubkey(parent)) == NULL) { |
@@ -483,8 +528,7 @@ x509_verify_parent_signature(X509 *parent, X509 *child, | |||
483 | ret = 1; | 528 | ret = 1; |
484 | 529 | ||
485 | /* Add result to cache */ | 530 | /* Add result to cache */ |
486 | if (child_md != NULL) | 531 | x509_issuer_cache_add(parent->hash, child->hash, ret); |
487 | x509_issuer_cache_add(parent_md, child_md, ret); | ||
488 | 532 | ||
489 | EVP_PKEY_free(pkey); | 533 | EVP_PKEY_free(pkey); |
490 | 534 | ||
@@ -493,8 +537,8 @@ x509_verify_parent_signature(X509 *parent, X509 *child, | |||
493 | 537 | ||
494 | static int | 538 | static int |
495 | x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, | 539 | x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, |
496 | unsigned char *cert_md, int is_root_cert, X509 *candidate, | 540 | int is_root_cert, X509 *candidate, struct x509_verify_chain *current_chain, |
497 | struct x509_verify_chain *current_chain, int full_chain) | 541 | int full_chain) |
498 | { | 542 | { |
499 | int depth = sk_X509_num(current_chain->certs); | 543 | int depth = sk_X509_num(current_chain->certs); |
500 | struct x509_verify_chain *new_chain; | 544 | struct x509_verify_chain *new_chain; |
@@ -514,8 +558,7 @@ x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, | |||
514 | return 0; | 558 | return 0; |
515 | } | 559 | } |
516 | 560 | ||
517 | if (!x509_verify_parent_signature(candidate, cert, cert_md, | 561 | if (!x509_verify_parent_signature(candidate, cert, &ctx->error)) { |
518 | &ctx->error)) { | ||
519 | if (!x509_verify_cert_error(ctx, candidate, depth, | 562 | if (!x509_verify_cert_error(ctx, candidate, depth, |
520 | ctx->error, 0)) | 563 | ctx->error, 0)) |
521 | return 0; | 564 | return 0; |
@@ -579,7 +622,6 @@ static void | |||
579 | x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | 622 | x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, |
580 | struct x509_verify_chain *current_chain, int full_chain) | 623 | struct x509_verify_chain *current_chain, int full_chain) |
581 | { | 624 | { |
582 | unsigned char cert_md[EVP_MAX_MD_SIZE] = { 0 }; | ||
583 | X509 *candidate; | 625 | X509 *candidate; |
584 | int i, depth, count, ret, is_root; | 626 | int i, depth, count, ret, is_root; |
585 | 627 | ||
@@ -600,11 +642,6 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
600 | X509_V_ERR_CERT_CHAIN_TOO_LONG, 0)) | 642 | X509_V_ERR_CERT_CHAIN_TOO_LONG, 0)) |
601 | return; | 643 | return; |
602 | 644 | ||
603 | if (!X509_digest(cert, X509_VERIFY_CERT_HASH, cert_md, NULL) && | ||
604 | !x509_verify_cert_error(ctx, cert, depth, | ||
605 | X509_V_ERR_UNSPECIFIED, 0)) | ||
606 | return; | ||
607 | |||
608 | count = ctx->chains_count; | 645 | count = ctx->chains_count; |
609 | 646 | ||
610 | ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; | 647 | ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; |
@@ -640,7 +677,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
640 | is_root = !full_chain || | 677 | is_root = !full_chain || |
641 | x509_verify_cert_self_signed(candidate); | 678 | x509_verify_cert_self_signed(candidate); |
642 | x509_verify_consider_candidate(ctx, cert, | 679 | x509_verify_consider_candidate(ctx, cert, |
643 | cert_md, is_root, candidate, current_chain, | 680 | is_root, candidate, current_chain, |
644 | full_chain); | 681 | full_chain); |
645 | } | 682 | } |
646 | X509_free(candidate); | 683 | X509_free(candidate); |
@@ -653,7 +690,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
653 | is_root = !full_chain || | 690 | is_root = !full_chain || |
654 | x509_verify_cert_self_signed(candidate); | 691 | x509_verify_cert_self_signed(candidate); |
655 | x509_verify_consider_candidate(ctx, cert, | 692 | x509_verify_consider_candidate(ctx, cert, |
656 | cert_md, is_root, candidate, current_chain, | 693 | is_root, candidate, current_chain, |
657 | full_chain); | 694 | full_chain); |
658 | } | 695 | } |
659 | } | 696 | } |
@@ -665,7 +702,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
665 | candidate = sk_X509_value(ctx->intermediates, i); | 702 | candidate = sk_X509_value(ctx->intermediates, i); |
666 | if (x509_verify_potential_parent(ctx, candidate, cert)) { | 703 | if (x509_verify_potential_parent(ctx, candidate, cert)) { |
667 | x509_verify_consider_candidate(ctx, cert, | 704 | x509_verify_consider_candidate(ctx, cert, |
668 | cert_md, 0, candidate, current_chain, | 705 | 0, candidate, current_chain, |
669 | full_chain); | 706 | full_chain); |
670 | } | 707 | } |
671 | } | 708 | } |
@@ -748,47 +785,9 @@ x509_verify_set_check_time(struct x509_verify_ctx *ctx) { | |||
748 | return 1; | 785 | return 1; |
749 | } | 786 | } |
750 | 787 | ||
751 | int | ||
752 | x509_verify_asn1_time_to_tm(const ASN1_TIME *atime, struct tm *tm, int notafter) | ||
753 | { | ||
754 | int type; | ||
755 | |||
756 | type = ASN1_time_parse(atime->data, atime->length, tm, atime->type); | ||
757 | if (type == -1) | ||
758 | return 0; | ||
759 | |||
760 | /* RFC 5280 section 4.1.2.5 */ | ||
761 | if (tm->tm_year < 150 && type != V_ASN1_UTCTIME) | ||
762 | return 0; | ||
763 | if (tm->tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME) | ||
764 | return 0; | ||
765 | |||
766 | if (notafter) { | ||
767 | /* | ||
768 | * If we are a completely broken operating system with a | ||
769 | * 32 bit time_t, and we have been told this is a notafter | ||
770 | * date, limit the date to a 32 bit representable value. | ||
771 | */ | ||
772 | if (!ASN1_time_tm_clamp_notafter(tm)) | ||
773 | return 0; | ||
774 | } | ||
775 | |||
776 | /* | ||
777 | * Defensively fail if the time string is not representable as | ||
778 | * a time_t. A time_t must be sane if you care about times after | ||
779 | * Jan 19 2038. | ||
780 | */ | ||
781 | if (timegm(tm) == -1) | ||
782 | return 0; | ||
783 | |||
784 | return 1; | ||
785 | } | ||
786 | |||
787 | static int | 788 | static int |
788 | x509_verify_cert_time(int is_notafter, const ASN1_TIME *cert_asn1, | 789 | x509_verify_cert_times(X509 *cert, time_t *cmp_time, int *error) |
789 | time_t *cmp_time, int *error) | ||
790 | { | 790 | { |
791 | struct tm cert_tm, when_tm; | ||
792 | time_t when; | 791 | time_t when; |
793 | 792 | ||
794 | if (cmp_time == NULL) | 793 | if (cmp_time == NULL) |
@@ -796,29 +795,21 @@ x509_verify_cert_time(int is_notafter, const ASN1_TIME *cert_asn1, | |||
796 | else | 795 | else |
797 | when = *cmp_time; | 796 | when = *cmp_time; |
798 | 797 | ||
799 | if (!x509_verify_asn1_time_to_tm(cert_asn1, &cert_tm, | 798 | if (cert->not_before == -1) { |
800 | is_notafter)) { | 799 | *error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; |
801 | *error = is_notafter ? | ||
802 | X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD : | ||
803 | X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; | ||
804 | return 0; | 800 | return 0; |
805 | } | 801 | } |
806 | 802 | if (when < cert->not_before) { | |
807 | if (gmtime_r(&when, &when_tm) == NULL) { | 803 | *error = X509_V_ERR_CERT_NOT_YET_VALID; |
808 | *error = X509_V_ERR_UNSPECIFIED; | ||
809 | return 0; | 804 | return 0; |
810 | } | 805 | } |
811 | 806 | if (cert->not_after == -1) { | |
812 | if (is_notafter) { | 807 | *error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; |
813 | if (ASN1_time_tm_cmp(&cert_tm, &when_tm) == -1) { | 808 | return 0; |
814 | *error = X509_V_ERR_CERT_HAS_EXPIRED; | 809 | } |
815 | return 0; | 810 | if (when > cert->not_after) { |
816 | } | 811 | *error = X509_V_ERR_CERT_HAS_EXPIRED; |
817 | } else { | 812 | return 0; |
818 | if (ASN1_time_tm_cmp(&cert_tm, &when_tm) == 1) { | ||
819 | *error = X509_V_ERR_CERT_NOT_YET_VALID; | ||
820 | return 0; | ||
821 | } | ||
822 | } | 813 | } |
823 | 814 | ||
824 | return 1; | 815 | return 1; |
@@ -924,15 +915,8 @@ x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert, | |||
924 | } | 915 | } |
925 | 916 | ||
926 | if (x509_verify_set_check_time(ctx)) { | 917 | if (x509_verify_set_check_time(ctx)) { |
927 | if (!x509_verify_cert_time(0, X509_get_notBefore(cert), | 918 | if (!x509_verify_cert_times(cert, ctx->check_time, |
928 | ctx->check_time, &ctx->error)) { | 919 | &ctx->error)) { |
929 | if (!x509_verify_cert_error(ctx, cert, depth, | ||
930 | ctx->error, 0)) | ||
931 | return 0; | ||
932 | } | ||
933 | |||
934 | if (!x509_verify_cert_time(1, X509_get_notAfter(cert), | ||
935 | ctx->check_time, &ctx->error)) { | ||
936 | if (!x509_verify_cert_error(ctx, cert, depth, | 920 | if (!x509_verify_cert_error(ctx, cert, depth, |
937 | ctx->error, 0)) | 921 | ctx->error, 0)) |
938 | return 0; | 922 | return 0; |
diff --git a/src/lib/libcrypto/x509/x509_verify.h b/src/lib/libcrypto/x509/x509_verify.h index a097404f2e..d8d2cb0b5f 100644 --- a/src/lib/libcrypto/x509/x509_verify.h +++ b/src/lib/libcrypto/x509/x509_verify.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_verify.h,v 1.1 2020/09/13 15:06:17 beck Exp $ */ | 1 | /* $OpenBSD: x509_verify.h,v 1.2 2021/11/04 23:52:34 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
4 | * | 4 | * |
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #ifdef LIBRESSL_INTERNAL | 20 | #ifdef LIBRESSL_INTERNAL |
21 | struct x509_verify_ctx; | 21 | struct x509_verify_ctx; |
22 | struct x509_verify_cert_info; | ||
22 | typedef struct x509_verify_ctx X509_VERIFY_CTX; | 23 | typedef struct x509_verify_ctx X509_VERIFY_CTX; |
23 | 24 | ||
24 | X509_VERIFY_CTX *x509_verify_ctx_new(STACK_OF(X509) *roots); | 25 | X509_VERIFY_CTX *x509_verify_ctx_new(STACK_OF(X509) *roots); |
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index 664474139c..3b0d6dfa35 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_vfy.c,v 1.93 2021/11/01 20:53:08 tb Exp $ */ | 1 | /* $OpenBSD: x509_vfy.c,v 1.94 2021/11/04 23:52:34 beck Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1843,6 +1843,18 @@ verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err) | |||
1843 | return ctx->verify_cb(0, ctx); | 1843 | return ctx->verify_cb(0, ctx); |
1844 | } | 1844 | } |
1845 | 1845 | ||
1846 | |||
1847 | /* Mimic OpenSSL '0 for failure' ick */ | ||
1848 | static int | ||
1849 | time_t_bogocmp(time_t a, time_t b) | ||
1850 | { | ||
1851 | if (a == -1 || b == -1) | ||
1852 | return 0; | ||
1853 | if (a <= b) | ||
1854 | return -1; | ||
1855 | return 1; | ||
1856 | } | ||
1857 | |||
1846 | /* | 1858 | /* |
1847 | * Check certificate validity times. | 1859 | * Check certificate validity times. |
1848 | * | 1860 | * |
@@ -1854,17 +1866,21 @@ verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err) | |||
1854 | int | 1866 | int |
1855 | x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) | 1867 | x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) |
1856 | { | 1868 | { |
1857 | time_t *ptime; | 1869 | time_t ptime; |
1858 | int i; | 1870 | int i; |
1859 | 1871 | ||
1860 | if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) | 1872 | if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) |
1861 | ptime = &ctx->param->check_time; | 1873 | ptime = ctx->param->check_time; |
1862 | else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) | 1874 | else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) |
1863 | return 1; | 1875 | return 1; |
1864 | else | 1876 | else |
1865 | ptime = NULL; | 1877 | ptime = time(NULL); |
1878 | |||
1879 | if (x->ex_flags & EXFLAG_SET) | ||
1880 | i = time_t_bogocmp(x->not_before, ptime); | ||
1881 | else | ||
1882 | i = X509_cmp_time(X509_get_notBefore(x), &ptime); | ||
1866 | 1883 | ||
1867 | i = X509_cmp_time(X509_get_notBefore(x), ptime); | ||
1868 | if (i >= 0 && depth < 0) | 1884 | if (i >= 0 && depth < 0) |
1869 | return 0; | 1885 | return 0; |
1870 | if (i == 0 && !verify_cb_cert(ctx, x, depth, | 1886 | if (i == 0 && !verify_cb_cert(ctx, x, depth, |
@@ -1874,7 +1890,11 @@ x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) | |||
1874 | X509_V_ERR_CERT_NOT_YET_VALID)) | 1890 | X509_V_ERR_CERT_NOT_YET_VALID)) |
1875 | return 0; | 1891 | return 0; |
1876 | 1892 | ||
1877 | i = X509_cmp_time_internal(X509_get_notAfter(x), ptime, 1); | 1893 | if (x->ex_flags & EXFLAG_SET) |
1894 | i = time_t_bogocmp(x->not_after, ptime); | ||
1895 | else | ||
1896 | i = X509_cmp_time_internal(X509_get_notAfter(x), &ptime, 1); | ||
1897 | |||
1878 | if (i <= 0 && depth < 0) | 1898 | if (i <= 0 && depth < 0) |
1879 | return 0; | 1899 | return 0; |
1880 | if (i == 0 && !verify_cb_cert(ctx, x, depth, | 1900 | if (i == 0 && !verify_cb_cert(ctx, x, depth, |
@@ -1883,6 +1903,7 @@ x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) | |||
1883 | if (i < 0 && !verify_cb_cert(ctx, x, depth, | 1903 | if (i < 0 && !verify_cb_cert(ctx, x, depth, |
1884 | X509_V_ERR_CERT_HAS_EXPIRED)) | 1904 | X509_V_ERR_CERT_HAS_EXPIRED)) |
1885 | return 0; | 1905 | return 0; |
1906 | |||
1886 | return 1; | 1907 | return 1; |
1887 | } | 1908 | } |
1888 | 1909 | ||
@@ -1994,30 +2015,23 @@ X509_cmp_current_time(const ASN1_TIME *ctm) | |||
1994 | * 0 on error. | 2015 | * 0 on error. |
1995 | */ | 2016 | */ |
1996 | static int | 2017 | static int |
1997 | X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, int clamp_notafter) | 2018 | X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, int is_notafter) |
1998 | { | 2019 | { |
1999 | time_t compare; | 2020 | time_t compare, cert_time; |
2000 | struct tm tm1, tm2; | ||
2001 | int ret = 0; | ||
2002 | 2021 | ||
2003 | if (cmp_time == NULL) | 2022 | if (cmp_time == NULL) |
2004 | compare = time(NULL); | 2023 | compare = time(NULL); |
2005 | else | 2024 | else |
2006 | compare = *cmp_time; | 2025 | compare = *cmp_time; |
2007 | 2026 | ||
2008 | memset(&tm1, 0, sizeof(tm1)); | 2027 | if ((cert_time = x509_verify_asn1_time_to_time_t(ctm, is_notafter)) == |
2028 | -1) | ||
2029 | return 0; /* invalid time */ | ||
2009 | 2030 | ||
2010 | if (!x509_verify_asn1_time_to_tm(ctm, &tm1, clamp_notafter)) | 2031 | if (cert_time <= compare) |
2011 | goto out; /* invalid time */ | 2032 | return -1; /* 0 is used for error, so map same to less than */ |
2012 | 2033 | ||
2013 | if (gmtime_r(&compare, &tm2) == NULL) | 2034 | return 1; |
2014 | goto out; | ||
2015 | |||
2016 | ret = ASN1_time_tm_cmp(&tm1, &tm2); | ||
2017 | if (ret == 0) | ||
2018 | ret = -1; /* 0 is used for error, so map same to less than */ | ||
2019 | out: | ||
2020 | return (ret); | ||
2021 | } | 2035 | } |
2022 | 2036 | ||
2023 | int | 2037 | int |