]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
mbedtls: add CURLOPT_TLS13_CIPHERS support
authorJan Venekamp <1422460+jan2000@users.noreply.github.com>
Sun, 4 Aug 2024 18:06:27 +0000 (20:06 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 5 Aug 2024 14:01:20 +0000 (16:01 +0200)
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

lib/vtls/mbedtls.c
tests/http/test_17_ssl_use.py

index d48bf46f3ab9511df63c95675a0e967163b1c198..5b8904b8d01a85125ceffc809dc8483ec7267607 100644 (file)
@@ -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),
index 813bcffd4247ca6e7d5cb9f721096f3658fbb14d..0294502193c1bc34f40dbaf285d65f5fb3f55057 100644 (file)
@@ -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: