The ConnectionCommon<T>::write_vectored was implemented by processing
each chunk, fragmenting them and wrapping each fragment in a
OutboundMessage before encrypting and sending it as separate TLS frames.
For very fragmented payloads this generates a lot of very small payloads
with most of the data being TLS headers.
OutboundChunks can contain an arbitrary amount of fragmented chunks.
This allows write_vectored to process all its chunks at once,
fragmenting it in place if needed and wrapping it in a OutboundMessage.
All the chunks are merged in a contiguous vector (taking atvantage of an
already existent copy) before being encrypted and sent as a single TLS
frame.
Signed-off-by: Eloi DEMOLIS <eloi.demolis@clever-cloud.com>
Co-Authored-By: Emmanuel Bosquet <bjokac@gmail.com>
One can be installed with `CryptoProvider::install_default`.
First call wins.
The current value can be retrieved with `CryptoProvider::get_default()`.
This can be set from the crate features, if and only if they are unambigious,
by installing the result of `CryptoProvider::from_crate_features()`.
Use this for `ClientConfig::builder` and `ServerConfig::builder` et al.
Naturally, `ClientConfig::builder_with_provider` and co. continue to exist.
Change default for `require_ems` based on `fips` crate feature,
generalising the existing tests for `require_ems` to verify this too.
Include `require_ems` in `fips()` determination.
This means a `ClientConfig` and `ServerConfig` can be asked whether it
is in fips mode, and it answers by asking the same of all its
constituent cryptography.
Take new rustls-webpki and pki-types to ask the same of
`SignatureVerificationAlgorithm`.
extension support from peer in TLS 1.2
* Add server config for requiring
`extended_master_secret` extension from peer.
* Add client config for requiring
`extended_master_secret` extension from peer.
* Add tests cases for server and client when requiring
`extended_master_secret` extension from peer.
The `ClientConfig` parts should appear before the types it references.
The `Tls12Resumption` enum should appear after the `Resumption` type
that uses it.
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
This commit adds a `Debug` bound to the `ResolvesClientCert` trait,
alongside `Send` and `Sync`. The types implementing this trait are
updated to either derive `Debug`, or implement it by hand, as
appropriate.
This commit adds a `Debug` bound to the `SideData` trait. The types
implementing it are updated to derive `Debug` or implement it by hand as
appropriate.
This commit adds a `Debug` bound to the `ClientSessionStore` trait,
alongside `Send` and `Sync`. Types implementing the trait are updated
with derived or hand-written `Debug` impls as appropriate, taking care
to avoid leaking any sensitive information.
This commit renames the `ClientCertVerifier::client_auth_root_subjects`
fn to `root_hint_subjects` to emphasize that these subjects
may be distinct from the subjects of the verifier's trust anchors. The
`client_auth` prefix is dropped as obvious from context.
The Rustdoc comment for the trait fn is expanded to give more
information about what these hint subjects are used for, and why there
are instances where the hint subject names aren't 1:1 with the
verifier's root cert store subject names.
Similarly the `ResolvesClientCert::resolve` fn's argument is renamed
from `root_hint_subjects` and the rustdoc gains additional context.
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).
The actually expensive part is mostly the gathering of certificates
from the platform trust root store, and it would be better to document
that in the relevant API (that is, in rustls-native-certs). Apart
from that, I believe that the use of `Arc`-wrapped types is also an
effective signal that the wrapped types should be reused where possible.
The docs formerly said the default maximum was 2**16 (64 kB) but according to
spec (and implementation) it's actually 2**14 (16 kb).
The docs recommended setting to TCP MSS but by my understanding there is a
little record overhead so it's better to set this to a little under the MSS.
Clarified that there is in fact a limit when the default value of None is used.
Use the slightly more precise "TLS record" instead of "TLS message".
This removes duplicated manual feature gates for documentation
and leaves it to `cargo doc` to derive the same information from
the actual feature gates.
I didn't find any gaps in the auto-generated features and what we had
before, but now things like `rustls::cipher_suite::TLS_ECDHE_*`
are correctly marked tls12-only.
This commit adds a `KeyExchange` associated type to the `CryptoProvider`
trait. The `KeyExchange` type is constrained with its own `KeyExchange`
trait that has an associated type for the `SupportedGroup`.
In the `crypto::ring` package we adapt the existing *ring* specific
`KeyExchange` and `SupportedKxGroup` types to these new traits.
Throughout the codebase we tighten generic bounds where required to
ensure we have a `CryptoProvider` bound that allows accessing the
associated `KeyExchange` and `SupportedGroup`. We also make the
`CryptoProvider` an associated type on the `Side` config.
This commit moves the existing Ring-based key exchange mechanisms from
`rustls/src/kx.rs` to `rustls/src/crypto/ring.rs` in anticipation of
adapting the codebase to a more general keyex trait that these types
will implement.
No changes are made to the implementation except to update import paths
to reference the new location.
Originally developed in #1259.
Co-authored-by: Daniel McCarney <daniel@binaryparadox.net>
Co-authored-by: Jacob Hoffman-Andrews <github@hoffman-andrews.com>