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
This commit is contained in:
Daniel McCarney 2024-09-12 12:18:26 -04:00 committed by Daniel Stenberg
parent 65b8d89463
commit f09adc3ad1
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 61 additions and 18 deletions

View 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:

View 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

View 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)