summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbeck <>2021-11-04 23:52:34 +0000
committerbeck <>2021-11-04 23:52:34 +0000
commit244374d8dda906a87c40f39a8ed949cf07a1c8f3 (patch)
tree3ca9bd91a3930e5f3e28873aa362dffdb8cf6227
parentb866948734d2d995d78efdc04fb93574782722fa (diff)
downloadopenbsd-244374d8dda906a87c40f39a8ed949cf07a1c8f3.tar.gz
openbsd-244374d8dda906a87c40f39a8ed949cf07a1c8f3.tar.bz2
openbsd-244374d8dda906a87c40f39a8ed949cf07a1c8f3.zip
Cache sha512 hash and parsed not_before and not_after with X509 cert.
Replace sha1 hash use with sha512 for certificate comparisons internal to the library. use the cached sha512 for the validator's verification cache. Reduces our recomputation of hashes, and heavy use of time1 time conversion functions noticed bu claudio@ in rpki client. ok jsing@ tb@
-rw-r--r--src/lib/libcrypto/ts/ts_rsp_sign.c10
-rw-r--r--src/lib/libcrypto/ts/ts_rsp_verify.c11
-rw-r--r--src/lib/libcrypto/x509/x509_cmp.c4
-rw-r--r--src/lib/libcrypto/x509/x509_internal.h6
-rw-r--r--src/lib/libcrypto/x509/x509_lcl.h12
-rw-r--r--src/lib/libcrypto/x509/x509_purp.c10
-rw-r--r--src/lib/libcrypto/x509/x509_verify.c172
-rw-r--r--src/lib/libcrypto/x509/x509_verify.h3
-rw-r--r--src/lib/libcrypto/x509/x509_vfy.c56
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
325TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) 325TS_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);
96void x509v3_cache_extensions(X509 *x); 96void x509v3_cache_extensions(X509 *x);
97X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x); 97X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x);
98 98
99int x509_verify_asn1_time_to_tm(const ASN1_TIME *atime, struct tm *tm, 99time_t x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notafter);
100 int notafter);
101 100
102struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc); 101struct 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);
133int x509_constraints_chain(STACK_OF(X509) *chain, int *error, 132int x509_constraints_chain(STACK_OF(X509) *chain, int *error,
134 int *depth); 133 int *depth);
134void 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
64struct X509_pubkey_st { 70struct 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);
39static void x509_verify_chain_free(struct x509_verify_chain *chain); 39static 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 */
45time_t
46x509_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 */
83void
84x509_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
43struct x509_verify_chain * 94struct x509_verify_chain *
44x509_verify_chain_new(void) 95x509_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
457static int 509static int
458x509_verify_parent_signature(X509 *parent, X509 *child, 510x509_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
494static int 538static int
495x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, 539x509_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
579x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, 622x509_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
751int
752x509_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
787static int 788static int
788x509_verify_cert_time(int is_notafter, const ASN1_TIME *cert_asn1, 789x509_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
21struct x509_verify_ctx; 21struct x509_verify_ctx;
22struct x509_verify_cert_info;
22typedef struct x509_verify_ctx X509_VERIFY_CTX; 23typedef struct x509_verify_ctx X509_VERIFY_CTX;
23 24
24X509_VERIFY_CTX *x509_verify_ctx_new(STACK_OF(X509) *roots); 25X509_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 */
1848static int
1849time_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)
1854int 1866int
1855x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) 1867x509_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 */
1996static int 2017static int
1997X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, int clamp_notafter) 2018X509_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
2023int 2037int