The per-provider key loading functions returned this singleton error,
but it was usually then wrapped into Error::General("invalid private key").
That means the singleton error is unnecessary API surface, but also
it means potentially valuable information is lost.
Move the wrapping into `Error::General` to a lower level, add detail
about which specific parsing operation failed, and pass along error
details from the lower-level library.
`CertificateError` and `CertRevocationListError` both had an `Other` variant
containing `Arc<dyn StdError + Send + Sync>`, while `rustls::Error` used
the newtype `OtherError`. Use `OtherError` in all three cases.
Also, implement `StdError` and `Display` for `OtherError`, and
specifically implement `source()` to return the underlying error.
Also document at the call site for `for_key_exchange` why those guarantees
are upheld.
I didn't get far enough to document where those guarantees are upheld at
the call sites for `for_secret`, but they are relied upon by one of the
implementations:
303b3ff97d/rustls/src/crypto/aws_lc_rs/tls12.rs (L407-L412)
Many projects use CHANGELOG.md to convey their list of changes. Add a
link there. In README.md, instead of describing "release history",
use the "Changelog" terminology.
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.
* Leadership -> membership.
* Clarify roles per member.
* List full-time members and funding source.
* Add Josh Aas, project management.
* Link to GitHub profiles.
When building a client config or a server config using the default
provider we know that the ciphersuites will be compatible with any
choice of protocol version. By having the default `builder` method
configure itself with safe default versions, and offering
a `builder_with_protocol_versions` for customization we can transition
directly to `WantsVerifier` for these default provider builders,
removing a `Result` that will never be an error and making the API more
ergonomic in the common case.
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`.
These helpers assumed the *ring* crypto provider. Consumers can now use
the exported `verify_tls12_signature` and `verify_tls13_signature`
helpers with the crypto provider of their choice to implement these fns.
Similarly since `WebPkiSupportedAlgorithms` now exposes the
`supported_schemes` fn there's no need for the
`default_supported_verify_schemes` helper.
The `verify_tls12_signature` and `verify_tls13_signature` helpers from
the `webpki::verify` module can be useful when implementing a custom
client/server certificate verifier. This commit exports them under the
`crypto` mod alongside the `WebPkiSupportedAlgorithms` type they rely
on.
This small helper is useful in downstream code. The
`WebPkiSupportedAlgorithms` type is already public, and so are the
`SignatureScheme`s returned. Making this available saves downstream
code from having to re-implement this same iterate -> map -> collect.
The old `verify_tls12_signature` referred to a `convert_algs` that
doesn't exist. Let's give more context to both the tls12 and tls13
signature verification fns and link to
`WebPkiSupportedAlgorithms::mapping` for more info.
The crate-internal `verify_signed_struct` and `verify_tls13` helpers in
`webpki::verify` are only used from the context of
`{ClientCertVerifier|ServerCertVerifier}::{verify_tls12_signature|verify_tls13_signature}`
and
`WebPkiServerVerifier::{default_verify_tls12_signature|default_verify_tls13_signature}`.
This commit renames both helpers to match the name used in the
call-sites, making usage clearer.
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.
The top level of the crate is meant for "paved path" exports.
In 0.21.x, there was a top-level `struct Ticketer`.
In current `main`, that's been moved to the separate crypto providers.
Additionally, there is a new public type `TicketSwitcher`. This type
should probably not be at the top level.
The derive(Debug) impl was printing the subject and subjectpublickeyinfo
for every single trust anchor in the root store, which made it very
difficult to read other Debug output that happened to contain a
RootCertStore.
For instance this made the Debug output for ClientConfig extremely long,
because ClientConfig often contains a WebPkiServerVerifier, which
contains a RootCertStore.
In the custom Debug impl, abbreviate the list of roots to simply say how
many of them there are.
Users who want to specifically print the contents of the root cert store
can call `subjects()` and print the output of that.
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.
When implementing a `CryptoProvider` external to this crate, one needs to be able to access the underlying `secret_bytes` after a key exchange when performing the TLS 1.2 PRF.
This change ensures that the bytes can be safely accessed.
The usage of black box was originally introduced to to ensure the optimizer didn't take advantage of
knowing both the client and the server side of the configuration. However, in this case, the server
and the client run in different processes, so each side of the connection has no compile-time
information about the other side.
It was surprising to me that builder_with_provider could set a
CryptoProvider, and then with_cipher_suites could choose implementations
from a different CryptoProvider. I've tried to document things to make
that a little less surprising.
Historically the types that now live in `rustls::crypto::signer` were
present in `rustls::sign`. When the crypto provider work refactored them
into their new home, we also added a `lib.rs` re-export under
`rustls::sign`. This left two import paths for accessing the same types.
To avoid duplicated import paths without causing more downstream
churn from moving the types this commit makes the
`rustls::crypto::signer` module `pub(crate)`, leaving `rustls::sign` as
the sole way to access the contained types externally.
Previously to supply a custom webpki-based server certificate verifier
when building a client configuration the caller had to invoke
`dangerous` to get access to a fn that can accept an `Arc<dyn
verify::ServerCertVerifier>`. We did this because implementing
a `ServerCertVerifier` from scratch leaves a lot of room for dangerous
errors.
However, when providing a `WebPkiServerVerifier` constructed with
`webpki::WebPkiServerVerifier::builder`, there is much less danger.
We've arranged the builder and concrete type to be safe for general
usage.
This commit changes the builder to return the concrete verifier type,
and then adds a new `with_webpki_verifier` fn to the client config
builder that accepts a `Arc<WebPkiServerVerifier` without needing to go
through `dangerous`. This will make the standard case of customizing the
built-in webpki verifier not appear dangerous, while still requiring
fully customized verifiers be provided through the dangerous API.