From: ValdikSS Date: Thu, 26 Jun 2025 14:24:28 +0000 (-0400) Subject: tls: Set TLSv1.3 ciphers to preserve ciphersuites order X-Git-Tag: tor-0.4.8.17~3^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e6890ae73ceb1e8f38a60a774636d131a18bc00e;p=thirdparty%2Ftor.git 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 --- diff --git a/changes/tls13-cipher b/changes/tls13-cipher new file mode 100644 index 0000000000..86eb934ee8 --- /dev/null +++ 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 index bc8ce18729..64448ba945 100644 --- 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 new file mode 100644 index 0000000000..1f2aa68f4f --- /dev/null +++ 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 index 7e05ef4f8c..27c1d057e0 100644 --- 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 index a1f24c6761..5654f7f654 100644 --- 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);