Struct CryptoProvider
pub struct CryptoProvider {
pub cipher_suites: Vec<SupportedCipherSuite>,
pub kx_groups: Vec<&'static dyn SupportedKxGroup>,
pub signature_verification_algorithms: WebPkiSupportedAlgorithms,
pub secure_random: &'static dyn SecureRandom,
pub key_provider: &'static dyn KeyProvider,
}
Expand description
Controls core cryptography used by rustls.
This crate comes with two built-in options, provided as
CryptoProvider
structures:
- [
crypto::aws_lc_rs::default_provider
]: (behind theaws_lc_rs
feature, which is enabled by default). This provider uses the aws-lc-rs crate. Thefips
crate feature makes this option use FIPS140-3-approved cryptography. - [
crypto::ring::default_provider
]: (behind thering
crate feature, which is optional). This provider uses the ring crate.
This structure provides defaults. Everything in it can be overridden at runtime by replacing field values as needed.
§Using the per-process default CryptoProvider
There is the concept of an implicit default provider, configured at run-time once in a given process.
It is used for functions like [ClientConfig::builder()
] and [ServerConfig::builder()
].
The intention is that an application can specify the CryptoProvider
they wish to use
once, and have that apply to the variety of places where their application does TLS
(which may be wrapped inside other libraries).
They should do this by calling CryptoProvider::install_default()
early on.
To achieve this goal:
- libraries should use [
ClientConfig::builder()
]/[ServerConfig::builder()
] or otherwise rely on theCryptoProvider::get_default()
provider. - applications should call
CryptoProvider::install_default()
early in theirfn main()
. If applications uses a custom provider based on the one built-in, they can activate thecustom-provider
feature to ensure its usage.
§Using a specific CryptoProvider
Supply the provider when constructing your [ClientConfig
] or [ServerConfig
]:
- [
ClientConfig::builder_with_provider()
] - [
ServerConfig::builder_with_provider()
]
When creating and configuring a webpki-backed client or server certificate verifier, a choice of provider is also needed to start the configuration process:
- [
client::WebPkiServerVerifier::builder_with_provider()
] - [
server::WebPkiClientVerifier::builder_with_provider()
]
If you install a custom provider and want to avoid any accidental use of a built-in provider, the feature
custom-provider
can be activated to ensure your custom provider is used everywhere
and not a built-in one. This will disable any implicit use of a built-in provider.
§Making a custom CryptoProvider
Your goal will be to populate a [crypto::CryptoProvider
] struct instance.
§Which elements are required?
There is no requirement that the individual elements (SupportedCipherSuite
, SupportedKxGroup
,
SigningKey
, etc.) come from the same crate. It is allowed and expected that uninteresting
elements would be delegated back to one of the default providers (statically) or a parent
provider (dynamically).
For example, if we want to make a provider that just overrides key loading in the config builder
API ([ConfigBuilder::with_single_cert
] etc.), it might look like this:
use rustls::crypto::aws_lc_rs;
pub fn provider() -> rustls::crypto::CryptoProvider {
rustls::crypto::CryptoProvider{
key_provider: &HsmKeyLoader,
..aws_lc_rs::default_provider()
}
}
#[derive(Debug)]
struct HsmKeyLoader;
impl rustls::crypto::KeyProvider for HsmKeyLoader {
fn load_private_key(&self, key_der: pki_types::PrivateKeyDer<'static>) -> Result<Arc<dyn rustls::sign::SigningKey>, rustls::Error> {
fictious_hsm_api::load_private_key(key_der)
}
}
§References to the individual elements
The elements are documented separately:
- Random - see [
crypto::SecureRandom::fill()
]. - Cipher suites - see [
SupportedCipherSuite
], [Tls12CipherSuite
], and [Tls13CipherSuite
]. - Key exchange groups - see [
crypto::SupportedKxGroup
]. - Signature verification algorithms - see [
crypto::WebPkiSupportedAlgorithms
]. - Authentication key loading - see [
crypto::KeyProvider::load_private_key()
] and [sign::SigningKey
].
§Example code
See provider-example/ for a full client and server example that uses cryptography from the rust-crypto and dalek-cryptography projects.
$ cargo run --example client | head -3
Current ciphersuite: TLS13_CHACHA20_POLY1305_SHA256
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 19899
§FIPS-approved cryptography
The fips
crate feature enables use of the aws-lc-rs
crate in FIPS mode.
You can verify the configuration at runtime by checking
[ServerConfig::fips()
]/[ClientConfig::fips()
] return true
.
Fields§
§cipher_suites: Vec<SupportedCipherSuite>
List of supported ciphersuites, in preference order – the first element is the highest priority.
The SupportedCipherSuite
type carries both configuration and implementation.
A valid CryptoProvider
must ensure that all cipher suites are accompanied by at least
one matching key exchange group in CryptoProvider::kx_groups
.
kx_groups: Vec<&'static dyn SupportedKxGroup>
List of supported key exchange groups, in preference order – the first element is the highest priority.
The first element in this list is the default key share algorithm, and in TLS1.3 a key share for it is sent in the client hello.
The SupportedKxGroup
type carries both configuration and implementation.
signature_verification_algorithms: WebPkiSupportedAlgorithms
List of signature verification algorithms for use with webpki.
These are used for both certificate chain verification and handshake signature verification.
This is called by [ConfigBuilder::with_root_certificates()
],
[server::WebPkiClientVerifier::builder_with_provider()
] and
[client::WebPkiServerVerifier::builder_with_provider()
].
secure_random: &'static dyn SecureRandom
Source of cryptographically secure random numbers.
key_provider: &'static dyn KeyProvider
Provider for loading private SigningKeys from PrivateKeyDer.
Implementations§
§impl CryptoProvider
impl CryptoProvider
pub fn install_default(self) -> Result<(), Arc<CryptoProvider>>
pub fn install_default(self) -> Result<(), Arc<CryptoProvider>>
Sets this CryptoProvider
as the default for this process.
This can be called successfully at most once in any process execution.
Call this early in your process to configure which provider is used for
the provider. The configuration should happen before any use of
[ClientConfig::builder()
] or [ServerConfig::builder()
].
pub fn get_default() -> Option<&'static Arc<CryptoProvider>>
pub fn get_default() -> Option<&'static Arc<CryptoProvider>>
Returns the default CryptoProvider
for this process.
This will be None
if no default has been set yet.
pub fn fips(&self) -> bool
pub fn fips(&self) -> bool
Returns true
if this CryptoProvider
is operating in FIPS mode.
This covers only the cryptographic parts of FIPS approval. There are
also TLS protocol-level recommendations made by NIST. You should
prefer to call [ClientConfig::fips()
] or [ServerConfig::fips()
]
which take these into account.
Trait Implementations§
§impl Clone for CryptoProvider
impl Clone for CryptoProvider
§fn clone(&self) -> CryptoProvider
fn clone(&self) -> CryptoProvider
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreAuto Trait Implementations§
impl Freeze for CryptoProvider
impl !RefUnwindSafe for CryptoProvider
impl Send for CryptoProvider
impl Sync for CryptoProvider
impl Unpin for CryptoProvider
impl !UnwindSafe for CryptoProvider
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§fn and<S, P, B, E>(self, other: P) -> And<T, P>
fn and<S, P, B, E>(self, other: P) -> And<T, P>
Policy
that returns Action::Follow
only if self
and other
return
Action::Follow
. Read more§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.