]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
rustls: add support for setting TLS version and ciphers
authorJan Venekamp <1422460+jan2000@users.noreply.github.com>
Tue, 13 Aug 2024 20:01:07 +0000 (22:01 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 16 Aug 2024 07:55:02 +0000 (09:55 +0200)
Add support for CURLOPT_SSLVERSION, CURLOPT_TLS13_CIPHERS and
CURLOPT_SSL_CIPHER_LIST.

Closes #14535

docs/libcurl/opts/CURLOPT_SSLVERSION.md
lib/vtls/cipher_suite.c
lib/vtls/cipher_suite.h
lib/vtls/rustls.c
tests/http/test_17_ssl_use.py
tests/unit/unit3205.c

index cab2d6115501a56acaa4ac87e7927629914037c5..9ac0bc75197a4601fb6e3ad4a88b4b5e6ad2b1b8 100644 (file)
@@ -148,6 +148,8 @@ Since 8.10.0 wolfSSL is fully supported. Before 8.10.0 the MAX macros were not
 supported with wolfSSL and the other macros did not set a minimum, but
 restricted the TLS version to only the specified one.
 
+rustls support added in 8.10.0.
+
 # %AVAILABILITY%
 
 # RETURN VALUE
index af9d55f09af1b9d521d2e40674ca7b95f625cb8f..c025b53e951be5e1fa1a849ffa6c4a5b591e0b93 100644 (file)
@@ -23,7 +23,8 @@
  ***************************************************************************/
 #include "curl_setup.h"
 
-#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL)
+#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \
+    defined(USE_BEARSSL) || defined(USE_RUSTLS)
 #include "cipher_suite.h"
 #include "curl_printf.h"
 #include "strcase.h"
@@ -190,6 +191,28 @@ struct cs_entry {
 
 /* !checksrc! disable COMMANOSPACE all */
 static const struct cs_entry cs_list [] = {
+  /* TLS 1.3 ciphers */
+#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_RUSTLS)
+  CS_ENTRY(0x1301, TLS,AES,128,GCM,SHA256,,,),
+  CS_ENTRY(0x1302, TLS,AES,256,GCM,SHA384,,,),
+  CS_ENTRY(0x1303, TLS,CHACHA20,POLY1305,SHA256,,,,),
+  CS_ENTRY(0x1304, TLS,AES,128,CCM,SHA256,,,),
+  CS_ENTRY(0x1305, TLS,AES,128,CCM,8,SHA256,,),
+#endif
+  /* TLS 1.2 ciphers */
+  CS_ENTRY(0xC02B, TLS,ECDHE,ECDSA,WITH,AES,128,GCM,SHA256),
+  CS_ENTRY(0xC02B, ECDHE,ECDSA,AES128,GCM,SHA256,,,),
+  CS_ENTRY(0xC02C, TLS,ECDHE,ECDSA,WITH,AES,256,GCM,SHA384),
+  CS_ENTRY(0xC02C, ECDHE,ECDSA,AES256,GCM,SHA384,,,),
+  CS_ENTRY(0xC02F, TLS,ECDHE,RSA,WITH,AES,128,GCM,SHA256),
+  CS_ENTRY(0xC02F, ECDHE,RSA,AES128,GCM,SHA256,,,),
+  CS_ENTRY(0xC030, TLS,ECDHE,RSA,WITH,AES,256,GCM,SHA384),
+  CS_ENTRY(0xC030, ECDHE,RSA,AES256,GCM,SHA384,,,),
+  CS_ENTRY(0xCCA8, TLS,ECDHE,RSA,WITH,CHACHA20,POLY1305,SHA256,),
+  CS_ENTRY(0xCCA8, ECDHE,RSA,CHACHA20,POLY1305,,,,),
+  CS_ENTRY(0xCCA9, TLS,ECDHE,ECDSA,WITH,CHACHA20,POLY1305,SHA256,),
+  CS_ENTRY(0xCCA9, ECDHE,ECDSA,CHACHA20,POLY1305,,,,),
+#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL)
   CS_ENTRY(0x002F, TLS,RSA,WITH,AES,128,CBC,SHA,),
   CS_ENTRY(0x002F, AES128,SHA,,,,,,),
   CS_ENTRY(0x0035, TLS,RSA,WITH,AES,256,CBC,SHA,),
@@ -234,26 +257,15 @@ static const struct cs_entry cs_list [] = {
   CS_ENTRY(0xC029, ECDH,RSA,AES128,SHA256,,,,),
   CS_ENTRY(0xC02A, TLS,ECDH,RSA,WITH,AES,256,CBC,SHA384),
   CS_ENTRY(0xC02A, ECDH,RSA,AES256,SHA384,,,,),
-  CS_ENTRY(0xC02B, TLS,ECDHE,ECDSA,WITH,AES,128,GCM,SHA256),
-  CS_ENTRY(0xC02B, ECDHE,ECDSA,AES128,GCM,SHA256,,,),
-  CS_ENTRY(0xC02C, TLS,ECDHE,ECDSA,WITH,AES,256,GCM,SHA384),
-  CS_ENTRY(0xC02C, ECDHE,ECDSA,AES256,GCM,SHA384,,,),
   CS_ENTRY(0xC02D, TLS,ECDH,ECDSA,WITH,AES,128,GCM,SHA256),
   CS_ENTRY(0xC02D, ECDH,ECDSA,AES128,GCM,SHA256,,,),
   CS_ENTRY(0xC02E, TLS,ECDH,ECDSA,WITH,AES,256,GCM,SHA384),
   CS_ENTRY(0xC02E, ECDH,ECDSA,AES256,GCM,SHA384,,,),
-  CS_ENTRY(0xC02F, TLS,ECDHE,RSA,WITH,AES,128,GCM,SHA256),
-  CS_ENTRY(0xC02F, ECDHE,RSA,AES128,GCM,SHA256,,,),
-  CS_ENTRY(0xC030, TLS,ECDHE,RSA,WITH,AES,256,GCM,SHA384),
-  CS_ENTRY(0xC030, ECDHE,RSA,AES256,GCM,SHA384,,,),
   CS_ENTRY(0xC031, TLS,ECDH,RSA,WITH,AES,128,GCM,SHA256),
   CS_ENTRY(0xC031, ECDH,RSA,AES128,GCM,SHA256,,,),
   CS_ENTRY(0xC032, TLS,ECDH,RSA,WITH,AES,256,GCM,SHA384),
   CS_ENTRY(0xC032, ECDH,RSA,AES256,GCM,SHA384,,,),
-  CS_ENTRY(0xCCA8, TLS,ECDHE,RSA,WITH,CHACHA20,POLY1305,SHA256,),
-  CS_ENTRY(0xCCA8, ECDHE,RSA,CHACHA20,POLY1305,,,,),
-  CS_ENTRY(0xCCA9, TLS,ECDHE,ECDSA,WITH,CHACHA20,POLY1305,SHA256,),
-  CS_ENTRY(0xCCA9, ECDHE,ECDSA,CHACHA20,POLY1305,,,,),
+#endif
 #if defined(USE_SECTRANSP) || defined(USE_MBEDTLS)
   CS_ENTRY(0x0001, TLS,RSA,WITH,NULL,MD5,,,),
   CS_ENTRY(0x0001, NULL,MD5,,,,,,),
@@ -327,11 +339,6 @@ static const struct cs_entry cs_list [] = {
   CS_ENTRY(0x00B8, RSA,PSK,NULL,SHA256,,,,),
   CS_ENTRY(0x00B9, TLS,RSA,PSK,WITH,NULL,SHA384,,),
   CS_ENTRY(0x00B9, RSA,PSK,NULL,SHA384,,,,),
-  CS_ENTRY(0x1301, TLS,AES,128,GCM,SHA256,,,),
-  CS_ENTRY(0x1302, TLS,AES,256,GCM,SHA384,,,),
-  CS_ENTRY(0x1303, TLS,CHACHA20,POLY1305,SHA256,,,,),
-  CS_ENTRY(0x1304, TLS,AES,128,CCM,SHA256,,,),
-  CS_ENTRY(0x1305, TLS,AES,128,CCM,8,SHA256,,),
   CS_ENTRY(0xC001, TLS,ECDH,ECDSA,WITH,NULL,SHA,,),
   CS_ENTRY(0xC001, ECDH,ECDSA,NULL,SHA,,,,),
   CS_ENTRY(0xC006, TLS,ECDHE,ECDSA,WITH,NULL,SHA,,),
@@ -881,4 +888,4 @@ int Curl_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size,
 }
 
 #endif /* defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \
-          defined(USE_BEARSSL) */
+          defined(USE_BEARSSL) || defined(USE_RUSTLS) */
index 1dd4d7b400fb905e11240d18e16e99f52c1a6dc8..6d980103a573d7871e0f3065dd733e47dc5d438d 100644 (file)
@@ -26,7 +26,8 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL)
+#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \
+    defined(USE_BEARSSL) || defined(USE_RUSTLS)
 #include <stdint.h>
 
 /* Lookup IANA id for cipher suite string, returns 0 if not recognized */
@@ -43,5 +44,5 @@ int Curl_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size,
                               bool prefer_rfc);
 
 #endif /* defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \
-          defined(USE_BEARSSL) */
+          defined(USE_BEARSSL) || defined(USE_RUSTLS) */
 #endif /* HEADER_CURL_CIPHER_SUITE_H */
index d86c81754aa54c750a3bb13c2eac32cf78bb786f..a044e4565b60d7fa0599a5cea8f41dd40b0c9f40 100644 (file)
@@ -41,6 +41,7 @@
 #include "strerror.h"
 #include "multiif.h"
 #include "connect.h" /* for the connect timeout */
+#include "cipher_suite.h"
 
 struct rustls_ssl_backend_data
 {
@@ -426,6 +427,101 @@ read_file_into(const char *filename,
   return fclose(f) == 0;
 }
 
+static void
+cr_get_selected_ciphers(struct Curl_easy *data,
+                        const char *ciphers12,
+                        const char *ciphers13,
+                        const struct rustls_supported_ciphersuite **selected,
+                        size_t *selected_size)
+{
+  size_t supported_len = *selected_size;
+  size_t default_len = rustls_default_ciphersuites_len();
+  const struct rustls_supported_ciphersuite *entry;
+  const char *ciphers = ciphers12;
+  size_t count = 0, default13_count = 0, i, j;
+  const char *ptr, *end;
+
+  DEBUGASSERT(default_len <= supported_len);
+
+  if(!ciphers13) {
+    /* Add default TLSv1.3 ciphers to selection */
+    for(j = 0; j < default_len; j++) {
+      struct rustls_str s;
+      entry = rustls_default_ciphersuites_get_entry(j);
+      s = rustls_supported_ciphersuite_get_name(entry);
+      if(s.len < 5 || strncmp(s.data, "TLS13", 5) != 0)
+        continue;
+
+      selected[count++] = entry;
+    }
+
+    default13_count = count;
+
+    if(!ciphers)
+      ciphers = "";
+  }
+  else
+    ciphers = ciphers13;
+
+add_ciphers:
+  for(ptr = ciphers; ptr[0] != '\0' && count < supported_len; ptr = end) {
+    uint16_t id = Curl_cipher_suite_walk_str(&ptr, &end);
+
+    /* Check if cipher is supported */
+    if(id) {
+      for(i = 0; i < supported_len; i++) {
+        entry = rustls_all_ciphersuites_get_entry(i);
+        if(rustls_supported_ciphersuite_get_suite(entry) == id)
+          break;
+      }
+      if(i == supported_len)
+        id = 0;
+    }
+    if(!id) {
+      if(ptr[0] != '\0')
+        infof(data, "rustls: unknown cipher in list: \"%.*s\"",
+              (int) (end - ptr), ptr);
+      continue;
+    }
+
+    /* No duplicates allowed (so selected cannot overflow) */
+    for(i = 0; i < count && selected[i] != entry; i++);
+    if(i < count) {
+      if(i >= default13_count)
+        infof(data, "rustls: duplicate cipher in list: \"%.*s\"",
+              (int) (end - ptr), ptr);
+      continue;
+    }
+
+    selected[count++] = entry;
+  }
+
+  if(ciphers == ciphers13 && ciphers12) {
+    ciphers = ciphers12;
+    goto add_ciphers;
+  }
+
+  if(!ciphers12) {
+    /* Add default TLSv1.2 ciphers to selection */
+    for(j = 0; j < default_len; j++) {
+      struct rustls_str s;
+      entry = rustls_default_ciphersuites_get_entry(j);
+      s = rustls_supported_ciphersuite_get_name(entry);
+      if(s.len < 5 || strncmp(s.data, "TLS13", 5) == 0)
+        continue;
+
+      /* No duplicates allowed (so selected cannot overflow) */
+      for(i = 0; i < count && selected[i] != entry; i++);
+      if(i < count)
+        continue;
+
+      selected[count++] = entry;
+    }
+  }
+
+  *selected_size = count;
+}
+
 static CURLcode
 cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
                 struct rustls_ssl_backend_data *const backend)
@@ -450,7 +546,74 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
   DEBUGASSERT(backend);
   rconn = backend->conn;
 
-  config_builder = rustls_client_config_builder_new();
+  {
+    uint16_t tls_versions[2] = {
+        RUSTLS_TLS_VERSION_TLSV1_2,
+        RUSTLS_TLS_VERSION_TLSV1_3,
+    };
+    size_t tls_versions_len = 2;
+    const struct rustls_supported_ciphersuite **cipher_suites;
+    size_t cipher_suites_len = rustls_default_ciphersuites_len();
+
+    switch(conn_config->version) {
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+    case CURL_SSLVERSION_TLSv1_1:
+    case CURL_SSLVERSION_TLSv1_2:
+      break;
+    case CURL_SSLVERSION_TLSv1_3:
+      tls_versions[0] = RUSTLS_TLS_VERSION_TLSV1_3;
+      tls_versions_len = 1;
+      break;
+    default:
+      failf(data, "rustls: unrecognized minimum TLS version value");
+      return CURLE_SSL_ENGINE_INITFAILED;
+    }
+
+    switch(conn_config->version_max) {
+    case CURL_SSLVERSION_MAX_DEFAULT:
+    case CURL_SSLVERSION_MAX_NONE:
+    case CURL_SSLVERSION_MAX_TLSv1_3:
+      break;
+    case CURL_SSLVERSION_MAX_TLSv1_2:
+      if(tls_versions[0] == RUSTLS_TLS_VERSION_TLSV1_2) {
+        tls_versions_len = 1;
+        break;
+      }
+      FALLTHROUGH();
+    case CURL_SSLVERSION_MAX_TLSv1_1:
+    case CURL_SSLVERSION_MAX_TLSv1_0:
+    default:
+      failf(data, "rustls: unsupported maximum TLS version value");
+      return CURLE_SSL_ENGINE_INITFAILED;
+    }
+
+    cipher_suites = malloc(sizeof(cipher_suites) * (cipher_suites_len));
+    if(!cipher_suites)
+      return CURLE_OUT_OF_MEMORY;
+
+    cr_get_selected_ciphers(data,
+                            conn_config->cipher_list,
+                            conn_config->cipher_list13,
+                            cipher_suites, &cipher_suites_len);
+    if(cipher_suites_len == 0) {
+      failf(data, "rustls: no supported cipher in list");
+      free(cipher_suites);
+      return CURLE_SSL_CIPHER;
+    }
+
+    result = rustls_client_config_builder_new_custom(cipher_suites,
+                                                     cipher_suites_len,
+                                                     tls_versions,
+                                                     tls_versions_len,
+                                                     &config_builder);
+    free(cipher_suites);
+    if(result != RUSTLS_RESULT_OK) {
+      failf(data, "rustls: failed to create client config");
+      return CURLE_SSL_ENGINE_INITFAILED;
+    }
+  }
+
   if(connssl->alpn) {
     struct alpn_proto_buf proto;
     rustls_slice_bytes alpn[ALPN_ENTRIES_MAX];
@@ -629,7 +792,6 @@ cr_connect_common(struct Curl_cfilter *cf,
     */
     connssl->io_need = CURL_SSL_IO_NEED_NONE;
     if(!rustls_connection_is_handshaking(rconn)) {
-      infof(data, "Done handshaking");
       /* rustls claims it is no longer handshaking *before* it has
        * send its FINISHED message off. We attempt to let it write
        * one more time. Oh my.
@@ -644,6 +806,22 @@ cr_connect_common(struct Curl_cfilter *cf,
         return tmperr;
       }
       /* REALLY Done with the handshake. */
+      {
+        uint16_t proto = rustls_connection_get_protocol_version(rconn);
+        const rustls_supported_ciphersuite *rcipher =
+            rustls_connection_get_negotiated_ciphersuite(rconn);
+        uint16_t cipher = rcipher ?
+                          rustls_supported_ciphersuite_get_suite(rcipher) : 0;
+        char buf[64] = "";
+        const char *ver = "TLS version unknown";
+        if(proto == RUSTLS_TLS_VERSION_TLSV1_3)
+          ver = "TLSv1.3";
+        if(proto == RUSTLS_TLS_VERSION_TLSV1_2)
+          ver = "TLSv1.2";
+        Curl_cipher_suite_get_str(cipher, buf, sizeof(buf), true);
+        infof(data, "rustls: handshake complete, %s, cipher: %s",
+              ver, buf);
+      }
       connssl->state = ssl_connection_complete;
       *done = TRUE;
       return CURLE_OK;
@@ -847,7 +1025,9 @@ static size_t cr_version(char *buffer, size_t size)
 const struct Curl_ssl Curl_ssl_rustls = {
   { CURLSSLBACKEND_RUSTLS, "rustls" },
   SSLSUPP_CAINFO_BLOB |            /* supports */
-  SSLSUPP_HTTPS_PROXY,
+  SSLSUPP_HTTPS_PROXY |
+  SSLSUPP_CIPHER_LIST |
+  SSLSUPP_TLS13_CIPHERSUITES,
   sizeof(struct rustls_ssl_backend_data),
 
   Curl_none_init,                  /* init */
index 32d45980af96e390112de71385208d6a879af2f3..d4431d414a81208f86eff1924e3fbc7c1e9d6ab7 100644 (file)
@@ -208,8 +208,6 @@ class TestSSLUse:
         extra_args = []
         if env.curl_uses_lib('gnutls'):
             pytest.skip('GnuTLS does not support setting ciphers by name')
-        if env.curl_uses_lib('rustls-ffi'):
-            pytest.skip('rustls-ffi does not support setting ciphers')
         if ciphers[0] & 0xFF00 == 0x1300:
             # test setting TLSv1.3 ciphers
             if env.curl_uses_lib('bearssl'):
index 6b75c28563fcf4c54d35b6481c22f3d5c4cb6ee1..4a2423e6bf54ff8d4a9d4c1d84b231c987729e1a 100644 (file)
@@ -34,7 +34,8 @@ static void unit_stop(void)
 {
 }
 
-#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL)
+#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \
+    defined(USE_BEARSSL) || defined(USE_RUSTLS)
 
 struct test_cs_entry {
   uint16_t id;
@@ -42,6 +43,31 @@ struct test_cs_entry {
   const char *openssl;
 };
 static const struct test_cs_entry test_cs_list[] = {
+#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_RUSTLS)
+  { 0x1301, "TLS_AES_128_GCM_SHA256",
+            NULL },
+  { 0x1302, "TLS_AES_256_GCM_SHA384",
+            NULL },
+  { 0x1303, "TLS_CHACHA20_POLY1305_SHA256",
+            NULL },
+  { 0x1304, "TLS_AES_128_CCM_SHA256",
+            NULL },
+  { 0x1305, "TLS_AES_128_CCM_8_SHA256",
+            NULL },
+#endif
+  { 0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+            "ECDHE-ECDSA-AES128-GCM-SHA256" },
+  { 0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+            "ECDHE-ECDSA-AES256-GCM-SHA384" },
+  { 0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+            "ECDHE-RSA-AES128-GCM-SHA256" },
+  { 0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+            "ECDHE-RSA-AES256-GCM-SHA384" },
+  { 0xCCA8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+            "ECDHE-RSA-CHACHA20-POLY1305" },
+  { 0xCCA9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+            "ECDHE-ECDSA-CHACHA20-POLY1305" },
+#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL)
   { 0x002F, "TLS_RSA_WITH_AES_128_CBC_SHA",
             "AES128-SHA" },
   { 0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA",
@@ -86,26 +112,15 @@ static const struct test_cs_entry test_cs_list[] = {
             "ECDH-RSA-AES128-SHA256" },
   { 0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
             "ECDH-RSA-AES256-SHA384" },
-  { 0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
-            "ECDHE-ECDSA-AES128-GCM-SHA256" },
-  { 0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
-            "ECDHE-ECDSA-AES256-GCM-SHA384" },
   { 0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
             "ECDH-ECDSA-AES128-GCM-SHA256" },
   { 0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
             "ECDH-ECDSA-AES256-GCM-SHA384" },
-  { 0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
-            "ECDHE-RSA-AES128-GCM-SHA256" },
-  { 0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
-            "ECDHE-RSA-AES256-GCM-SHA384" },
   { 0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
             "ECDH-RSA-AES128-GCM-SHA256" },
   { 0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
             "ECDH-RSA-AES256-GCM-SHA384" },
-  { 0xCCA8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
-            "ECDHE-RSA-CHACHA20-POLY1305" },
-  { 0xCCA9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
-            "ECDHE-ECDSA-CHACHA20-POLY1305" },
+#endif
 #if defined(USE_SECTRANSP) || defined(USE_MBEDTLS)
   { 0x0001, "TLS_RSA_WITH_NULL_MD5",
             "NULL-MD5" },
@@ -179,16 +194,6 @@ static const struct test_cs_entry test_cs_list[] = {
             "RSA-PSK-NULL-SHA256" },
   { 0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384",
             "RSA-PSK-NULL-SHA384" },
-  { 0x1301, "TLS_AES_128_GCM_SHA256",
-            NULL },
-  { 0x1302, "TLS_AES_256_GCM_SHA384",
-            NULL },
-  { 0x1303, "TLS_CHACHA20_POLY1305_SHA256",
-            NULL },
-  { 0x1304, "TLS_AES_128_CCM_SHA256",
-            NULL },
-  { 0x1305, "TLS_AES_128_CCM_8_SHA256",
-            NULL },
   { 0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA",
             "ECDH-ECDSA-NULL-SHA" },
   { 0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA",
@@ -604,7 +609,7 @@ struct test_str_entry {
   const char *str;
 };
 static const struct test_str_entry test_str_list[] = {
-#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS)
+#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_RUSTLS)
   { 0x1301, "TLS_AES_128_GCM_SHA256"},
   { 0x1302, "TLS_AES_256_GCM_SHA384"},
   { 0x1303, "TLS_CHACHA20_POLY1305_SHA256"},
@@ -631,6 +636,7 @@ static const struct test_str_entry test_str_list[] = {
 #else
   { 0x0000, "DHE-RSA-CHACHA20-POLY1305"},
 #endif
+#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL)
   { 0xC023, "ECDHE-ECDSA-AES128-SHA256" },
   { 0xC027, "ECDHE-RSA-AES128-SHA256" },
   { 0xC009, "ECDHE-ECDSA-AES128-SHA" },
@@ -639,6 +645,16 @@ static const struct test_str_entry test_str_list[] = {
   { 0xC028, "ECDHE-RSA-AES256-SHA384" },
   { 0xC00A, "ECDHE-ECDSA-AES256-SHA" },
   { 0xC014, "ECDHE-RSA-AES256-SHA" },
+#else
+  { 0x0000, "ECDHE-ECDSA-AES128-SHA256" },
+  { 0x0000, "ECDHE-RSA-AES128-SHA256" },
+  { 0x0000, "ECDHE-ECDSA-AES128-SHA" },
+  { 0x0000, "ECDHE-RSA-AES128-SHA" },
+  { 0x0000, "ECDHE-ECDSA-AES256-SHA384" },
+  { 0x0000, "ECDHE-RSA-AES256-SHA384" },
+  { 0x0000, "ECDHE-ECDSA-AES256-SHA" },
+  { 0x0000, "ECDHE-RSA-AES256-SHA" },
+#endif
 #if defined(USE_SECTRANSP) || defined(USE_MBEDTLS)
   { 0x0067, "DHE-RSA-AES128-SHA256" },
   { 0x006B, "DHE-RSA-AES256-SHA256" },
@@ -646,12 +662,21 @@ static const struct test_str_entry test_str_list[] = {
   { 0x0000, "DHE-RSA-AES128-SHA256" },
   { 0x0000, "DHE-RSA-AES256-SHA256" },
 #endif
+#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL)
   { 0x009C, "AES128-GCM-SHA256" },
   { 0x009D, "AES256-GCM-SHA384" },
   { 0x003C, "AES128-SHA256" },
   { 0x003D, "AES256-SHA256" },
   { 0x002F, "AES128-SHA" },
   { 0x0035, "AES256-SHA" },
+#else
+  { 0x0000, "AES128-GCM-SHA256" },
+  { 0x0000, "AES256-GCM-SHA384" },
+  { 0x0000, "AES128-SHA256" },
+  { 0x0000, "AES256-SHA256" },
+  { 0x0000, "AES128-SHA" },
+  { 0x0000, "AES256-SHA" },
+#endif
 #if defined(USE_SECTRANSP) || defined(USE_BEARSSL)
   { 0x000A, "DES-CBC3-SHA" },
 #else
@@ -769,4 +794,4 @@ UNITTEST_START
 UNITTEST_STOP
 
 #endif /* defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \
-          defined(USE_BEARSSL) */
+          defined(USE_BEARSSL) || defined(USE_RUSTLS) */