]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
rustls: make curl compile with 0.12.0
authorkpcyrd <git@rxv.cc>
Sun, 25 Feb 2024 20:50:18 +0000 (21:50 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 26 Feb 2024 07:59:43 +0000 (08:59 +0100)
Closes #12989

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

index b655c963798e3e845bb8dfa3290782c5f5529664..3d447a871bc19e0977169272b901d65a751167aa 100644 (file)
@@ -48,7 +48,7 @@ env:
   msh3-version: v0.6.0
   openssl3-version: openssl-3.1.3
   quictls-version: 3.1.4+quic
-  rustls-version: v0.10.0
+  rustls-version: v0.12.0
 
 jobs:
   autotools:
index 7a0d806b627e913bf18aa9c2190bfad592b84696..3515e166625fb0349a0bca6ae0b10cd8930b109f 100644 (file)
@@ -3,7 +3,7 @@
 [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.10.0 of rustls-ffi.
+version of curl depends on version v0.12.0 of rustls-ffi.
 
 # Building with rustls
 
@@ -12,7 +12,7 @@ First, [install Rust](https://rustup.rs/).
 Next, check out, build, and install the appropriate version of rustls-ffi:
 
     % cargo install cbindgen
-    % git clone https://github.com/rustls/rustls-ffi -b v0.10.0
+    % git clone https://github.com/rustls/rustls-ffi -b v0.12.0
     % cd rustls-ffi
     % make
     % make DESTDIR=${HOME}/rustls-ffi-built/ install
index ee537b913f346dfbf2fcc1835a39e1ef987e590b..f1b3ccd664cb3f741fb5df3ca02e7bdc240bfeba 100644 (file)
--- a/docs/TODO
+++ b/docs/TODO
  13.12 Reduce CA certificate bundle reparsing
  13.13 Make sure we forbid TLS 1.3 post-handshake authentication
  13.14 Support the clienthello extension
- 13.15 Support latest rustls
 
  14. GnuTLS
  14.2 check connection
  https://datatracker.ietf.org/doc/html/rfc7685
  https://github.com/curl/curl/issues/2299
 
-13.15 Support latest rustls
-
- The rustls backend does not build with the latest rustls-ffi version due to
- API changes. Taking this bump should be a first step towards fixing the
- remaining issues that still keeps the rustls backend experimental in curl.
-
- See https://github.com/curl/curl/issues/12737
-
 14. GnuTLS
 
 14.2 check connection
index d58970910c59d2f6fe17954b998fa8f6fcc9016e..485b1d389057bdcc991a61296ead2654d1214ade 100644 (file)
@@ -7,6 +7,7 @@
  *
  * Copyright (C) Jacob Hoffman-Andrews,
  * <github@hoffman-andrews.com>
+ * Copyright (C) kpcyrd, <kpcyrd@archlinux.org>
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -373,7 +374,10 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
   struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
   struct rustls_connection *rconn = NULL;
   struct rustls_client_config_builder *config_builder = NULL;
-  struct rustls_root_cert_store *roots = NULL;
+  const struct rustls_root_cert_store *roots = NULL;
+  struct rustls_root_cert_store_builder *roots_builder = NULL;
+  struct rustls_web_pki_server_cert_verifier_builder *verifier_builder = NULL;
+  struct rustls_server_cert_verifier *server_cert_verifier = NULL;
   const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
   const char * const ssl_cafile =
     /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
@@ -414,38 +418,60 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
       hostname = "example.invalid";
     }
   }
-  else if(ca_info_blob) {
-    roots = rustls_root_cert_store_new();
-
-    /* Enable strict parsing only if verification isn't disabled. */
-    result = rustls_root_cert_store_add_pem(roots, ca_info_blob->data,
-                                            ca_info_blob->len, verifypeer);
-    if(result != RUSTLS_RESULT_OK) {
-      failf(data, "rustls: failed to parse trusted certificates from blob");
-      rustls_root_cert_store_free(roots);
-      rustls_client_config_free(
-        rustls_client_config_builder_build(config_builder));
-      return CURLE_SSL_CACERT_BADFILE;
+  else if(ca_info_blob || ssl_cafile) {
+    roots_builder = rustls_root_cert_store_builder_new();
+
+    if(ca_info_blob) {
+      /* Enable strict parsing only if verification isn't disabled. */
+      result = rustls_root_cert_store_builder_add_pem(roots_builder,
+                                                      ca_info_blob->data,
+                                                      ca_info_blob->len,
+                                                      verifypeer);
+      if(result != RUSTLS_RESULT_OK) {
+        failf(data, "rustls: failed to parse trusted certificates from blob");
+        rustls_root_cert_store_builder_free(roots_builder);
+        rustls_client_config_free(
+          rustls_client_config_builder_build(config_builder));
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+    }
+    else if(ssl_cafile) {
+      /* Enable strict parsing only if verification isn't disabled. */
+      result = rustls_root_cert_store_builder_load_roots_from_file(
+        roots_builder, ssl_cafile, verifypeer);
+      if(result != RUSTLS_RESULT_OK) {
+        failf(data, "rustls: failed to load trusted certificates");
+        rustls_root_cert_store_builder_free(roots_builder);
+        rustls_client_config_free(
+          rustls_client_config_builder_build(config_builder));
+        return CURLE_SSL_CACERT_BADFILE;
+      }
     }
 
-    result = rustls_client_config_builder_use_roots(config_builder, roots);
-    rustls_root_cert_store_free(roots);
+    result = rustls_root_cert_store_builder_build(roots_builder, &roots);
+    rustls_root_cert_store_builder_free(roots_builder);
     if(result != RUSTLS_RESULT_OK) {
       failf(data, "rustls: failed to load trusted certificates");
       rustls_client_config_free(
         rustls_client_config_builder_build(config_builder));
       return CURLE_SSL_CACERT_BADFILE;
     }
-  }
-  else if(ssl_cafile) {
-    result = rustls_client_config_builder_load_roots_from_file(
-      config_builder, ssl_cafile);
+
+    verifier_builder = rustls_web_pki_server_cert_verifier_builder_new(roots);
+
+    result = rustls_web_pki_server_cert_verifier_builder_build(
+      verifier_builder, &server_cert_verifier);
+    rustls_web_pki_server_cert_verifier_builder_free(verifier_builder);
     if(result != RUSTLS_RESULT_OK) {
       failf(data, "rustls: failed to load trusted certificates");
+      rustls_server_cert_verifier_free(server_cert_verifier);
       rustls_client_config_free(
         rustls_client_config_builder_build(config_builder));
       return CURLE_SSL_CACERT_BADFILE;
     }
+
+    rustls_client_config_builder_set_server_verifier(config_builder,
+                                                     server_cert_verifier);
   }
 
   backend->config = rustls_client_config_builder_build(config_builder);