diff --git a/conf.c b/conf.c index 3a360ef..a604357 100644 --- a/conf.c +++ b/conf.c @@ -235,6 +235,9 @@ static int nts_refresh = 2419200; /* 4 weeks */ static int nts_rotate = 604800; /* 1 week */ static char *nts_trusted_cert_file = NULL; +/* Number of clock updates needed to enable certificate time checks */ +static int no_cert_time_check = 0; + /* Flag disabling use of system trusted certificates */ static int no_system_cert = 0; @@ -545,6 +548,8 @@ CNF_ParseLine(const char *filename, int number, char *line) parse_int(p, &min_samples); } else if (!strcasecmp(command, "minsources")) { parse_int(p, &min_sources); + } else if (!strcasecmp(command, "nocerttimecheck")) { + parse_int(p, &no_cert_time_check); } else if (!strcasecmp(command, "noclientlog")) { no_client_log = parse_null(p); } else if (!strcasecmp(command, "nosystemcert")) { @@ -2158,3 +2163,11 @@ CNF_GetNoSystemCert(void) { return no_system_cert; } + +/* ================================================== */ + +int +CNF_GetNoCertTimeCheck(void) +{ + return no_cert_time_check; +} diff --git a/conf.h b/conf.h index 7c92470..4d27ef1 100644 --- a/conf.h +++ b/conf.h @@ -150,5 +150,6 @@ extern int CNF_GetNtsRefresh(void); extern int CNF_GetNtsRotate(void); extern char *CNF_GetNtsTrustedCertFile(void); extern int CNF_GetNoSystemCert(void); +extern int CNF_GetNoCertTimeCheck(void); #endif /* GOT_CONF_H */ diff --git a/nts_ke_session.c b/nts_ke_session.c index 78c9735..a27216f 100644 --- a/nts_ke_session.c +++ b/nts_ke_session.c @@ -40,6 +40,7 @@ #include "util.h" #include +#include #define INVALID_SOCK_FD (-8) @@ -89,6 +90,8 @@ static gnutls_priority_t priority_cache; static int credentials_counter = 0; +static int clock_updates = 0; + /* ================================================== */ static void @@ -209,6 +212,7 @@ create_tls_session(int server_mode, int sock_fd, const char *server_name, unsigned char alpn_name[sizeof (NKE_ALPN_NAME)]; gnutls_session_t session; gnutls_datum_t alpn; + unsigned int flags; int r; r = gnutls_init(&session, GNUTLS_NONBLOCK | (server_mode ? GNUTLS_SERVER : GNUTLS_CLIENT)); @@ -221,7 +225,15 @@ create_tls_session(int server_mode, int sock_fd, const char *server_name, r = gnutls_server_name_set(session, GNUTLS_NAME_DNS, server_name, strlen(server_name)); if (r < 0) goto error; - gnutls_session_set_verify_cert(session, server_name, 0); + + flags = 0; + + if (clock_updates < CNF_GetNoCertTimeCheck()) { + flags |= GNUTLS_VERIFY_DISABLE_TIME_CHECKS | GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS; + DEBUG_LOG("Disabled time checks"); + } + + gnutls_session_set_verify_cert(session, server_name, flags); } r = gnutls_priority_set(session, priority); @@ -552,6 +564,16 @@ get_time(time_t *t) /* ================================================== */ +static void +handle_step(struct timespec *raw, struct timespec *cooked, double dfreq, + double doffset, LCL_ChangeType change_type, void *anything) +{ + if (change_type != LCL_ChangeUnknownStep && clock_updates < INT_MAX) + clock_updates++; +} + +/* ================================================== */ + static int gnutls_initialised = 0; static void @@ -576,6 +598,8 @@ init_gnutls(void) gnutls_global_set_time_function(get_time); gnutls_initialised = 1; + + LCL_AddParameterChangeHandler(handle_step, NULL); } /* ================================================== */ @@ -585,6 +609,8 @@ deinit_gnutls(void) { assert(gnutls_initialised); + LCL_RemoveParameterChangeHandler(handle_step, NULL); + gnutls_priority_deinit(priority_cache); gnutls_global_deinit(); gnutls_initialised = 0; diff --git a/test/unit/nts_ke_client.c b/test/unit/nts_ke_client.c index 74a17e4..80d5232 100644 --- a/test/unit/nts_ke_client.c +++ b/test/unit/nts_ke_client.c @@ -24,6 +24,7 @@ #ifdef FEAT_NTS #include +#include static void prepare_response(NKSN_Instance session, int valid) @@ -110,6 +111,7 @@ test_unit(void) for (i = 0; i < sizeof conf / sizeof conf[0]; i++) CNF_ParseLine(NULL, i + 1, conf[i]); + LCL_Initialise(); NKC_Initialise(); SCK_GetLoopbackIPAddress(AF_INET, &addr.ip_addr); @@ -128,6 +130,7 @@ test_unit(void) NKC_DestroyInstance(inst); NKC_Finalise(); + LCL_Finalise(); CNF_Finalise(); } #else