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_ratelimit(char *line, int *enabled, int *interval,
int *burst, int *leak);
static void parse_refclock(char *);
/* NTS server and client configuration */
static char *nts_dump_dir = NULL;
static char *nts_ntp_server = NULL;
-static char *nts_server_cert_file = NULL;
-static char *nts_server_key_file = NULL;
+static ARR_Instance nts_server_cert_files; /* array of (char *) */
+static ARR_Instance nts_server_key_files; /* array of (char *) */
static int nts_server_port = NKE_PORT;
static int nts_server_processes = 1;
static int nts_server_connections = 100;
ntp_restrictions = ARR_CreateInstance(sizeof (AllowDeny));
cmd_restrictions = ARR_CreateInstance(sizeof (AllowDeny));
+ nts_server_cert_files = ARR_CreateInstance(sizeof (char *));
+ nts_server_key_files = ARR_CreateInstance(sizeof (char *));
+
rtc_device = Strdup(DEFAULT_RTC_DEVICE);
hwclock_file = Strdup(DEFAULT_HWCLOCK_FILE);
user = Strdup(DEFAULT_USER);
Free(((RefclockParameters *)ARR_GetElement(refclock_sources, i))->driver_name);
Free(((RefclockParameters *)ARR_GetElement(refclock_sources, i))->driver_parameter);
}
+ for (i = 0; i < ARR_GetSize(nts_server_cert_files); i++)
+ 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));
ARR_DestroyInstance(init_sources);
ARR_DestroyInstance(ntp_sources);
ARR_DestroyInstance(ntp_restrictions);
ARR_DestroyInstance(cmd_restrictions);
+ ARR_DestroyInstance(nts_server_cert_files);
+ ARR_DestroyInstance(nts_server_key_files);
+
Free(drift_file);
Free(dumpdir);
Free(hwclock_file);
Free(tempcomp_point_file);
Free(nts_dump_dir);
Free(nts_ntp_server);
- Free(nts_server_cert_file);
- Free(nts_server_key_file);
Free(nts_trusted_cert_file);
}
} else if (!strcasecmp(command, "ntsrotate")) {
parse_int(p, &nts_rotate);
} else if (!strcasecmp(command, "ntsservercert")) {
- parse_string(p, &nts_server_cert_file);
+ parse_ntsserver(p, nts_server_cert_files);
} else if (!strcasecmp(command, "ntsserverkey")) {
- parse_string(p, &nts_server_key_file);
+ parse_ntsserver(p, nts_server_key_files);
} else if (!strcasecmp(command, "peer")) {
parse_source(p, command, 1);
} else if (!strcasecmp(command, "pidfile")) {
/* ================================================== */
+static void
+parse_ntsserver(char *line, ARR_Instance files)
+{
+ char *file = NULL;
+
+ parse_string(line, &file);
+ ARR_AppendElement(files, &file);
+}
+
+/* ================================================== */
+
static void
parse_allow_deny(char *line, ARR_Instance restrictions, int allow)
{
/* ================================================== */
-char *
-CNF_GetNtsServerCertFile(void)
+int
+CNF_GetNtsServerCertAndKeyFiles(const char ***certs, const char ***keys)
{
- return nts_server_cert_file;
-}
+ *certs = ARR_GetElements(nts_server_cert_files);
+ *keys = ARR_GetElements(nts_server_key_files);
-/* ================================================== */
+ if (ARR_GetSize(nts_server_cert_files) != ARR_GetSize(nts_server_key_files))
+ LOG_FATAL("Uneven number of NTS certs and keys");
-char *
-CNF_GetNtsServerKeyFile(void)
-{
- return nts_server_key_file;
+ return ARR_GetSize(nts_server_cert_files);
}
/* ================================================== */
extern char *CNF_GetNtsDumpDir(void);
extern char *CNF_GetNtsNtpServer(void);
-extern char *CNF_GetNtsServerCertFile(void);
-extern char *CNF_GetNtsServerKeyFile(void);
+extern int CNF_GetNtsServerCertAndKeyFiles(const char ***certs, const char ***keys);
extern int CNF_GetNtsServerPort(void);
extern int CNF_GetNtsServerProcesses(void);
extern int CNF_GetNtsServerConnections(void);
[[ntsservercert]]*ntsservercert* _file_::
This directive specifies a file containing a certificate in the PEM format
for *chronyd* to operate as an NTS server.
++
+This directive can be used multiple times to specify multiple certificates.
[[ntsserverkey]]*ntsserverkey* _file_::
This directive specifies a file containing a private key in the PEM format
for *chronyd* to operate as an NTS server.
++
+This directive can be used multiple times to specify multiple keys. The number
+of keys must be the same as the number of certificates and the corresponding
+files must be specified in the same order.
[[ntsprocesses]]*ntsprocesses* _processes_::
This directive specifies how many helper processes will *chronyd* operating
NKS_PreInitialise(uid_t uid, gid_t gid, int scfilter_level)
{
int i, processes, sock_fd1, sock_fd2;
+ const char **certs, **keys;
char prefix[16];
pid_t pid;
helper_sock_fd = INVALID_SOCK_FD;
is_helper = 0;
- if (!CNF_GetNtsServerCertFile() || !CNF_GetNtsServerKeyFile())
+ if (CNF_GetNtsServerCertAndKeyFiles(&certs, &keys) <= 0)
return;
processes = CNF_GetNtsServerProcesses();
void
NKS_Initialise(void)
{
- char *cert, *key;
+ const char **certs, **keys;
+ int i, n_certs_keys;
double key_delay;
- int i;
server_sock_fd4 = INVALID_SOCK_FD;
server_sock_fd6 = INVALID_SOCK_FD;
- cert = CNF_GetNtsServerCertFile();
- key = CNF_GetNtsServerKeyFile();
-
- if (!cert || !key)
+ n_certs_keys = CNF_GetNtsServerCertAndKeyFiles(&certs, &keys);
+ if (n_certs_keys <= 0)
return;
if (helper_sock_fd == INVALID_SOCK_FD) {
- server_credentials = NKSN_CreateServerCertCredentials(cert, key);
+ server_credentials = NKSN_CreateServerCertCredentials(certs, keys, n_certs_keys);
if (!server_credentials)
return;
} else {
/* ================================================== */
static NKSN_Credentials
-create_credentials(const char *cert, const char *key, const char *trusted_certs)
+create_credentials(const char **certs, const char **keys, int n_certs_keys,
+ const char *trusted_certs)
{
gnutls_certificate_credentials_t credentials = NULL;
- int r;
+ int i, r;
init_gnutls();
if (r < 0)
goto error;
- if (cert && key) {
+ if (certs && keys) {
assert(!trusted_certs);
- r = gnutls_certificate_set_x509_key_file(credentials, cert, key,
- GNUTLS_X509_FMT_PEM);
- if (r < 0)
- goto error;
+ for (i = 0; i < n_certs_keys; i++) {
+ r = gnutls_certificate_set_x509_key_file(credentials, certs[i], keys[i],
+ GNUTLS_X509_FMT_PEM);
+ if (r < 0)
+ goto error;
+ }
} else {
- assert(!cert && !key);
+ if (certs || keys || n_certs_keys > 0)
+ assert(0);
if (!CNF_GetNoSystemCert()) {
r = gnutls_certificate_set_x509_system_trust(credentials);
/* ================================================== */
NKSN_Credentials
-NKSN_CreateServerCertCredentials(const char *cert, const char *key)
+NKSN_CreateServerCertCredentials(const char **certs, const char **keys, int n_certs_keys)
{
- return create_credentials(cert, key, NULL);
+ return create_credentials(certs, keys, n_certs_keys, NULL);
}
/* ================================================== */
NKSN_Credentials
NKSN_CreateClientCertCredentials(const char *trusted_certs)
{
- return create_credentials(NULL, NULL, trusted_certs);
+ return create_credentials(NULL, NULL, 0, trusted_certs);
}
/* ================================================== */
/* Get server or client credentials using a server certificate and key,
or certificates of trusted CAs. The credentials may be shared between
different clients or servers. */
-extern NKSN_Credentials NKSN_CreateServerCertCredentials(const char *cert, const char *key);
+extern NKSN_Credentials NKSN_CreateServerCertCredentials(const char **certs, const char **keys,
+ int n_certs_keys);
extern NKSN_Credentials NKSN_CreateClientCertCredentials(const char *trusted_certs);
/* Destroy the credentials */
void
NNS_Initialise(void)
{
+ const char **certs, **keys;
+
/* Create an NTS-NTP server instance only if NTS-KE server is enabled */
- if (!CNF_GetNtsServerCertFile() || !CNF_GetNtsServerKeyFile()) {
+ if (CNF_GetNtsServerCertAndKeyFiles(&certs, &keys) <= 0) {
server = NULL;
return;
}
test_unit(void)
{
NKSN_Credentials client_cred, server_cred;
+ const char *cert, *key;
int sock_fds[2], i;
LCL_Initialise();
TST_RegisterDummyDrivers();
+ cert = "nts_ke.crt";
+ key = "nts_ke.key";
+
for (i = 0; i < 50; i++) {
SCH_Initialise();
server = NKSN_CreateInstance(1, NULL, handle_request, NULL);
client = NKSN_CreateInstance(0, "test", handle_response, NULL);
- server_cred = NKSN_CreateServerCertCredentials("nts_ke.crt", "nts_ke.key");
- client_cred = NKSN_CreateClientCertCredentials("nts_ke.crt");
+ server_cred = NKSN_CreateServerCertCredentials(&cert, &key, 1);
+ client_cred = NKSN_CreateClientCertCredentials(cert);
TEST_CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sock_fds) == 0);
TEST_CHECK(fcntl(sock_fds[0], F_SETFL, O_NONBLOCK) == 0);