mbedtls: add CURLOPT_TLS13_CIPHERS support

Bring setting ciphers with mbedTLS in line with other SSL backends,
to make the curl interface more consistent across the backends.

Now the tls1.3 ciphers are set with the --tls13-ciphers option, when
not set the default tls1.3 ciphers are used. The tls1.2 (1.1, 1.0)
ciphers are set with the --ciphers option, when not set the default
tls1.2 ciphers are used. The ciphers available for the connection
are now a union of the tls1.3 and tls1.2 ciphers.

This changes the behaviour for mbedTLS when --ciphers is set, but
--tls13-ciphers is not set. Now the ciphers set with --ciphers
are combined with the default tls1.3 ciphers, whereas before solely
the ciphers of --ciphers were used.

Thus before when no tls1.3 ciphers were specified in --ciphers,
tls1.3 was completely disabled. This might not be what the user
expected, especially as this does not happen with OpenSSL.

Closes #14384
This commit is contained in:
Jan Venekamp 2024-08-04 20:06:27 +02:00 committed by Daniel Stenberg
parent d266d19d86
commit 3f7dc8a404
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 64 additions and 9 deletions

View File

@ -429,11 +429,13 @@ mbed_cipher_suite_walk_str(const char **str, const char **end)
static CURLcode static CURLcode
mbed_set_selected_ciphers(struct Curl_easy *data, mbed_set_selected_ciphers(struct Curl_easy *data,
struct mbed_ssl_backend_data *backend, struct mbed_ssl_backend_data *backend,
const char *ciphers) const char *ciphers12,
const char *ciphers13)
{ {
const char *ciphers = ciphers12;
const int *supported; const int *supported;
int *selected; int *selected;
size_t supported_len, count = 0, i; size_t supported_len, count = 0, default13_count = 0, i, j;
const char *ptr, *end; const char *ptr, *end;
supported = mbedtls_ssl_list_ciphersuites(); supported = mbedtls_ssl_list_ciphersuites();
@ -444,6 +446,26 @@ mbed_set_selected_ciphers(struct Curl_easy *data,
if(!selected) if(!selected)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
#ifndef TLS13_SUPPORT
(void) ciphers13, (void) j;
#else
if(!ciphers13) {
/* Add default TLSv1.3 ciphers to selection */
for(j = 0; j < supported_len; j++) {
uint16_t id = (uint16_t) supported[j];
if(strncmp(mbedtls_ssl_get_ciphersuite_name(id), "TLS1-3", 6) != 0)
continue;
selected[count++] = id;
}
default13_count = count;
}
else
ciphers = ciphers13;
add_ciphers:
#endif
for(ptr = ciphers; ptr[0] != '\0' && count < supported_len; ptr = end) { for(ptr = ciphers; ptr[0] != '\0' && count < supported_len; ptr = end) {
uint16_t id = mbed_cipher_suite_walk_str(&ptr, &end); uint16_t id = mbed_cipher_suite_walk_str(&ptr, &end);
@ -463,6 +485,7 @@ mbed_set_selected_ciphers(struct Curl_easy *data,
/* No duplicates allowed (so selected cannot overflow) */ /* No duplicates allowed (so selected cannot overflow) */
for(i = 0; i < count && selected[i] != id; i++); for(i = 0; i < count && selected[i] != id; i++);
if(i < count) { if(i < count) {
if(i >= default13_count)
infof(data, "mbedTLS: duplicate cipher in list: \"%.*s\"", infof(data, "mbedTLS: duplicate cipher in list: \"%.*s\"",
(int) (end - ptr), ptr); (int) (end - ptr), ptr);
continue; continue;
@ -471,6 +494,29 @@ mbed_set_selected_ciphers(struct Curl_easy *data,
selected[count++] = id; selected[count++] = id;
} }
#ifdef TLS13_SUPPORT
if(ciphers == ciphers13 && ciphers12) {
ciphers = ciphers12;
goto add_ciphers;
}
if(!ciphers12) {
/* Add default TLSv1.2 ciphers to selection */
for(j = 0; j < supported_len; j++) {
uint16_t id = (uint16_t) supported[j];
if(strncmp(mbedtls_ssl_get_ciphersuite_name(id), "TLS1-3", 6) == 0)
continue;
/* No duplicates allowed (so selected cannot overflow) */
for(i = 0; i < count && selected[i] != id; i++);
if(i < count)
continue;
selected[count++] = id;
}
}
#endif
selected[count] = 0; selected[count] = 0;
if(count == 0) { if(count == 0) {
@ -814,9 +860,17 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
mbedtls_bio_cf_read, mbedtls_bio_cf_read,
NULL /* rev_timeout() */); NULL /* rev_timeout() */);
#ifndef TLS13_SUPPORT
if(conn_config->cipher_list) { if(conn_config->cipher_list) {
CURLcode result = mbed_set_selected_ciphers(data, backend, CURLcode result = mbed_set_selected_ciphers(data, backend,
conn_config->cipher_list); conn_config->cipher_list,
NULL);
#else
if(conn_config->cipher_list || conn_config->cipher_list13) {
CURLcode result = mbed_set_selected_ciphers(data, backend,
conn_config->cipher_list,
conn_config->cipher_list13);
#endif
if(result != CURLE_OK) { if(result != CURLE_OK) {
failf(data, "mbedTLS: failed to set cipher suites"); failf(data, "mbedTLS: failed to set cipher suites");
return result; return result;
@ -1669,6 +1723,9 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
SSLSUPP_CERTINFO | SSLSUPP_CERTINFO |
SSLSUPP_PINNEDPUBKEY | SSLSUPP_PINNEDPUBKEY |
SSLSUPP_SSL_CTX | SSLSUPP_SSL_CTX |
#ifdef TLS13_SUPPORT
SSLSUPP_TLS13_CIPHERSUITES |
#endif
SSLSUPP_HTTPS_PROXY, SSLSUPP_HTTPS_PROXY,
sizeof(struct mbed_ssl_backend_data), sizeof(struct mbed_ssl_backend_data),

View File

@ -213,10 +213,8 @@ class TestSSLUse:
pytest.skip('SecureTransport does not support TLSv1.3') pytest.skip('SecureTransport does not support TLSv1.3')
elif env.curl_uses_lib('boringssl'): elif env.curl_uses_lib('boringssl'):
pytest.skip('BoringSSL does not support setting TLSv1.3 ciphers') pytest.skip('BoringSSL does not support setting TLSv1.3 ciphers')
elif env.curl_uses_lib('mbedtls'): elif env.curl_uses_lib('mbedtls') and not env.curl_lib_version_at_least('mbedtls', '3.6.0'):
if not env.curl_lib_version_at_least('mbedtls', '3.6.0'):
pytest.skip('mbedTLS TLSv1.3 support requires at least 3.6.0') pytest.skip('mbedTLS TLSv1.3 support requires at least 3.6.0')
extra_args = ['--ciphers', ':'.join(cipher_names)]
elif env.curl_uses_lib('wolfssl'): elif env.curl_uses_lib('wolfssl'):
extra_args = ['--ciphers', ':'.join(cipher_names)] extra_args = ['--ciphers', ':'.join(cipher_names)]
else: else: