diff --git a/doc/xml/release/2020s/2026/2.58.0.xml b/doc/xml/release/2020s/2026/2.58.0.xml
index 789d6d363..7a9dc1105 100644
--- a/doc/xml/release/2020s/2026/2.58.0.xml
+++ b/doc/xml/release/2020s/2026/2.58.0.xml
@@ -57,6 +57,18 @@
Support for Azure managed identities.
+
+
+
+
+
+
+
+
+
+ Allow configuration of TLS cipher suites.
+
+
diff --git a/src/build/config/config.yaml b/src/build/config/config.yaml
index 703c9c35d..857c725d8 100644
--- a/src/build/config/config.yaml
+++ b/src/build/config/config.yaml
@@ -952,6 +952,16 @@ option:
command: buffer-size
depend: tcp-keep-alive-count
+ # TLS allowed ciphers
+ tls-cipher-12:
+ section: global
+ type: string
+ required: false
+ command: buffer-size
+
+ tls-cipher-13:
+ inherit: tls-cipher-12
+
# Logging options
#---------------------------------------------------------------------------------------------------------------------------------
log-level-console:
diff --git a/src/build/help/help.xml b/src/build/help/help.xml
index a4186e28a..3cb00596b 100644
--- a/src/build/help/help.xml
+++ b/src/build/help/help.xml
@@ -430,6 +430,35 @@
30
+
+
+ Allowed TLSv1.2 cipher suites.
+
+
+ All TLS connections between the client and server are encrypted. By default, connections to objects stores (e.g. S3) are also encrypted.
+
+ The absolute minimum security level for any transport connection is TLSv1.2.
+
+ The accepted cipher suites can be adjusted if need arises. The example is reasonable choice unless you have specific security requirements. If unset (the default), the default of the underlying OpenSSL library applies.
+
+
+ HIGH:MEDIUM:+3DES:!aNULL
+
+
+
+ Allowed TLSv1.3 cipher suites.
+
+
+ All TLS connections between the client and server are encrypted. By default, connections to objects stores (e.g. S3) are also encrypted.
+
+ The absolute minimum security level for any transport connection is TLSv1.2.
+
+ The accepted cipher suites can be adjusted if need arises. If unset (the default), the default of the underlying OpenSSL library applies.
+
+
+ TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
+
+
diff --git a/src/common/io/tls/common.c b/src/common/io/tls/common.c
index 7770ab259..d1806b418 100644
--- a/src/common/io/tls/common.c
+++ b/src/common/io/tls/common.c
@@ -14,6 +14,17 @@ TLS Common
#include "common/user.h"
#include "storage/posix/storage.h"
+/***********************************************************************************************************************************
+Local variables
+***********************************************************************************************************************************/
+static struct TlsCommonLocal
+{
+ MemContext *memContext; // Mem context for TLS common
+
+ String *tlsCipher12; // Allowed ciphers for TLSv1.2
+ String *tlsCipher13; // Allowed ciphers for TLSv1.3
+} tlsCommonLocal;
+
/**********************************************************************************************************************************/
FN_EXTERN Buffer *
tlsAsn1ToBuf(const ASN1_STRING *const nameAsn1)
@@ -172,6 +183,35 @@ tlsCertKeyLoad(SSL_CTX *const context, const String *const certFile, const Strin
FUNCTION_TEST_RETURN_VOID();
}
+/**********************************************************************************************************************************/
+FN_EXTERN void
+tlsInit(const String *const tlsCipher12, const String *const tlsCipher13)
+{
+ FUNCTION_TEST_BEGIN();
+ FUNCTION_TEST_PARAM(STRING, tlsCipher12);
+ FUNCTION_TEST_PARAM(STRING, tlsCipher13);
+ FUNCTION_TEST_END();
+
+ // Free old mem context (if any)
+ if (tlsCommonLocal.memContext != NULL)
+ memContextFree(tlsCommonLocal.memContext);
+
+ // Initialize mem context
+ MEM_CONTEXT_BEGIN(memContextTop())
+ {
+ MEM_CONTEXT_NEW_BEGIN(TlsCommon, .childQty = MEM_CONTEXT_QTY_MAX)
+ {
+ tlsCommonLocal.memContext = MEM_CONTEXT_NEW();
+ tlsCommonLocal.tlsCipher12 = strDup(tlsCipher12);
+ tlsCommonLocal.tlsCipher13 = strDup(tlsCipher13);
+ }
+ MEM_CONTEXT_NEW_END();
+ }
+ MEM_CONTEXT_END();
+
+ FUNCTION_TEST_RETURN_VOID();
+}
+
/**********************************************************************************************************************************/
FN_EXTERN SSL_CTX *
tlsContext(const bool verifyPeer)
@@ -200,6 +240,14 @@ tlsContext(const bool verifyPeer)
{
// Set minimum TLS version to 1.2
cryptoError(SSL_CTX_set_min_proto_version(result, TLS1_2_VERSION) != 1, "unable to set minumum TLS version to 1.2");
+
+ // Set allowed ciphers for TLSv1.2 when configured
+ if (tlsCommonLocal.tlsCipher12 != NULL)
+ cryptoError(SSL_CTX_set_cipher_list(result, strZ(tlsCommonLocal.tlsCipher12)) != 1, "unable to set TLSv1.2 ciphers");
+
+ // Set allowed ciphers for TLSv1.3 when configured
+ if (tlsCommonLocal.tlsCipher13 != NULL)
+ cryptoError(SSL_CTX_set_ciphersuites(result, strZ(tlsCommonLocal.tlsCipher13)) != 1, "unable to set TLSv1.3 ciphers");
}
FUNCTION_TEST_RETURN_TYPE_P(SSL_CTX, result);
diff --git a/src/common/io/tls/common.h b/src/common/io/tls/common.h
index 63c6f33f3..09762a223 100644
--- a/src/common/io/tls/common.h
+++ b/src/common/io/tls/common.h
@@ -11,6 +11,9 @@ TLS Common
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
+// Initialize TLS with allowed ciphers
+FN_EXTERN void tlsInit(const String *tlsCipher12, const String *tlsCipher13);
+
// Convert an ASN1 string used in certificates to a Buffer
FN_EXTERN Buffer *tlsAsn1ToBuf(const ASN1_STRING *nameAsn1);
diff --git a/src/config/config.auto.h b/src/config/config.auto.h
index 49deabe33..6a7c3f181 100644
--- a/src/config/config.auto.h
+++ b/src/config/config.auto.h
@@ -132,6 +132,8 @@ Option constants
#define CFGOPT_TCP_KEEP_ALIVE_COUNT "tcp-keep-alive-count"
#define CFGOPT_TCP_KEEP_ALIVE_IDLE "tcp-keep-alive-idle"
#define CFGOPT_TCP_KEEP_ALIVE_INTERVAL "tcp-keep-alive-interval"
+#define CFGOPT_TLS_CIPHER_12 "tls-cipher-12"
+#define CFGOPT_TLS_CIPHER_13 "tls-cipher-13"
#define CFGOPT_TLS_SERVER_ADDRESS "tls-server-address"
#define CFGOPT_TLS_SERVER_AUTH "tls-server-auth"
#define CFGOPT_TLS_SERVER_CA_FILE "tls-server-ca-file"
@@ -142,7 +144,7 @@ Option constants
#define CFGOPT_VERBOSE "verbose"
#define CFGOPT_VERSION "version"
-#define CFG_OPTION_TOTAL 190
+#define CFG_OPTION_TOTAL 192
/***********************************************************************************************************************************
Option value constants
@@ -585,6 +587,8 @@ typedef enum
cfgOptTcpKeepAliveCount,
cfgOptTcpKeepAliveIdle,
cfgOptTcpKeepAliveInterval,
+ cfgOptTlsCipher12,
+ cfgOptTlsCipher13,
cfgOptTlsServerAddress,
cfgOptTlsServerAuth,
cfgOptTlsServerCaFile,
diff --git a/src/config/load.c b/src/config/load.c
index 52a152b76..f8d0176ed 100644
--- a/src/config/load.c
+++ b/src/config/load.c
@@ -14,6 +14,7 @@ Configuration Load
#include "common/debug.h"
#include "common/io/io.h"
#include "common/io/socket/common.h"
+#include "common/io/tls/common.h"
#include "common/log.h"
#include "common/memContext.h"
#include "config/config.intern.h"
@@ -492,6 +493,13 @@ cfgLoad(const unsigned int argListSize, const char *argList[])
cfgOptionTest(cfgOptTcpKeepAliveInterval) ? cfgOptionInt(cfgOptTcpKeepAliveInterval) : 0);
}
+ // Initialize TLS settings
+ if (cfgOptionValid(cfgOptTlsCipher12))
+ {
+ ASSERT(cfgOptionValid(cfgOptTlsCipher13));
+ tlsInit(cfgOptionStrNull(cfgOptTlsCipher12), cfgOptionStrNull(cfgOptTlsCipher13));
+ }
+
// Set IO buffer size (use the default for help to lower memory usage)
if (cfgOptionValid(cfgOptBufferSize) && !cfgCommandHelp())
ioBufferSizeSet(cfgOptionUInt(cfgOptBufferSize));
diff --git a/src/config/parse.auto.c.inc b/src/config/parse.auto.c.inc
index b486988c1..0ff01c5e0 100644
--- a/src/config/parse.auto.c.inc
+++ b/src/config/parse.auto.c.inc
@@ -11138,6 +11138,142 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
), // opt/tcp-keep-alive-interval
), // opt/tcp-keep-alive-interval
// -----------------------------------------------------------------------------------------------------------------------------
+ PARSE_RULE_OPTION // opt/tls-cipher-12
+ ( // opt/tls-cipher-12
+ PARSE_RULE_OPTION_NAME("tls-cipher-12"), // opt/tls-cipher-12
+ PARSE_RULE_OPTION_TYPE(String), // opt/tls-cipher-12
+ PARSE_RULE_OPTION_RESET(true), // opt/tls-cipher-12
+ PARSE_RULE_OPTION_REQUIRED(false), // opt/tls-cipher-12
+ PARSE_RULE_OPTION_SECTION(Global), // opt/tls-cipher-12
+ // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND_ROLE_MAIN_VALID_LIST // opt/tls-cipher-12
+ ( // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Annotate) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(ArchiveGet) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(ArchivePush) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Backup) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Check) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Expire) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Info) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Manifest) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(RepoGet) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(RepoLs) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(RepoPut) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(RepoRm) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Restore) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Server) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(ServerPing) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(StanzaCreate) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(StanzaDelete) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(StanzaUpgrade) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Verify) // opt/tls-cipher-12
+ ), // opt/tls-cipher-12
+ // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND_ROLE_ASYNC_VALID_LIST // opt/tls-cipher-12
+ ( // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(ArchiveGet) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(ArchivePush) // opt/tls-cipher-12
+ ), // opt/tls-cipher-12
+ // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND_ROLE_LOCAL_VALID_LIST // opt/tls-cipher-12
+ ( // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(ArchiveGet) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(ArchivePush) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Backup) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Restore) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Verify) // opt/tls-cipher-12
+ ), // opt/tls-cipher-12
+ // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND_ROLE_REMOTE_VALID_LIST // opt/tls-cipher-12
+ ( // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Annotate) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(ArchiveGet) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(ArchivePush) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Backup) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Check) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Expire) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Info) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Manifest) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(RepoGet) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(RepoLs) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(RepoPut) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(RepoRm) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Restore) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(StanzaCreate) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(StanzaDelete) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(StanzaUpgrade) // opt/tls-cipher-12
+ PARSE_RULE_OPTION_COMMAND(Verify) // opt/tls-cipher-12
+ ), // opt/tls-cipher-12
+ ), // opt/tls-cipher-12
+ // -----------------------------------------------------------------------------------------------------------------------------
+ PARSE_RULE_OPTION // opt/tls-cipher-13
+ ( // opt/tls-cipher-13
+ PARSE_RULE_OPTION_NAME("tls-cipher-13"), // opt/tls-cipher-13
+ PARSE_RULE_OPTION_TYPE(String), // opt/tls-cipher-13
+ PARSE_RULE_OPTION_RESET(true), // opt/tls-cipher-13
+ PARSE_RULE_OPTION_REQUIRED(false), // opt/tls-cipher-13
+ PARSE_RULE_OPTION_SECTION(Global), // opt/tls-cipher-13
+ // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND_ROLE_MAIN_VALID_LIST // opt/tls-cipher-13
+ ( // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Annotate) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(ArchiveGet) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(ArchivePush) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Backup) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Check) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Expire) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Info) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Manifest) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(RepoGet) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(RepoLs) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(RepoPut) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(RepoRm) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Restore) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Server) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(ServerPing) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(StanzaCreate) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(StanzaDelete) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(StanzaUpgrade) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Verify) // opt/tls-cipher-13
+ ), // opt/tls-cipher-13
+ // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND_ROLE_ASYNC_VALID_LIST // opt/tls-cipher-13
+ ( // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(ArchiveGet) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(ArchivePush) // opt/tls-cipher-13
+ ), // opt/tls-cipher-13
+ // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND_ROLE_LOCAL_VALID_LIST // opt/tls-cipher-13
+ ( // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(ArchiveGet) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(ArchivePush) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Backup) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Restore) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Verify) // opt/tls-cipher-13
+ ), // opt/tls-cipher-13
+ // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND_ROLE_REMOTE_VALID_LIST // opt/tls-cipher-13
+ ( // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Annotate) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(ArchiveGet) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(ArchivePush) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Backup) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Check) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Expire) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Info) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Manifest) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(RepoGet) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(RepoLs) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(RepoPut) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(RepoRm) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Restore) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(StanzaCreate) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(StanzaDelete) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(StanzaUpgrade) // opt/tls-cipher-13
+ PARSE_RULE_OPTION_COMMAND(Verify) // opt/tls-cipher-13
+ ), // opt/tls-cipher-13
+ ), // opt/tls-cipher-13
+ // -----------------------------------------------------------------------------------------------------------------------------
PARSE_RULE_OPTION // opt/tls-server-address
( // opt/tls-server-address
PARSE_RULE_OPTION_NAME("tls-server-address"), // opt/tls-server-address
@@ -11741,6 +11877,8 @@ static const uint8_t optionResolveOrder[] =
cfgOptTcpKeepAliveCount, // opt-resolve-order
cfgOptTcpKeepAliveIdle, // opt-resolve-order
cfgOptTcpKeepAliveInterval, // opt-resolve-order
+ cfgOptTlsCipher12, // opt-resolve-order
+ cfgOptTlsCipher13, // opt-resolve-order
cfgOptTlsServerAddress, // opt-resolve-order
cfgOptTlsServerAuth, // opt-resolve-order
cfgOptTlsServerCaFile, // opt-resolve-order
diff --git a/test/define.yaml b/test/define.yaml
index 6cdcb1f6e..6dcbed3bf 100644
--- a/test/define.yaml
+++ b/test/define.yaml
@@ -530,6 +530,7 @@ unit:
include:
- common/io/socket/common
+ - common/io/tls/common
# ----------------------------------------------------------------------------------------------------------------------------
- name: exec
diff --git a/test/src/module/command/helpTest.c b/test/src/module/command/helpTest.c
index decdd2336..8d4d0434f 100644
--- a/test/src/module/command/helpTest.c
+++ b/test/src/module/command/helpTest.c
@@ -278,6 +278,8 @@ testRun(void)
" --tcp-keep-alive-count keep-alive count\n"
" --tcp-keep-alive-idle keep-alive idle time\n"
" --tcp-keep-alive-interval keep-alive interval time\n"
+ " --tls-cipher-12 allowed TLSv1.2 cipher suites\n"
+ " --tls-cipher-13 allowed TLSv1.3 cipher suites\n"
"\n"
"Log Options:\n"
"\n"
diff --git a/test/src/module/common/ioTlsTest.c b/test/src/module/common/ioTlsTest.c
index 252847b5e..2a3f68404 100644
--- a/test/src/module/common/ioTlsTest.c
+++ b/test/src/module/common/ioTlsTest.c
@@ -917,6 +917,64 @@ testRun(void)
}
HRN_FORK_END();
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("fail on mismatch between allowed TLS cipher suites");
+
+ HRN_FORK_BEGIN()
+ {
+ const unsigned int testPort = hrnServerPortNext();
+
+ HRN_FORK_CHILD_BEGIN(.prefix = "test server", .timeout = 5000)
+ {
+ TEST_RESULT_VOID(tlsInit(STRDEF("eNULL"), STRDEF("TLS_AES_256_GCM_SHA384")), "disallow TLS 1.2");
+
+ // Start server to test various certificate errors
+ TEST_ERROR_MULTI(
+ hrnServerRunP(
+ HRN_FORK_CHILD_READ(), hrnServerProtocolTls, testPort, .certificate = STRDEF(HRN_SERVER_CERT),
+ .key = STRDEF(HRN_SERVER_KEY), .address = STRDEF("::1")),
+ ServiceError,
+ // TLS >= 3
+ "TLS error [1:167772353] no shared cipher",
+ // TLS < 3
+ "TLS error [1:337678529] no shared cipher");
+ }
+ HRN_FORK_CHILD_END();
+
+ HRN_FORK_PARENT_BEGIN(.prefix = "test client", .timeout = 1000)
+ {
+ IoWrite *const tls = hrnServerScriptBegin(HRN_FORK_PARENT_WRITE(0));
+
+ // -----------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("cipher suite mismatch");
+
+ hrnServerScriptAccept(tls);
+ hrnServerScriptClose(tls);
+
+ TEST_RESULT_VOID(tlsInit(STRDEF("COMPLEMENTOFALL"), STRDEF("TLS_AES_128_GCM_SHA256")), "disallow TLS 1.3");
+
+ TEST_ERROR_MULTI(
+ ioClientOpen(
+ tlsClientNewP(
+ sckClientNew(STRDEF("::1"), testPort, 5000, 5000), STRDEF("::1"), 0, 0, true,
+ .caFile = STRDEF(HRN_SERVER_CA))),
+ ServiceError,
+ // TLS >= 3
+ "TLS error [1:167773200] sslv3 alert handshake failure",
+ // TLS < 3
+ "TLS error [1:336151568] sslv3 alert handshake failure",
+ // TLS >= 3 Fedora/Alpine
+ "TLS error [1:167773200] ssl/tls alert handshake failure");
+
+ // -----------------------------------------------------------------------------------------------------------------
+ hrnServerScriptEnd(tls);
+ }
+ HRN_FORK_PARENT_END();
+ }
+ HRN_FORK_END();
+
+ TEST_RESULT_VOID(tlsInit(NULL, NULL), "init null tls ciphers");
+
// Server on IPv6
// -------------------------------------------------------------------------------------------------------------------------
HRN_FORK_BEGIN()
diff --git a/test/src/module/config/loadTest.c b/test/src/module/config/loadTest.c
index c864100b9..109e71aed 100644
--- a/test/src/module/config/loadTest.c
+++ b/test/src/module/config/loadTest.c
@@ -731,12 +731,29 @@ testRun(void)
if (testBegin("cfgLoad()"))
{
// -------------------------------------------------------------------------------------------------------------------------
- TEST_TITLE("dry-run valid, --no-dry-run");
+ TEST_TITLE("TLS cipher suites");
StringList *argList = strLstNew();
strLstAddZ(argList, PROJECT_BIN);
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
hrnCfgArgRawZ(argList, cfgOptLockPath, HRN_PATH "/lock");
+ hrnCfgArgRawZ(argList, cfgOptTlsCipher12, "HIGH:MEDIUM:+3DES:!aNULL");
+ hrnCfgArgRawZ(argList, cfgOptTlsCipher13, "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256");
+ strLstAddZ(argList, CFGCMD_EXPIRE);
+
+ TEST_RESULT_VOID(cfgLoad(strLstSize(argList), strLstPtr(argList)), "load config");
+ TEST_RESULT_STR_Z(tlsCommonLocal.tlsCipher12, "HIGH:MEDIUM:+3DES:!aNULL", "check tls1.2 cipher suites");
+ TEST_RESULT_STR_Z(
+ tlsCommonLocal.tlsCipher13, "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256", "check tls1.3 cipher suites");
+ cmdLockReleaseP();
+
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("dry-run valid, --no-dry-run");
+
+ argList = strLstNew();
+ strLstAddZ(argList, PROJECT_BIN);
+ hrnCfgArgRawZ(argList, cfgOptStanza, "db");
+ hrnCfgArgRawZ(argList, cfgOptLockPath, HRN_PATH "/lock");
hrnCfgArgRawZ(argList, cfgOptLogLevelStderr, CFGOPTVAL_ARCHIVE_MODE_OFF_Z);
strLstAddZ(argList, CFGCMD_EXPIRE);