commit e6890ae73ceb1e8f38a60a774636d131a18bc00e
parent a7f035f7f85b1314b63fbe05a4165b4d517c75f2
Author: ValdikSS <iam@valdikss.org.ru>
Date: Thu, 26 Jun 2025 10:24:28 -0400
tls: Set TLSv1.3 ciphers to preserve ciphersuites order
This commit fixes two issues:
1. ciphers.inc has TLSv1.3 ciphers prefixed with "TXT", while current version
has "RFC". TLS1_3_RFC_AES_128_GCM_SHA256 should be instead of
TLS1_3_TXT_AES_128_GCM_SHA256, in both define and CIPHER() macro.
2. Tor calls only SSL_set_cipher_list() in tlstls_openssl.c, this sets only
TLSv1.2 ciphers, while TLSv1.3 ciphers stay in default state. TLSv1.3
ciphersuites are set with SSL_set_ciphersuites(), but the list require to
contain only TLSv1.3 suites (no v1.2).
Contrary to SSL_set_cipher_list(), TLSv1.3 SSL_set_ciphersuites() does NOT
accept finalizing :, so it should be stripped out.
Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat:
5 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/changes/tls13-cipher b/changes/tls13-cipher
@@ -0,0 +1,2 @@
+ o Minor feature (client, TLS):
+ - Set the TLS 1.3 cipher list instead of falling back on the default value.
diff --git a/configure.ac b/configure.ac
@@ -1141,7 +1141,8 @@ AC_CHECK_FUNCS([ \
SSL_get_client_ciphers \
SSL_get_client_random \
SSL_get_server_random \
- TLS_method \
+ SSL_set_ciphersuites \
+ TLS_method
])
dnl Check if OpenSSL structures are opaque
diff --git a/src/lib/tls/ciphers_v13.inc b/src/lib/tls/ciphers_v13.inc
@@ -0,0 +1,15 @@
+/* Here are the TLS1.3 ciphers. Note that we don't have XCIPHER instances
+ * here, since we don't want to ever fake them.
+ *
+ * This matches Firefox's list:
+ * https://searchfox.org/mozilla-central/source/security/nss/lib/ssl/ssl3con.c#100
+ */
+#ifdef TLS1_3_RFC_AES_128_GCM_SHA256
+ CIPHER(0x1301, TLS1_3_RFC_AES_128_GCM_SHA256)
+#endif
+#ifdef TLS1_3_RFC_CHACHA20_POLY1305_SHA256
+ CIPHER(0x1303, TLS1_3_RFC_CHACHA20_POLY1305_SHA256)
+#endif
+#ifdef TLS1_3_RFC_AES_256_GCM_SHA384
+ CIPHER(0x1302, TLS1_3_RFC_AES_256_GCM_SHA384)
+#endif
diff --git a/src/lib/tls/include.am b/src/lib/tls/include.am
@@ -33,6 +33,7 @@ src_lib_libtor_tls_testing_a_CFLAGS = \
# ADD_C_FILE: INSERT HEADERS HERE.
noinst_HEADERS += \
src/lib/tls/ciphers.inc \
+ src/lib/tls/ciphers_v13.inc \
src/lib/tls/buffers_tls.h \
src/lib/tls/nss_countbytes.h \
src/lib/tls/tortls.h \
diff --git a/src/lib/tls/tortls_openssl.c b/src/lib/tls/tortls_openssl.c
@@ -493,6 +493,12 @@ static const char CLIENT_CIPHER_LIST[] =
* of any cipher we say. */
"!SSLv2"
;
+static char CLIENT_CIPHER_LIST_TLSv13[] =
+#ifndef COCCI
+#include "lib/tls/ciphers_v13.inc"
+#endif
+ ""
+ ;
#undef CIPHER
#undef XCIPHER
@@ -1136,8 +1142,24 @@ tor_tls_new(tor_socket_t sock, int isServer)
}
#endif /* defined(SSL_CTRL_SET_MAX_PROTO_VERSION) */
- if (!SSL_set_cipher_list(result->ssl,
- isServer ? SERVER_CIPHER_LIST : CLIENT_CIPHER_LIST)) {
+ /* Contrary to SSL_set_cipher_list(), TLSv1.3 SSL_set_ciphersuites() does NOT
+ * accept the final ':' so we have to strip it out. */
+ size_t TLSv13len = strlen(CLIENT_CIPHER_LIST_TLSv13);
+ if (TLSv13len && CLIENT_CIPHER_LIST_TLSv13[TLSv13len - 1] == ':') {
+ CLIENT_CIPHER_LIST_TLSv13[TLSv13len - 1] = '\0';
+ }
+
+ const bool tls12_ciphers_ok = SSL_set_cipher_list(
+ result->ssl, isServer ? SERVER_CIPHER_LIST : CLIENT_CIPHER_LIST);
+ bool tls13_ciphers_ok = true;
+#ifdef HAVE_SSL_SET_CIPHERSUITES
+ if (!isServer) {
+ tls13_ciphers_ok =
+ SSL_set_ciphersuites(result->ssl, CLIENT_CIPHER_LIST_TLSv13);
+ }
+#endif
+
+ if (!tls12_ciphers_ok || !tls13_ciphers_ok) {
tls_log_errors(NULL, LOG_WARN, LD_NET, "setting ciphers");
#ifdef SSL_set_tlsext_host_name
SSL_set_tlsext_host_name(result->ssl, NULL);