]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
nts: allow disabling certificate time checks
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 16 Apr 2020 14:08:43 +0000 (16:08 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 16 Apr 2020 16:09:32 +0000 (18:09 +0200)
Add "nocerttimecheck" directive to specify the number of clock updates
that need to be made before the time validation of certificates is
enabled. This makes NTS usable on machines that don't have a RTC.

conf.c
conf.h
nts_ke_session.c
test/unit/nts_ke_client.c

diff --git a/conf.c b/conf.c
index 3a360ef7195cdbf62a07595103dab56ab7b4c0c0..a604357cbae2c4e964bc129bb8faf8737f14ee00 100644 (file)
--- 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 7c9247088b72a577f1626c4a0b5e46406098b163..4d27ef1186239b997acb5cee4137766336253917 100644 (file)
--- 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 */
index 78c9735460bb461eee9fe9931742847f4557d332..a27216f20aa51dc0a874debcc107391f332545a9 100644 (file)
@@ -40,6 +40,7 @@
 #include "util.h"
 
 #include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
 
 #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;
index 74a17e4a9de6eaaaa2991b1eae12c8df6274ce28..80d523284237b88b12a0f1db1550874ba8f41871 100644 (file)
@@ -24,6 +24,7 @@
 #ifdef FEAT_NTS
 
 #include <nts_ke_client.c>
+#include <local.h>
 
 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