Skip to content
Snippets Groups Projects
Commit 0b4221f9 authored by Nick Mathewson's avatar Nick Mathewson :game_die:
Browse files

Make the current time an argument to x509 cert-checking functions

This makes the code a bit cleaner by having more of the functions be
pure functions that don't depend on the current time.
parent e3c82537
No related branches found
No related tags found
No related merge requests found
...@@ -136,6 +136,7 @@ static void tor_tls_context_decref(tor_tls_context_t *ctx); ...@@ -136,6 +136,7 @@ static void tor_tls_context_decref(tor_tls_context_t *ctx);
static void tor_tls_context_incref(tor_tls_context_t *ctx); static void tor_tls_context_incref(tor_tls_context_t *ctx);
static int check_cert_lifetime_internal(int severity, const X509 *cert, static int check_cert_lifetime_internal(int severity, const X509 *cert,
time_t now,
int past_tolerance, int future_tolerance); int past_tolerance, int future_tolerance);
/** Global TLS contexts. We keep them here because nobody else needs /** Global TLS contexts. We keep them here because nobody else needs
...@@ -860,6 +861,7 @@ int ...@@ -860,6 +861,7 @@ int
tor_tls_cert_is_valid(int severity, tor_tls_cert_is_valid(int severity,
const tor_x509_cert_t *cert, const tor_x509_cert_t *cert,
const tor_x509_cert_t *signing_cert, const tor_x509_cert_t *signing_cert,
time_t now,
int check_rsa_1024) int check_rsa_1024)
{ {
check_no_tls_errors(); check_no_tls_errors();
...@@ -879,7 +881,7 @@ tor_tls_cert_is_valid(int severity, ...@@ -879,7 +881,7 @@ tor_tls_cert_is_valid(int severity,
/* okay, the signature checked out right. Now let's check the check the /* okay, the signature checked out right. Now let's check the check the
* lifetime. */ * lifetime. */
if (check_cert_lifetime_internal(severity, cert->cert, if (check_cert_lifetime_internal(severity, cert->cert, now,
48*60*60, 30*24*60*60) < 0) 48*60*60, 30*24*60*60) < 0)
goto bad; goto bad;
...@@ -2028,13 +2030,13 @@ tor_tls_get_peer_cert,(tor_tls_t *tls)) ...@@ -2028,13 +2030,13 @@ tor_tls_get_peer_cert,(tor_tls_t *tls))
/** Warn that a certificate lifetime extends through a certain range. */ /** Warn that a certificate lifetime extends through a certain range. */
static void static void
log_cert_lifetime(int severity, const X509 *cert, const char *problem) log_cert_lifetime(int severity, const X509 *cert, const char *problem,
time_t now)
{ {
BIO *bio = NULL; BIO *bio = NULL;
BUF_MEM *buf; BUF_MEM *buf;
char *s1=NULL, *s2=NULL; char *s1=NULL, *s2=NULL;
char mytime[33]; char mytime[33];
time_t now = time(NULL);
struct tm tm; struct tm tm;
size_t n; size_t n;
...@@ -2182,6 +2184,7 @@ tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_t **identity_key) ...@@ -2182,6 +2184,7 @@ tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_t **identity_key)
*/ */
int int
tor_tls_check_lifetime(int severity, tor_tls_t *tls, tor_tls_check_lifetime(int severity, tor_tls_t *tls,
time_t now,
int past_tolerance, int future_tolerance) int past_tolerance, int future_tolerance)
{ {
X509 *cert; X509 *cert;
...@@ -2190,7 +2193,7 @@ tor_tls_check_lifetime(int severity, tor_tls_t *tls, ...@@ -2190,7 +2193,7 @@ tor_tls_check_lifetime(int severity, tor_tls_t *tls,
if (!(cert = SSL_get_peer_certificate(tls->ssl))) if (!(cert = SSL_get_peer_certificate(tls->ssl)))
goto done; goto done;
if (check_cert_lifetime_internal(severity, cert, if (check_cert_lifetime_internal(severity, cert, now,
past_tolerance, future_tolerance) < 0) past_tolerance, future_tolerance) < 0)
goto done; goto done;
...@@ -2206,24 +2209,24 @@ tor_tls_check_lifetime(int severity, tor_tls_t *tls, ...@@ -2206,24 +2209,24 @@ tor_tls_check_lifetime(int severity, tor_tls_t *tls,
/** Helper: check whether <b>cert</b> is expired give or take /** Helper: check whether <b>cert</b> is expired give or take
* <b>past_tolerance</b> seconds, or not-yet-valid give or take * <b>past_tolerance</b> seconds, or not-yet-valid give or take
* <b>future_tolerance</b> seconds. If it is live, return 0. If it is not * <b>future_tolerance</b> seconds. (Relative to the current time
* live, log a message and return -1. */ * <b>now</b>.) If it is live, return 0. If it is not live, log a message
* and return -1. */
static int static int
check_cert_lifetime_internal(int severity, const X509 *cert, check_cert_lifetime_internal(int severity, const X509 *cert,
time_t now,
int past_tolerance, int future_tolerance) int past_tolerance, int future_tolerance)
{ {
time_t now, t; time_t t;
now = time(NULL);
t = now + future_tolerance; t = now + future_tolerance;
if (X509_cmp_time(X509_get_notBefore_const(cert), &t) > 0) { if (X509_cmp_time(X509_get_notBefore_const(cert), &t) > 0) {
log_cert_lifetime(severity, cert, "not yet valid"); log_cert_lifetime(severity, cert, "not yet valid", now);
return -1; return -1;
} }
t = now - past_tolerance; t = now - past_tolerance;
if (X509_cmp_time(X509_get_notAfter_const(cert), &t) < 0) { if (X509_cmp_time(X509_get_notAfter_const(cert), &t) < 0) {
log_cert_lifetime(severity, cert, "already expired"); log_cert_lifetime(severity, cert, "already expired", now);
return -1; return -1;
} }
......
...@@ -200,7 +200,8 @@ int tor_tls_peer_has_cert(tor_tls_t *tls); ...@@ -200,7 +200,8 @@ int tor_tls_peer_has_cert(tor_tls_t *tls);
MOCK_DECL(tor_x509_cert_t *,tor_tls_get_peer_cert,(tor_tls_t *tls)); MOCK_DECL(tor_x509_cert_t *,tor_tls_get_peer_cert,(tor_tls_t *tls));
int tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_t **identity); int tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_t **identity);
int tor_tls_check_lifetime(int severity, int tor_tls_check_lifetime(int severity,
tor_tls_t *tls, int past_tolerance, tor_tls_t *tls, time_t now,
int past_tolerance,
int future_tolerance); int future_tolerance);
MOCK_DECL(int, tor_tls_read, (tor_tls_t *tls, char *cp, size_t len)); MOCK_DECL(int, tor_tls_read, (tor_tls_t *tls, char *cp, size_t len));
int tor_tls_write(tor_tls_t *tls, const char *cp, size_t n); int tor_tls_write(tor_tls_t *tls, const char *cp, size_t n);
...@@ -259,6 +260,7 @@ MOCK_DECL(int,tor_tls_cert_matches_key,(const tor_tls_t *tls, ...@@ -259,6 +260,7 @@ MOCK_DECL(int,tor_tls_cert_matches_key,(const tor_tls_t *tls,
int tor_tls_cert_is_valid(int severity, int tor_tls_cert_is_valid(int severity,
const tor_x509_cert_t *cert, const tor_x509_cert_t *cert,
const tor_x509_cert_t *signing_cert, const tor_x509_cert_t *signing_cert,
time_t now,
int check_rsa_1024); int check_rsa_1024);
const char *tor_tls_get_ciphersuite_name(tor_tls_t *tls); const char *tor_tls_get_ciphersuite_name(tor_tls_t *tls);
......
...@@ -1918,7 +1918,8 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan) ...@@ -1918,7 +1918,8 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
if (! or_handshake_certs_rsa_ok(severity, if (! or_handshake_certs_rsa_ok(severity,
chan->conn->handshake_state->certs, chan->conn->handshake_state->certs,
chan->conn->tls)) chan->conn->tls,
time(NULL)))
ERR("Invalid RSA certificates!"); ERR("Invalid RSA certificates!");
if (chan->conn->handshake_state->started_here) { if (chan->conn->handshake_state->started_here) {
......
...@@ -431,7 +431,8 @@ or_handshake_certs_free(or_handshake_certs_t *certs) ...@@ -431,7 +431,8 @@ or_handshake_certs_free(or_handshake_certs_t *certs)
int int
or_handshake_certs_rsa_ok(int severity, or_handshake_certs_rsa_ok(int severity,
or_handshake_certs_t *certs, or_handshake_certs_t *certs,
tor_tls_t *tls) tor_tls_t *tls,
time_t now)
{ {
tor_x509_cert_t *link_cert = certs->link_cert; tor_x509_cert_t *link_cert = certs->link_cert;
tor_x509_cert_t *auth_cert = certs->auth_cert; tor_x509_cert_t *auth_cert = certs->auth_cert;
...@@ -442,17 +443,19 @@ or_handshake_certs_rsa_ok(int severity, ...@@ -442,17 +443,19 @@ or_handshake_certs_rsa_ok(int severity,
ERR("The certs we wanted were missing"); ERR("The certs we wanted were missing");
if (! tor_tls_cert_matches_key(tls, link_cert)) if (! tor_tls_cert_matches_key(tls, link_cert))
ERR("The link certificate didn't match the TLS public key"); ERR("The link certificate didn't match the TLS public key");
if (! tor_tls_cert_is_valid(severity, link_cert, id_cert, 0)) if (! tor_tls_cert_is_valid(severity, link_cert, id_cert, now, 0))
ERR("The link certificate was not valid"); ERR("The link certificate was not valid");
if (! tor_tls_cert_is_valid(severity, id_cert, id_cert, 1)) if (! tor_tls_cert_is_valid(severity, id_cert, id_cert, now, 1))
ERR("The ID certificate was not valid"); ERR("The ID certificate was not valid");
} else { } else {
if (! (id_cert && auth_cert)) if (! (id_cert && auth_cert))
ERR("The certs we wanted were missing"); ERR("The certs we wanted were missing");
/* Remember these certificates so we can check an AUTHENTICATE cell */ /* Remember these certificates so we can check an AUTHENTICATE cell
if (! tor_tls_cert_is_valid(LOG_PROTOCOL_WARN, auth_cert, id_cert, 1)) * XXXX make sure we do that
*/
if (! tor_tls_cert_is_valid(LOG_PROTOCOL_WARN, auth_cert, id_cert, now, 1))
ERR("The authentication certificate was not valid"); ERR("The authentication certificate was not valid");
if (! tor_tls_cert_is_valid(LOG_PROTOCOL_WARN, id_cert, id_cert, 1)) if (! tor_tls_cert_is_valid(LOG_PROTOCOL_WARN, id_cert, id_cert, now, 1))
ERR("The ID certificate was not valid"); ERR("The ID certificate was not valid");
} }
......
...@@ -81,8 +81,8 @@ or_handshake_certs_t *or_handshake_certs_new(void); ...@@ -81,8 +81,8 @@ or_handshake_certs_t *or_handshake_certs_new(void);
void or_handshake_certs_free(or_handshake_certs_t *certs); void or_handshake_certs_free(or_handshake_certs_t *certs);
int or_handshake_certs_rsa_ok(int severity, int or_handshake_certs_rsa_ok(int severity,
or_handshake_certs_t *certs, or_handshake_certs_t *certs,
tor_tls_t *tls); tor_tls_t *tls,
int or_handshake_certs_ed25519_ok(or_handshake_certs_t *certs); time_t now);
#endif #endif
...@@ -1086,13 +1086,13 @@ test_tortls_check_lifetime(void *ignored) ...@@ -1086,13 +1086,13 @@ test_tortls_check_lifetime(void *ignored)
time_t now = time(NULL); time_t now = time(NULL);
tls = tor_malloc_zero(sizeof(tor_tls_t)); tls = tor_malloc_zero(sizeof(tor_tls_t));
ret = tor_tls_check_lifetime(LOG_WARN, tls, 0, 0); ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), 0, 0);
tt_int_op(ret, OP_EQ, -1); tt_int_op(ret, OP_EQ, -1);
tls->ssl = tor_malloc_zero(sizeof(SSL)); tls->ssl = tor_malloc_zero(sizeof(SSL));
tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION)); tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
tls->ssl->session->peer = validCert; tls->ssl->session->peer = validCert;
ret = tor_tls_check_lifetime(LOG_WARN, tls, 0, 0); ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), 0, 0);
tt_int_op(ret, OP_EQ, 0); tt_int_op(ret, OP_EQ, 0);
ASN1_STRING_free(validCert->cert_info->validity->notBefore); ASN1_STRING_free(validCert->cert_info->validity->notBefore);
...@@ -1100,10 +1100,10 @@ test_tortls_check_lifetime(void *ignored) ...@@ -1100,10 +1100,10 @@ test_tortls_check_lifetime(void *ignored)
ASN1_STRING_free(validCert->cert_info->validity->notAfter); ASN1_STRING_free(validCert->cert_info->validity->notAfter);
validCert->cert_info->validity->notAfter = ASN1_TIME_set(NULL, now+60); validCert->cert_info->validity->notAfter = ASN1_TIME_set(NULL, now+60);
ret = tor_tls_check_lifetime(LOG_WARN, tls, 0, -1000); ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), 0, -1000);
tt_int_op(ret, OP_EQ, -1); tt_int_op(ret, OP_EQ, -1);
ret = tor_tls_check_lifetime(LOG_WARN, tls, -1000, 0); ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), -1000, 0);
tt_int_op(ret, OP_EQ, -1); tt_int_op(ret, OP_EQ, -1);
done: done:
...@@ -2653,18 +2653,18 @@ test_tortls_cert_is_valid(void *ignored) ...@@ -2653,18 +2653,18 @@ test_tortls_cert_is_valid(void *ignored)
tor_x509_cert_t *cert = NULL, *scert = NULL; tor_x509_cert_t *cert = NULL, *scert = NULL;
scert = tor_malloc_zero(sizeof(tor_x509_cert_t)); scert = tor_malloc_zero(sizeof(tor_x509_cert_t));
ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, 0); ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
tt_int_op(ret, OP_EQ, 0); tt_int_op(ret, OP_EQ, 0);
cert = tor_malloc_zero(sizeof(tor_x509_cert_t)); cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, 0); ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
tt_int_op(ret, OP_EQ, 0); tt_int_op(ret, OP_EQ, 0);
tor_free(scert); tor_free(scert);
tor_free(cert); tor_free(cert);
cert = tor_x509_cert_new(read_cert_from(validCertString)); cert = tor_x509_cert_new(read_cert_from(validCertString));
scert = tor_x509_cert_new(read_cert_from(caCertString)); scert = tor_x509_cert_new(read_cert_from(caCertString));
ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, 0); ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
tt_int_op(ret, OP_EQ, 1); tt_int_op(ret, OP_EQ, 1);
#ifndef OPENSSL_OPAQUE #ifndef OPENSSL_OPAQUE
...@@ -2675,7 +2675,7 @@ test_tortls_cert_is_valid(void *ignored) ...@@ -2675,7 +2675,7 @@ test_tortls_cert_is_valid(void *ignored)
ASN1_TIME_free(cert->cert->cert_info->validity->notAfter); ASN1_TIME_free(cert->cert->cert_info->validity->notAfter);
cert->cert->cert_info->validity->notAfter = cert->cert->cert_info->validity->notAfter =
ASN1_TIME_set(NULL, time(NULL)-1000000); ASN1_TIME_set(NULL, time(NULL)-1000000);
ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, 0); ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
tt_int_op(ret, OP_EQ, 0); tt_int_op(ret, OP_EQ, 0);
tor_x509_cert_free(cert); tor_x509_cert_free(cert);
...@@ -2684,7 +2684,7 @@ test_tortls_cert_is_valid(void *ignored) ...@@ -2684,7 +2684,7 @@ test_tortls_cert_is_valid(void *ignored)
scert = tor_x509_cert_new(read_cert_from(caCertString)); scert = tor_x509_cert_new(read_cert_from(caCertString));
X509_PUBKEY_free(cert->cert->cert_info->key); X509_PUBKEY_free(cert->cert->cert_info->key);
cert->cert->cert_info->key = NULL; cert->cert->cert_info->key = NULL;
ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, 1); ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
tt_int_op(ret, OP_EQ, 0); tt_int_op(ret, OP_EQ, 0);
#endif #endif
...@@ -2695,7 +2695,7 @@ test_tortls_cert_is_valid(void *ignored) ...@@ -2695,7 +2695,7 @@ test_tortls_cert_is_valid(void *ignored)
scert = tor_x509_cert_new(read_cert_from(caCertString)); scert = tor_x509_cert_new(read_cert_from(caCertString));
/* This doesn't actually change the key in the cert. XXXXXX */ /* This doesn't actually change the key in the cert. XXXXXX */
BN_one(EVP_PKEY_get1_RSA(X509_get_pubkey(cert->cert))->n); BN_one(EVP_PKEY_get1_RSA(X509_get_pubkey(cert->cert))->n);
ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, 1); ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
tt_int_op(ret, OP_EQ, 0); tt_int_op(ret, OP_EQ, 0);
tor_x509_cert_free(cert); tor_x509_cert_free(cert);
...@@ -2704,7 +2704,7 @@ test_tortls_cert_is_valid(void *ignored) ...@@ -2704,7 +2704,7 @@ test_tortls_cert_is_valid(void *ignored)
scert = tor_x509_cert_new(read_cert_from(caCertString)); scert = tor_x509_cert_new(read_cert_from(caCertString));
/* This doesn't actually change the key in the cert. XXXXXX */ /* This doesn't actually change the key in the cert. XXXXXX */
X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC; X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, 1); ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
tt_int_op(ret, OP_EQ, 0); tt_int_op(ret, OP_EQ, 0);
tor_x509_cert_free(cert); tor_x509_cert_free(cert);
...@@ -2713,7 +2713,7 @@ test_tortls_cert_is_valid(void *ignored) ...@@ -2713,7 +2713,7 @@ test_tortls_cert_is_valid(void *ignored)
scert = tor_x509_cert_new(read_cert_from(caCertString)); scert = tor_x509_cert_new(read_cert_from(caCertString));
/* This doesn't actually change the key in the cert. XXXXXX */ /* This doesn't actually change the key in the cert. XXXXXX */
X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC; X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, 0); ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
tt_int_op(ret, OP_EQ, 1); tt_int_op(ret, OP_EQ, 1);
tor_x509_cert_free(cert); tor_x509_cert_free(cert);
...@@ -2723,7 +2723,7 @@ test_tortls_cert_is_valid(void *ignored) ...@@ -2723,7 +2723,7 @@ test_tortls_cert_is_valid(void *ignored)
/* This doesn't actually change the key in the cert. XXXXXX */ /* This doesn't actually change the key in the cert. XXXXXX */
X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC; X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
X509_get_pubkey(cert->cert)->ameth = NULL; X509_get_pubkey(cert->cert)->ameth = NULL;
ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, 0); ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
tt_int_op(ret, OP_EQ, 0); tt_int_op(ret, OP_EQ, 0);
#endif #endif
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment