]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
vtls/rustls: rustls-ffi 0.14.0 update
authorDaniel McCarney <daniel@binaryparadox.net>
Thu, 12 Sep 2024 16:18:26 +0000 (12:18 -0400)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 13 Sep 2024 12:11:49 +0000 (14:11 +0200)
* Documentation is updated to describe new required version, and to link
  to the upstream README about cryptography providers.
* GitHub workflow is updated to fetch 0.14.0.
* Breaking changes in`lib/vtls/rustls.c` are addressed:
  * The `rustls_client_config_builder_build()` function now uses an out
    parameter for the built config instead of returning it directly.
    This allows the building process to fail if the default crypto
    provider state isn't appropriate, or another error condition occurs.
  * Default ciphersuites are collected using renamed functions named to
    make it clear the ciphersuites are associated with the default
    crypto provider.
  * Customization of ciphersuites is now done via
    a `rustls_crypto_provider_builder` used to instantiate a
    `rustls_crypto_provider`. The customized provider can then can be
    used with `rustls_client_config_builder_new_custom` in place of
    providing ciphersuites directly.
  * `rustls_connection_get_negotiated_ciphersuite()` now returns the
    ciphersuite ID directly.

Closes #14889

.github/workflows/linux.yml
docs/RUSTLS.md
lib/vtls/rustls.c

index 909960dea8e502dfdfb158cdb41de30650f2dc5f..47dd1cc41ee6d35288fc081f8c23d7848bd93967 100644 (file)
@@ -54,7 +54,7 @@ env:
   # unhandled
   quictls-version: 3.1.4+quic
   # renovate: datasource=github-tags depName=rustls/rustls-ffi versioning=semver registryUrl=https://github.com
-  rustls-version: 0.13.0
+  rustls-version: 0.14.0
 
 jobs:
   linux:
index 893fd2134883fa968191b5469277972721a0db0c..e91a090a7ca3d22d85d850613eb3ce34bd804a8d 100644 (file)
@@ -9,7 +9,7 @@ SPDX-License-Identifier: curl
 [Rustls is a TLS backend written in Rust](https://docs.rs/rustls/). Curl can
 be built to use it as an alternative to OpenSSL or other TLS backends. We use
 the [rustls-ffi C bindings](https://github.com/rustls/rustls-ffi/). This
-version of curl depends on version v0.13.0 of rustls-ffi.
+version of curl depends on version v0.14.0 of rustls-ffi.
 
 # Building with Rustls
 
@@ -17,7 +17,7 @@ First, [install Rust](https://rustup.rs/).
 
 Next, check out, build, and install the appropriate version of rustls-ffi:
 
-    % git clone https://github.com/rustls/rustls-ffi -b v0.13.0
+    % git clone https://github.com/rustls/rustls-ffi -b v0.14.0
     % cd rustls-ffi
     % make
     % make DESTDIR=${HOME}/rustls-ffi-built/ install
@@ -30,6 +30,11 @@ Now configure and build curl with Rustls:
     % ./configure --with-rustls=${HOME}/rustls-ffi-built
     % make
 
+See the [rustls-ffi README] for more information on cryptography providers and
+their build/platform requirements.
+
+[rustls-ffi README]: https://github.com/rustls/rustls-ffi/blob/main/README.md#cryptography-provide
+
 ## Randomness
 
 Every TLS libcurl curl supports - *except* Rustls - provides a function for
index e887fbecf23a05125267db73340603a0a9229969..848bd973cd4233c3cb3c4df31f3592fb0ee6a7a8 100644 (file)
@@ -436,7 +436,7 @@ cr_get_selected_ciphers(struct Curl_easy *data,
                         size_t *selected_size)
 {
   size_t supported_len = *selected_size;
-  size_t default_len = rustls_default_ciphersuites_len();
+  size_t default_len = rustls_default_crypto_provider_ciphersuites_len();
   const struct rustls_supported_ciphersuite *entry;
   const char *ciphers = ciphers12;
   size_t count = 0, default13_count = 0, i, j;
@@ -448,7 +448,7 @@ cr_get_selected_ciphers(struct Curl_easy *data,
     /* 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);
+      entry = rustls_default_crypto_provider_ciphersuites_get(j);
       s = rustls_supported_ciphersuite_get_name(entry);
       if(s.len < 5 || strncmp(s.data, "TLS13", 5) != 0)
         continue;
@@ -471,7 +471,7 @@ add_ciphers:
     /* Check if cipher is supported */
     if(id) {
       for(i = 0; i < supported_len; i++) {
-        entry = rustls_all_ciphersuites_get_entry(i);
+        entry = rustls_default_crypto_provider_ciphersuites_get(i);
         if(rustls_supported_ciphersuite_get_suite(entry) == id)
           break;
       }
@@ -506,7 +506,7 @@ add_ciphers:
     /* 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);
+      entry = rustls_default_crypto_provider_ciphersuites_get(j);
       s = rustls_supported_ciphersuite_get_name(entry);
       if(s.len >= 5 && strncmp(s.data, "TLS13", 5) == 0)
         continue;
@@ -529,6 +529,8 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
 {
   struct ssl_connect_data *connssl = cf->ctx;
   struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+  struct rustls_crypto_provider_builder *custom_provider_builder = NULL;
+  const struct rustls_crypto_provider *custom_provider = NULL;
   struct rustls_connection *rconn = NULL;
   struct rustls_client_config_builder *config_builder = NULL;
   const struct rustls_root_cert_store *roots = NULL;
@@ -554,7 +556,8 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
     };
     size_t tls_versions_len = 2;
     const struct rustls_supported_ciphersuite **cipher_suites;
-    size_t cipher_suites_len = rustls_default_ciphersuites_len();
+    size_t cipher_suites_len =
+      rustls_default_crypto_provider_ciphersuites_len();
 
     switch(conn_config->version) {
     case CURL_SSLVERSION_DEFAULT:
@@ -604,11 +607,38 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
       return CURLE_SSL_CIPHER;
     }
 
-    result = rustls_client_config_builder_new_custom(cipher_suites,
-                                                     cipher_suites_len,
-                                                     tls_versions,
-                                                     tls_versions_len,
-                                                     &config_builder);
+    result = rustls_crypto_provider_builder_new_from_default(
+                      &custom_provider_builder);
+    if(result != RUSTLS_RESULT_OK) {
+      failf(data,
+        "rustls: failed to create crypto provider builder from default");
+      return CURLE_SSL_ENGINE_INITFAILED;
+    }
+
+    result =
+      rustls_crypto_provider_builder_set_cipher_suites(
+        custom_provider_builder,
+        cipher_suites,
+        cipher_suites_len);
+    if(result != RUSTLS_RESULT_OK) {
+      failf(data,
+        "rustls: failed to set ciphersuites for crypto provider builder");
+        rustls_crypto_provider_builder_free(custom_provider_builder);
+        return CURLE_SSL_ENGINE_INITFAILED;
+    }
+
+    result = rustls_crypto_provider_builder_build(
+      custom_provider_builder, &custom_provider);
+    if(result != RUSTLS_RESULT_OK) {
+      failf(data, "rustls: failed to build custom crypto provider");
+      rustls_crypto_provider_builder_free(custom_provider_builder);
+      return CURLE_SSL_ENGINE_INITFAILED;
+    }
+
+    result = rustls_client_config_builder_new_custom(custom_provider,
+                                                      tls_versions,
+                                                      tls_versions_len,
+                                                      &config_builder);
     free(cipher_suites);
     if(result != RUSTLS_RESULT_OK) {
       failf(data, "rustls: failed to create client config");
@@ -616,6 +646,9 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
     }
   }
 
+  rustls_crypto_provider_builder_free(custom_provider_builder);
+  rustls_crypto_provider_free(custom_provider);
+
   if(connssl->alpn) {
     struct alpn_proto_buf proto;
     rustls_slice_bytes alpn[ALPN_ENTRIES_MAX];
@@ -710,7 +743,15 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
     rustls_server_cert_verifier_free(server_cert_verifier);
   }
 
-  backend->config = rustls_client_config_builder_build(config_builder);
+  result = rustls_client_config_builder_build(
+    config_builder,
+    &backend->config);
+  if(result != RUSTLS_RESULT_OK) {
+    failf(data, "rustls: failed to build client config");
+    rustls_client_config_free(backend->config);
+    return CURLE_SSL_ENGINE_INITFAILED;
+  }
+
   DEBUGASSERT(rconn == NULL);
   result = rustls_client_connection_new(backend->config,
                                         connssl->peer.hostname, &rconn);
@@ -806,10 +847,7 @@ cr_connect_common(struct Curl_cfilter *cf,
       /* 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;
+        uint16_t cipher = rustls_connection_get_negotiated_ciphersuite(rconn);
         char buf[64] = "";
         const char *ver = "TLS version unknown";
         if(proto == RUSTLS_TLS_VERSION_TLSV1_3)