The top level of the crate is meant for "paved path" exports.
In 0.21.x, this type was in `cipher_suites`, along with a few other
types that got moved to specific crypto providers. Moving this to
`crypto` instead of re-exporting under its old name in `cipher_suites`
seems acceptable, because it will mainly be used in implementing crypto
providers. Also, its internals have changed significantly so there is
already churn for this type.
This commit replaces the existing `CryptoProvider` trait with
a `CryptoProvider` struct. This has several advantages:
* it consolidates all of the cryptography related settings into one API
surface, the `CryptoProvider` struct members. Previously the provider
had methods to suggest default ciphersuites, key exchanges etc, but
the builder API methods could override them in confusing ways.
* it allows removing the `WantsCipherSuites` and `WantsKxGroups` builder
states - the "safe defaults" are automatically supplied by the choice
of a crypto provider. Customization is achieved by overriding the
provider's struct fields. Having fewer builder states makes the API
easier to understand and document.
* it makes customization easier: the end user can rely on "struct update
syntax"[0] to only specify fields values for the required
customization, and defer the rest to an existing `CryptoProvider`.
Achieving this requires a couple of additional changes:
* The cipher suite and key exchange groups are now expressed as `Vec`
elements. This avoids imposing a `&'static` lifetime that would
preclude runtime customization (e.g. the tls*-mio examples that
build the list of ciphersuites at runtime based on command line
flags).
* As a result of the `Vec` members we can no longer offer the concrete
`CryptoProvider`s as `static` members of their respective modules.
Instead we add `pub fn default_provider() -> CryptoProvider` methods
to the `ring` and `aws-lc-rs` module that construct the `CryptoProvider`
with the safe defaults, ready for further customization.
[0]: https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax
In preparation for moving to a struct based model where
a `CryptoProvider` has a `&'static dyn KeyProvider` field, this commit
splits the `KeyProvider` trait from the `CryptoProvider` trait. In its
place `CryptoProvider` gets a `key_provider(&self)` fn that acts as
a stand-in for what will be a field in the struct based approach.
We're working towards making `CryptoProvider` a struct holding distinct
elements to be used for cryptography. To support this the
`load_private_key` fn needs to be lifted to a new trait, `KeyProvider`.
We can hold a `&dyn KeyProvider` in the to-be-added struct to invoke
as required for `load_private_key`.
This commit adds the new trait, includes `KeyProvider` in the existing
`CryptoProvider` trait bounds, and updates the *ring*, aws-lc-rs, and
provider example crypto providers to implement `KeyProvider`.
In preparation for moving to a struct based model where
a `CryptoProvider` has a `&'static dyn SecureRandom` field, this commit
splits the `SecureRandom` trait from the `CryptoProvider` trait. In its
place `CryptoProvider` gets a `secure_random(&self)` fn that acts as
a stand-in for what will be a field in the struct based approach.
We're working towards making `CryptoProvider` a struct holding distinct
elements to be used for cryptography. To support this the `fill_random`
fn needs to be lifted to a new trait, `SecureRandom`. We can hold
a `&dyn SecureRandom` in the to-be-added struct to invoke as required
for `fill_random`. Since the trait now provides additional context, the
fn is renamed from `fill_random` to `fill`.
This commit adds the new trait, includes `SecureRandom` in the existing
`CryptoProvider` trait bounds, and updates the *ring*, aws-lc-rs, and
provider example crypto providers to implement `SecureRandom`.
The top level of the crate is meant for "paved path" exports.
This newly exported type is used for cryptographic provider
customization, so it properly belongs in the `crypto` module.
Previously we had to use `Error::General` when translating
error instances from the hpke-rs dependencies of the provider-example
into `rustls::error::Error` instances, because one of the upstream error
types didn't implement `StdError`.
This commit updates the hpke-rs dependency, bringing in a fix for this
and allowing usage of the more appropriate `Error::GeneralError` error
type.
The goal is to make it possible for provider-example to exist
without implementing (eg) QUIC header protection.
This introduces some knock-on requirements for other types/functions
to be the public, so `quic::Algorithm` can be implemented outside
the crate.
This commit implements the Rustls HPKE provider traits using hpke-rs[0]
with the rust-crypto backend.
Since HPKE is not yet used in Rustls (but will be for ECH support),
a unit test based on the RFC 9180 test vectors is added.
Likely in the future we will want to move this test somewhere outside of
the provider-example crate and use it to test a *ring* HPKE
implementation using the same test vector data.
[0]: https://github.com/franziskuskiefer/hpke-rs
This drastically simplifies `provider-example`. But the
primary goal is ensuring a client configured `with_provider(AWS_LC_RS)`
only uses algorithms from aws-lc-rs, irrespective of crate features.
Naming cipher suites individually seems like a "detail" feature, and
therefore having to name the provider too is not a large imposition.
Naturally this is a breaking change.
Use `Error` instead of `GetRandomFailed` in trait `SupportedKxGroup`,
so that underlying crypto provider could throw errors other than RNG
related errors.
This replaces the HMAC trait in Tls12CipherSuite
(there were no other uses of HMAC).
Provide an implementation of the new PRF trait in terms of
HMAC, for convenience of providers that have a HMAC (common)
but not a separate TLS1.2 PRF (relatively uncommon). The
*ring* and `provider-example/` providers use this.
This commit reworks the `WebPkiServerCertVerifier` type to use
a builder model similar to the `WebPkiClientCertVerifier` type. The new
`ServerCertVerifierBuilder` additionally exposes support for configuring
the depth of revocation status checking, and how to handle unknown
revocation status.
This commit updates `ConnectionTrafficSecrets` to hold `AeadKey` and
`Iv` instances, instead of byte arrays, removing the need for the
`slices_to_arrays` and `slice_to_array` helpers.
In an effort to reduce our feature list, this commit replaces the
`secret_extraction` feature flag with functions that are always present,
but named `dangerous_extract_secrets` to emphasize potential danger.
Cargo features are additive, which means transitive dependencies could
enable them for you without explicit opt-in. Using obviously named
functions will maintain the property that it's easy to grep for imports,
but avoids feature flag bloat and the additive downsides.
In an effort to reduce our feature list, this commit replaces the
`dangerous_configuration` feature flag with separate `danger` modules.
Cargo features are additive, which means transitive dependencies could
enable them for you without explicit opt-in. Using obviously named
modules will maintain the property that it's easy to grep for imports,
but avoids feature flag bloat and the additive downsides.
After discussion we've chosen to not include the webpki verifier and
helper functions as part of the dangerous API surface. Functionality for
setting a custom verifier, or implementing one to make assertions about
verification status, remain marked as dangerous via their module name.
Instead of the type `rustls::crypto:💍:Ring`, the value
`rustls::crypto:💍:RING` implements this, and is more
entertaining to write.
`ServerConfig::builder()` references this by default, and
is equivalent to `ServerConfig::builder_with_provider(crypto:💍:RING)`.
This turns `SupportedKxGroup` into a trait, which can tell you
which `NamedGroup` it is, and `start()` an `ActiveKeyExchange`.
An `ActiveKeyExchange` represents the need for the peer's public key
which can be passed to `ActiveKeyExchange::complete`.
Unfortunately we can't be generic at compile-time over the various uses
of the resulting shared secret, so define a further type
which encapsulates the resulting shared secret.
Predefined key exchange algorithms (eg `rustls::kx_group::X25519`)
are now `&'static dyn rustls::SupportedKxGroup`.
The remainder of this commit is noise as much code ceased needing
to be generic of CryptoProvider (for its `KeyExchange` associated type).
This is an example that builds a mostly-unchanged rustls example
(simpleclient), but only using crypto from the rust-crypto project
and elsewhere.
This is intended to be minimalistic, and not a complete replacement
for *ring*.
It implements:
- TLS1.3 TLS13_CHACHA20_POLY1305_SHA256 cipher suite.
- TLS1.2 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 cipher suite.
- X25519 key exchange.
- RSA-PSS-SHA256 and RSA-PKCS1-SHA256 signature verification for
verifying the server, integrated into the webpki crate.
- random generation using `rand_core`.
This means it can fetch www.rust-lang.org.
TLS1.2 is not strictly necessary for this server, but serves to
demonstrate that part of the API.