#![warn(missing_docs)]
use openssl::rand::rand_priv_bytes;
use rustls::SupportedCipherSuite;
use rustls::crypto::{CryptoProvider, GetRandomFailed, SupportedKxGroup};
mod aead;
mod hash;
mod hkdf;
mod hmac;
pub mod kx_group;
mod openssl_internal;
#[cfg(feature = "tls12")]
mod prf;
mod quic;
mod signer;
#[cfg(feature = "tls12")]
mod tls12;
mod tls13;
mod verify;
pub mod cipher_suite {
#[cfg(feature = "tls12")]
pub use super::tls12::{
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
};
#[cfg(all(feature = "tls12", chacha, not(feature = "fips")))]
pub use super::tls12::{
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
};
#[cfg(all(chacha, not(feature = "fips")))]
pub use super::tls13::TLS13_CHACHA20_POLY1305_SHA256;
pub use super::tls13::{TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384};
}
pub use signer::KeyProvider;
pub use verify::SUPPORTED_SIG_ALGS;
pub fn default_provider() -> CryptoProvider {
CryptoProvider {
cipher_suites: ALL_CIPHER_SUITES.to_vec(),
kx_groups: kx_group::DEFAULT_KX_GROUPS.to_vec(),
signature_verification_algorithms: SUPPORTED_SIG_ALGS,
secure_random: &SecureRandom,
key_provider: &KeyProvider,
}
}
pub fn custom_provider(
cipher_suites: Vec<SupportedCipherSuite>,
kx_groups: Vec<&'static dyn SupportedKxGroup>,
) -> CryptoProvider {
CryptoProvider {
cipher_suites,
kx_groups,
signature_verification_algorithms: SUPPORTED_SIG_ALGS,
secure_random: &SecureRandom,
key_provider: &KeyProvider,
}
}
pub static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[
tls13::TLS13_AES_256_GCM_SHA384,
tls13::TLS13_AES_128_GCM_SHA256,
#[cfg(all(chacha, not(feature = "fips")))]
tls13::TLS13_CHACHA20_POLY1305_SHA256,
#[cfg(feature = "tls12")]
tls12::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
#[cfg(feature = "tls12")]
tls12::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
#[cfg(all(feature = "tls12", chacha, not(feature = "fips")))]
tls12::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
#[cfg(feature = "tls12")]
tls12::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
#[cfg(feature = "tls12")]
tls12::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
#[cfg(all(feature = "tls12", chacha, not(feature = "fips")))]
tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
];
#[derive(Debug)]
pub struct SecureRandom;
impl rustls::crypto::SecureRandom for SecureRandom {
fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed> {
rand_priv_bytes(buf).map_err(|_| GetRandomFailed)
}
fn fips(&self) -> bool {
fips::enabled()
}
}
pub mod fips {
#[cfg(fips_module)]
pub(crate) fn enabled() -> bool {
openssl::fips::enabled()
}
#[cfg(not(fips_module))]
pub(crate) fn enabled() -> bool {
unsafe { openssl_sys::EVP_default_properties_is_fips_enabled(std::ptr::null_mut()) == 1 }
}
#[cfg(fips_module)]
pub fn enable() {
openssl::fips::enable(true).expect("Failed to enable FIPS mode.");
}
#[cfg(not(fips_module))]
pub fn enable() {
use once_cell::sync::OnceCell;
use crate::openssl_internal;
static PROVIDER: OnceCell<openssl::provider::Provider> = OnceCell::new();
PROVIDER.get_or_init(|| {
let provider = openssl::provider::Provider::load(None, "fips")
.expect("Failed to load FIPS provider.");
unsafe {
openssl_internal::cvt(openssl_sys::EVP_default_properties_enable_fips(
std::ptr::null_mut(),
1,
))
.expect("Failed to enable FIPS properties.");
}
provider
});
}
}