]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
nts: allow multiple files with trusted certificates
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 11 Feb 2021 11:20:59 +0000 (12:20 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 11 Feb 2021 15:13:39 +0000 (16:13 +0100)
Allow the ntstrustedcerts directive to be specified multiple times.

conf.c
conf.h
doc/chrony.conf.adoc
nts_ke_client.c
nts_ke_session.c
nts_ke_session.h
test/unit/nts_ke_session.c

diff --git a/conf.c b/conf.c
index 4c62a075c9ba7f23d52436355f506761e321ed56..3ae025403e784395f5c2ba8317baee5aacaa3ed8 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -77,6 +77,7 @@ static void parse_mailonchange(char *);
 static void parse_makestep(char *);
 static void parse_maxchange(char *);
 static void parse_ntsserver(char *, ARR_Instance files);
+static void parse_ntstrustedcerts(char *);
 static void parse_ratelimit(char *line, int *enabled, int *interval,
                             int *burst, int *leak);
 static void parse_refclock(char *);
@@ -260,7 +261,7 @@ static int nts_server_processes = 1;
 static int nts_server_connections = 100;
 static int nts_refresh = 2419200; /* 4 weeks */
 static int nts_rotate = 604800; /* 1 week */
-static char *nts_trusted_cert_file = NULL;
+static ARR_Instance nts_trusted_certs_files; /* array of (char *) */
 
 /* Number of clock updates needed to enable certificate time checks */
 static int no_cert_time_check = 0;
@@ -391,6 +392,7 @@ CNF_Initialise(int r, int client_only)
 
   nts_server_cert_files = ARR_CreateInstance(sizeof (char *));
   nts_server_key_files = ARR_CreateInstance(sizeof (char *));
+  nts_trusted_certs_files = ARR_CreateInstance(sizeof (char *));
 
   rtc_device = Strdup(DEFAULT_RTC_DEVICE);
   hwclock_file = Strdup(DEFAULT_HWCLOCK_FILE);
@@ -434,6 +436,8 @@ CNF_Finalise(void)
     Free(*(char **)ARR_GetElement(nts_server_cert_files, i));
   for (i = 0; i < ARR_GetSize(nts_server_key_files); i++)
     Free(*(char **)ARR_GetElement(nts_server_key_files, i));
+  for (i = 0; i < ARR_GetSize(nts_trusted_certs_files); i++)
+    Free(*(char **)ARR_GetElement(nts_trusted_certs_files, i));
 
   ARR_DestroyInstance(init_sources);
   ARR_DestroyInstance(ntp_sources);
@@ -447,6 +451,7 @@ CNF_Finalise(void)
 
   ARR_DestroyInstance(nts_server_cert_files);
   ARR_DestroyInstance(nts_server_key_files);
+  ARR_DestroyInstance(nts_trusted_certs_files);
 
   Free(drift_file);
   Free(dumpdir);
@@ -468,7 +473,6 @@ CNF_Finalise(void)
   Free(tempcomp_point_file);
   Free(nts_dump_dir);
   Free(nts_ntp_server);
-  Free(nts_trusted_cert_file);
 }
 
 /* ================================================== */
@@ -652,8 +656,6 @@ CNF_ParseLine(const char *filename, int number, char *line)
   } else if (!strcasecmp(command, "ntsratelimit")) {
     parse_ratelimit(p, &nts_ratelimit_enabled, &nts_ratelimit_interval,
                     &nts_ratelimit_burst, &nts_ratelimit_leak);
-  } else if (!strcasecmp(command, "ntstrustedcerts")) {
-    parse_string(p, &nts_trusted_cert_file);
   } else if (!strcasecmp(command, "ntscachedir") ||
              !strcasecmp(command, "ntsdumpdir")) {
     parse_string(p, &nts_dump_dir);
@@ -671,6 +673,8 @@ CNF_ParseLine(const char *filename, int number, char *line)
     parse_ntsserver(p, nts_server_cert_files);
   } else if (!strcasecmp(command, "ntsserverkey")) {
     parse_ntsserver(p, nts_server_key_files);
+  } else if (!strcasecmp(command, "ntstrustedcerts")) {
+    parse_ntstrustedcerts(p);
   } else if (!strcasecmp(command, "peer")) {
     parse_source(p, command, 1);
   } else if (!strcasecmp(command, "pidfile")) {
@@ -1178,6 +1182,17 @@ parse_ntsserver(char *line, ARR_Instance files)
 
 /* ================================================== */
 
+static void
+parse_ntstrustedcerts(char *line)
+{
+  char *file = NULL;
+
+  parse_string(line, &file);
+  ARR_AppendElement(nts_trusted_certs_files, &file);
+}
+
+/* ================================================== */
+
 static void
 parse_allow_deny(char *line, ARR_Instance restrictions, int allow)
 {
@@ -2589,10 +2604,12 @@ CNF_GetNtsRotate(void)
 
 /* ================================================== */
 
-char *
-CNF_GetNtsTrustedCertFile(void)
+int
+CNF_GetNtsTrustedCertsFiles(const char ***files)
 {
-  return nts_trusted_cert_file;
+  *files = ARR_GetElements(nts_trusted_certs_files);
+
+  return ARR_GetSize(nts_trusted_certs_files);
 }
 
 /* ================================================== */
diff --git a/conf.h b/conf.h
index cf5fc3ba7b680dade379777036ff94546aaeb77f..025ca607569e72e875c0305bf5925bd37c29005a 100644 (file)
--- a/conf.h
+++ b/conf.h
@@ -159,7 +159,7 @@ extern int CNF_GetNtsServerProcesses(void);
 extern int CNF_GetNtsServerConnections(void);
 extern int CNF_GetNtsRefresh(void);
 extern int CNF_GetNtsRotate(void);
-extern char *CNF_GetNtsTrustedCertFile(void);
+extern int CNF_GetNtsTrustedCertsFiles(const char ***files);
 extern int CNF_GetNoSystemCert(void);
 extern int CNF_GetNoCertTimeCheck(void);
 
index d9da7b40d24918f558c2dd40f10d5f07603aeb4c..a1de81487f583ca4b9f1d8acd356194403623fa9 100644 (file)
@@ -755,6 +755,9 @@ This directive specifies a file containing certificates (in the PEM format) of
 trusted certificate authorities (CA) that should be used to verify certificates
 of NTS servers in addition to the system's default trusted CAs (if the
 *nosystemcert* directive is not present).
++
+This directive can be used multiple times to specify multiple files with
+trusted certificates.
 
 [[nosystemcert]]*nosystemcert*::
 This directive disables the system's default trusted CAs.
index 5e87fe44e624087031b6b975e31c02de80d2f76c..59a9730adc75709d98ad8a72eecb1ae56f74802e 100644 (file)
@@ -268,7 +268,9 @@ handle_message(void *arg)
 NKC_Instance
 NKC_CreateInstance(IPSockAddr *address, const char *name)
 {
+  const char **trusted_certs;
   NKC_Instance inst;
+  int n_certs;
 
   inst = MallocNew(struct NKC_Instance_Record);
 
@@ -279,9 +281,11 @@ NKC_CreateInstance(IPSockAddr *address, const char *name)
   inst->destroying = 0;
   inst->got_response = 0;
 
+  n_certs = CNF_GetNtsTrustedCertsFiles(&trusted_certs);
+
   /* Share the credentials with other client instances */
   if (!client_credentials)
-    client_credentials = NKSN_CreateClientCertCredentials(CNF_GetNtsTrustedCertFile());
+    client_credentials = NKSN_CreateClientCertCredentials(trusted_certs, n_certs);
   client_credentials_refs++;
 
   return inst;
index d92b4c24c4a99bc36b2199b8c769d054176d12f5..131ad90e187b075a60991591278c038ce0399c02 100644 (file)
@@ -643,7 +643,7 @@ deinit_gnutls(void)
 
 static NKSN_Credentials
 create_credentials(const char **certs, const char **keys, int n_certs_keys,
-                   const char *trusted_certs)
+                   const char **trusted_certs, int n_trusted_certs)
 {
   gnutls_certificate_credentials_t credentials = NULL;
   int i, r;
@@ -674,10 +674,12 @@ create_credentials(const char **certs, const char **keys, int n_certs_keys,
     }
 
     if (trusted_certs) {
-      r = gnutls_certificate_set_x509_trust_file(credentials, trusted_certs,
-                                                 GNUTLS_X509_FMT_PEM);
-      if (r < 0)
-        goto error;
+      for (i = 0; i < n_trusted_certs; i++) {
+        r = gnutls_certificate_set_x509_trust_file(credentials, trusted_certs[i],
+                                                   GNUTLS_X509_FMT_PEM);
+        if (r < 0)
+          goto error;
+      }
     }
   }
 
@@ -698,15 +700,15 @@ error:
 NKSN_Credentials
 NKSN_CreateServerCertCredentials(const char **certs, const char **keys, int n_certs_keys)
 {
-  return create_credentials(certs, keys, n_certs_keys, NULL);
+  return create_credentials(certs, keys, n_certs_keys, NULL, 0);
 }
 
 /* ================================================== */
 
 NKSN_Credentials
-NKSN_CreateClientCertCredentials(const char *trusted_certs)
+NKSN_CreateClientCertCredentials(const char **trusted_certs, int n_certs)
 {
-  return create_credentials(NULL, NULL, 0, trusted_certs);
+  return create_credentials(NULL, NULL, 0, trusted_certs, n_certs);
 }
 
 /* ================================================== */
index ed9c711f16fb3d2fc614ad3531bcb0caa681f74d..eb19b920283d2c725d82b04c7dd7daad89da1224 100644 (file)
@@ -43,7 +43,8 @@ typedef int (*NKSN_MessageHandler)(void *arg);
    different clients or servers. */
 extern NKSN_Credentials NKSN_CreateServerCertCredentials(const char **certs, const char **keys,
                                                          int n_certs_keys);
-extern NKSN_Credentials NKSN_CreateClientCertCredentials(const char *trusted_certs);
+extern NKSN_Credentials NKSN_CreateClientCertCredentials(const char **trusted_certs,
+                                                         int n_certs);
 
 /* Destroy the credentials */
 extern void NKSN_DestroyCertCredentials(NKSN_Credentials credentials);
index b29675b9a3049a26d3d822f6e4f11cd41bb56217..1dd9aba7086684a65b69458a2ba906cd05700aa8 100644 (file)
@@ -179,7 +179,7 @@ test_unit(void)
     client = NKSN_CreateInstance(0, "test", handle_response, NULL);
 
     server_cred = NKSN_CreateServerCertCredentials(&cert, &key, 1);
-    client_cred = NKSN_CreateClientCertCredentials(cert);
+    client_cred = NKSN_CreateClientCertCredentials(&cert, 1);
 
     TEST_CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sock_fds) == 0);
     TEST_CHECK(fcntl(sock_fds[0], F_SETFL, O_NONBLOCK) == 0);