From: Daniel McCarney Date: Thu, 12 Sep 2024 16:18:26 +0000 (-0400) Subject: vtls/rustls: rustls-ffi 0.14.0 update X-Git-Tag: curl-8_10_1~29 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f09adc3ad16b428e9af10ce04e833ddf0885aa12;p=thirdparty%2Fcurl.git vtls/rustls: rustls-ffi 0.14.0 update * 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 --- diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 909960dea8..47dd1cc41e 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -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: diff --git a/docs/RUSTLS.md b/docs/RUSTLS.md index 893fd21348..e91a090a7c 100644 --- a/docs/RUSTLS.md +++ b/docs/RUSTLS.md @@ -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 diff --git a/lib/vtls/rustls.c b/lib/vtls/rustls.c index e887fbecf2..848bd973cd 100644 --- a/lib/vtls/rustls.c +++ b/lib/vtls/rustls.c @@ -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)