From a8bc25e5431b68ecc7ca204e8c3c377e1121ff9c Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Thu, 18 Feb 2021 17:15:10 +0100 Subject: [PATCH] conf: add set selection to ntstrustedcerts Add an optional set-ID argument to the ntstrustedcerts directive to enable multiple sets of trusted certificates to be specified. --- conf.c | 26 +++++++++++++++++++++++--- conf.h | 2 +- doc/chrony.conf.adoc | 27 +++++++++++++++++++++------ nts_ke_client.c | 6 +----- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/conf.c b/conf.c index 573094e..3567252 100644 --- a/conf.c +++ b/conf.c @@ -262,6 +262,7 @@ static int nts_server_connections = 100; static int nts_refresh = 2419200; /* 4 weeks */ static int nts_rotate = 604800; /* 1 week */ static ARR_Instance nts_trusted_certs_paths; /* array of (char *) */ +static ARR_Instance nts_trusted_certs_ids; /* array of uint32_t */ /* Number of clock updates needed to enable certificate time checks */ static int no_cert_time_check = 0; @@ -393,6 +394,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_paths = ARR_CreateInstance(sizeof (char *)); + nts_trusted_certs_ids = ARR_CreateInstance(sizeof (uint32_t)); rtc_device = Strdup(DEFAULT_RTC_DEVICE); hwclock_file = Strdup(DEFAULT_HWCLOCK_FILE); @@ -452,6 +454,7 @@ CNF_Finalise(void) ARR_DestroyInstance(nts_server_cert_files); ARR_DestroyInstance(nts_server_key_files); ARR_DestroyInstance(nts_trusted_certs_paths); + ARR_DestroyInstance(nts_trusted_certs_ids); Free(drift_file); Free(dumpdir); @@ -1185,10 +1188,23 @@ parse_ntsserver(char *line, ARR_Instance files) static void parse_ntstrustedcerts(char *line) { - char *path = NULL; + uint32_t id; + char *path; + + if (get_number_of_args(line) == 2) { + path = CPS_SplitWord(line); + if (sscanf(line, "%"SCNu32, &id) != 1) + command_parse_error(); + } else { + check_number_of_args(line, 1); + path = line; + id = 0; + } + + path = Strdup(path); - parse_string(line, &path); ARR_AppendElement(nts_trusted_certs_paths, &path); + ARR_AppendElement(nts_trusted_certs_ids, &id); } /* ================================================== */ @@ -2605,9 +2621,13 @@ CNF_GetNtsRotate(void) /* ================================================== */ int -CNF_GetNtsTrustedCertsPaths(const char ***paths) +CNF_GetNtsTrustedCertsPaths(const char ***paths, uint32_t **ids) { *paths = ARR_GetElements(nts_trusted_certs_paths); + *ids = ARR_GetElements(nts_trusted_certs_ids); + + if (ARR_GetSize(nts_trusted_certs_paths) != ARR_GetSize(nts_trusted_certs_ids)) + assert(0); return ARR_GetSize(nts_trusted_certs_paths); } diff --git a/conf.h b/conf.h index 0ca5017..0ba1be1 100644 --- 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 int CNF_GetNtsTrustedCertsPaths(const char ***paths); +extern int CNF_GetNtsTrustedCertsPaths(const char ***paths, uint32_t **ids); extern int CNF_GetNoSystemCert(void); extern int CNF_GetNoCertTimeCheck(void); diff --git a/doc/chrony.conf.adoc b/doc/chrony.conf.adoc index 2abac69..ece42eb 100644 --- a/doc/chrony.conf.adoc +++ b/doc/chrony.conf.adoc @@ -750,14 +750,29 @@ This directive specifies the maximum interval between NTS-KE handshakes (in seconds) in order to refresh the keys authenticating NTP packets. The default value is 2419200 (4 weeks). -[[ntstrustedcerts]]*ntstrustedcerts* _file_|_directory_:: +[[ntstrustedcerts]]*ntstrustedcerts* [_set-ID_] _file_|_directory_:: This directive specifies a file or directory 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). +PEM format) of trusted certificate authorities (CA) which can be used to +verify certificates of NTS servers. + -This directive can be used multiple times to specify multiple files and/or -directories with trusted certificates. +The optional _set-ID_ argument is a number in the range 0 through 2^32-1, which +selects the set of certificates where certificates from the specified file +or directory are added. The default ID is 0, which is a set containing the +system's default trusted CAs (unless the *nosystemcert* directive is present). +All other sets are empty by default. ++ +This directive can be used multiple times to specify one or more sets of +trusted certificates, each containing certificates from one or more files +and/or directories. ++ +An example is: ++ +---- +ntstrustedcerts /etc/pki/nts/foo.crt +ntstrustedcerts 1 /etc/pki/nts/bar.crt +ntstrustedcerts 1 /etc/pki/nts/baz.crt +ntstrustedcerts 2 /etc/pki/nts/qux.crt +---- [[nosystemcert]]*nosystemcert*:: This directive disables the system's default trusted CAs. diff --git a/nts_ke_client.c b/nts_ke_client.c index dddb4c0..d47a1d1 100644 --- a/nts_ke_client.c +++ b/nts_ke_client.c @@ -283,9 +283,7 @@ NKC_CreateInstance(IPSockAddr *address, const char *name, uint32_t cert_set) inst->destroying = 0; inst->got_response = 0; - n_certs = CNF_GetNtsTrustedCertsPaths(&trusted_certs); - certs_ids = MallocArray(uint32_t, n_certs); - memset(certs_ids, 0, sizeof (uint32_t) * n_certs); + n_certs = CNF_GetNtsTrustedCertsPaths(&trusted_certs, &certs_ids); /* Share the credentials among clients using the default set of trusted certificates, which likely contains most certificates */ @@ -301,8 +299,6 @@ NKC_CreateInstance(IPSockAddr *address, const char *name, uint32_t cert_set) n_certs, cert_set); } - Free(certs_ids); - return inst; }