From: Jan Venekamp <1422460+jan2000@users.noreply.github.com> Date: Sun, 4 Aug 2024 18:06:27 +0000 (+0200) Subject: mbedtls: add CURLOPT_TLS13_CIPHERS support X-Git-Tag: curl-8_10_0~377 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3f7dc8a40437861f1ff190cd402e91d00f1afecc;p=thirdparty%2Fcurl.git 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 --- diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index d48bf46f3a..5b8904b8d0 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -429,11 +429,13 @@ mbed_cipher_suite_walk_str(const char **str, const char **end) static CURLcode mbed_set_selected_ciphers(struct Curl_easy *data, struct mbed_ssl_backend_data *backend, - const char *ciphers) + const char *ciphers12, + const char *ciphers13) { + const char *ciphers = ciphers12; const int *supported; int *selected; - size_t supported_len, count = 0, i; + size_t supported_len, count = 0, default13_count = 0, i, j; const char *ptr, *end; supported = mbedtls_ssl_list_ciphersuites(); @@ -444,6 +446,26 @@ mbed_set_selected_ciphers(struct Curl_easy *data, if(!selected) 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) { uint16_t id = mbed_cipher_suite_walk_str(&ptr, &end); @@ -463,14 +485,38 @@ mbed_set_selected_ciphers(struct Curl_easy *data, /* No duplicates allowed (so selected cannot overflow) */ for(i = 0; i < count && selected[i] != id; i++); if(i < count) { - infof(data, "mbedTLS: duplicate cipher in list: \"%.*s\"", - (int) (end - ptr), ptr); + if(i >= default13_count) + infof(data, "mbedTLS: duplicate cipher in list: \"%.*s\"", + (int) (end - ptr), ptr); continue; } 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; if(count == 0) { @@ -814,9 +860,17 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) mbedtls_bio_cf_read, NULL /* rev_timeout() */); +#ifndef TLS13_SUPPORT if(conn_config->cipher_list) { 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) { failf(data, "mbedTLS: failed to set cipher suites"); return result; @@ -1669,6 +1723,9 @@ const struct Curl_ssl Curl_ssl_mbedtls = { SSLSUPP_CERTINFO | SSLSUPP_PINNEDPUBKEY | SSLSUPP_SSL_CTX | +#ifdef TLS13_SUPPORT + SSLSUPP_TLS13_CIPHERSUITES | +#endif SSLSUPP_HTTPS_PROXY, sizeof(struct mbed_ssl_backend_data), diff --git a/tests/http/test_17_ssl_use.py b/tests/http/test_17_ssl_use.py index 813bcffd42..0294502193 100644 --- a/tests/http/test_17_ssl_use.py +++ b/tests/http/test_17_ssl_use.py @@ -213,10 +213,8 @@ class TestSSLUse: pytest.skip('SecureTransport does not support TLSv1.3') elif env.curl_uses_lib('boringssl'): pytest.skip('BoringSSL does not support setting TLSv1.3 ciphers') - elif env.curl_uses_lib('mbedtls'): - if not env.curl_lib_version_at_least('mbedtls', '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('mbedtls') and not env.curl_lib_version_at_least('mbedtls', '3.6.0'): + pytest.skip('mbedTLS TLSv1.3 support requires at least 3.6.0') elif env.curl_uses_lib('wolfssl'): extra_args = ['--ciphers', ':'.join(cipher_names)] else: