diff --git a/ChangeLog.txt b/ChangeLog.txt
index 409b0805..d6e6b02f 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -86,6 +86,8 @@ Broker:
- Fix file logging on Windows. Closes #1880.
- Fix bridge sock not being removed from sock hash on error. Closes #1897.
- Default for max_queued_messages has been changed to 1000.
+- Add `ciphers_tls1.3` option, to allow setting TLS v1.3 ciphersuites.
+ Closes #1825.
Client library:
- Client no longer generates random client ids for v3.1.1 clients, these are
diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml
index 86aa656c..fa909a68 100644
--- a/man/mosquitto.conf.5.xml
+++ b/man/mosquitto.conf.5.xml
@@ -1171,8 +1171,8 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S
default at compile time. Certificate based TLS may be used
with websockets, except that only the
, ,
- and
- options are
+ , , and
+ options are
supported.
Not reloaded on reload signal.
@@ -1289,9 +1289,21 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S
cipher:list
- The list of allowed ciphers, each separated with
- a colon. Available ciphers can be obtained using
- the "openssl ciphers" command.
+
+ The list of allowed ciphers for this listener, for
+ TLS v1.2 and earlier only, each separated with
+ a colon. Available ciphers can be obtained using
+ the "openssl ciphers" command.
+
+
+
+
+ cipher:list
+
+
+ The list of allowed ciphersuites for this listener,
+ for TLS v1.3, each separated with a colon.
+
diff --git a/mosquitto.conf b/mosquitto.conf
index adb1cac7..243964d0 100644
--- a/mosquitto.conf
+++ b/mosquitto.conf
@@ -257,7 +257,7 @@
# Choose the protocol to use when listening.
# This can be either mqtt or websockets.
# Certificate based TLS may be used with websockets, except that only the
-# cafile, certfile, keyfile and ciphers options are supported.
+# cafile, certfile, keyfile, ciphers, and ciphers_tls13 options are supported.
#protocol mqtt
# Set use_username_as_clientid to true to replace the clientid that a client
@@ -300,9 +300,14 @@
# If you wish to control which encryption ciphers are used, use the ciphers
# option. The list of available ciphers can be optained using the "openssl
# ciphers" command and should be provided in the same format as the output of
-# that command.
+# that command. This applies to TLS 1.2 and earlier versions only. Use
+# ciphers_tls1.3 for TLS v1.3.
#ciphers
+# Choose which TLS v1.3 ciphersuites are used for this listener.
+# Defaults to "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
+#ciphers_tls1.3
+
# If you have require_certificate set to true, you can create a certificate
# revocation list file to revoke access to particular client certificates. If
# you have done this, use crlfile to point to the PEM encoded revocation file.
diff --git a/src/conf.c b/src/conf.c
index c2db4216..aca38d02 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -278,6 +278,7 @@ void config__cleanup(struct mosquitto__config *config)
mosquitto__free(config->listeners[i].certfile);
mosquitto__free(config->listeners[i].keyfile);
mosquitto__free(config->listeners[i].ciphers);
+ mosquitto__free(config->listeners[i].ciphers_tls13);
mosquitto__free(config->listeners[i].psk_hint);
mosquitto__free(config->listeners[i].crlfile);
mosquitto__free(config->listeners[i].dhparamfile);
@@ -428,6 +429,7 @@ int config__parse_args(struct mosquitto__config *config, int argc, char *argv[])
|| config->default_listener.tls_keyform != mosq_k_pem
|| config->default_listener.tls_engine_kpass_sha1
|| config->default_listener.ciphers
+ || config->default_listener.ciphers_tls13
|| config->default_listener.dhparamfile
|| config->default_listener.psk_hint
|| config->default_listener.require_certificate
@@ -492,6 +494,7 @@ int config__parse_args(struct mosquitto__config *config, int argc, char *argv[])
config->listeners[config->listener_count-1].certfile = config->default_listener.certfile;
config->listeners[config->listener_count-1].keyfile = config->default_listener.keyfile;
config->listeners[config->listener_count-1].ciphers = config->default_listener.ciphers;
+ config->listeners[config->listener_count-1].ciphers_tls13 = config->default_listener.ciphers_tls13;
config->listeners[config->listener_count-1].dhparamfile = config->default_listener.dhparamfile;
config->listeners[config->listener_count-1].psk_hint = config->default_listener.psk_hint;
config->listeners[config->listener_count-1].require_certificate = config->default_listener.require_certificate;
@@ -1173,6 +1176,13 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
if(conf__parse_string(&token, "ciphers", &cur_listener->ciphers, saveptr)) return MOSQ_ERR_INVAL;
#else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available.");
+#endif
+ }else if(!strcmp(token, "ciphers_tls1.3")){
+#ifdef WITH_TLS
+ if(reload) continue; /* Listeners not valid for reloading. */
+ if(conf__parse_string(&token, "ciphers_tls1.3", &cur_listener->ciphers_tls13, saveptr)) return MOSQ_ERR_INVAL;
+#else
+ log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available.");
#endif
}else if(!strcmp(token, "clientid") || !strcmp(token, "remote_clientid")){
#ifdef WITH_BRIDGE
diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h
index 18315270..231e4447 100644
--- a/src/mosquitto_broker_internal.h
+++ b/src/mosquitto_broker_internal.h
@@ -228,6 +228,7 @@ struct mosquitto__listener {
char *tls_engine;
char *tls_engine_kpass_sha1;
char *ciphers;
+ char *ciphers_tls13;
char *psk_hint;
SSL_CTX *ssl_ctx;
char *crlfile;
diff --git a/src/net.c b/src/net.c
index 78a1dc56..acd60025 100644
--- a/src/net.c
+++ b/src/net.c
@@ -386,6 +386,16 @@ int net__tls_server_ctx(struct mosquitto__listener *listener)
return MOSQ_ERR_TLS;
}
}
+#if OPENSSL_VERSION_NUMBER >= 0x10101000
+ if(listener->ciphers_tls13){
+ rc = SSL_CTX_set_ciphersuites(listener->ssl_ctx, listener->ciphers_tls13);
+ if(rc == 0){
+ log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set TLS 1.3 ciphersuites. Check cipher_tls13 list \"%s\".", listener->ciphers_tls13);
+ return MOSQ_ERR_TLS;
+ }
+ }
+#endif
+
if(listener->dhparamfile){
dhparamfile = fopen(listener->dhparamfile, "r");
if(!dhparamfile){
diff --git a/src/websockets.c b/src/websockets.c
index f39214c4..63527937 100644
--- a/src/websockets.c
+++ b/src/websockets.c
@@ -753,6 +753,9 @@ struct libwebsocket_context *mosq_websockets_init(struct mosquitto__listener *li
info.ssl_cert_filepath = listener->certfile;
info.ssl_private_key_filepath = listener->keyfile;
info.ssl_cipher_list = listener->ciphers;
+#if defined(WITH_WEBSOCKETS) && LWS_LIBRARY_VERSION_NUMBER>=3001000
+ info->tls_1_3_plus_cipher_list = listener->ciphers_tls13;
+#endif
if(listener->require_certificate){
info.options |= LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT;
}