use rustls::crypto::CryptoProvider;
use windows::Win32::Security::Cryptography::BCryptGetFipsAlgorithmMode;
use crate::{KeyProvider, SecureRandom, ALL_CIPHER_SUITES, ALL_KX_GROUPS, SUPPORTED_SIG_ALGS};
pub(crate) fn enabled() -> bool {
let mut enabled = 0u8;
unsafe {
BCryptGetFipsAlgorithmMode(&mut enabled).ok().unwrap();
}
enabled != 0
}
pub fn provider() -> CryptoProvider {
CryptoProvider {
cipher_suites: ALL_CIPHER_SUITES
.iter()
.filter(|cs| cs.fips())
.cloned()
.collect(),
kx_groups: ALL_KX_GROUPS
.iter()
.filter(|kx| kx.fips())
.cloned()
.collect(),
signature_verification_algorithms: SUPPORTED_SIG_ALGS,
secure_random: &SecureRandom,
key_provider: &KeyProvider,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn fips() {
let provider = provider();
assert_eq!(provider.fips(), enabled());
}
#[cfg(feature = "fips")]
#[test]
fn fips_provider_has_fips_cipher_suites() {
let provider = provider();
assert!(!provider.cipher_suites.is_empty());
assert!(!provider.kx_groups.is_empty());
assert!(provider.fips());
assert!(provider.cipher_suites.iter().any(|cs| cs.tls13().is_some()));
#[cfg(feature = "tls12")]
assert!(provider.cipher_suites.iter().any(|cs| cs.tls13().is_none()));
dbg!(provider);
}
}