#![deny(unsafe_code)]
#![deny(clippy::unwrap_used)]
#![deny(clippy::panic)]
#![allow(deprecated)]
use crate::tls::{TlsConfig, TlsMode};
use crate::unified_api::{PerformancePreference, SecurityLevel};
pub const DEFAULT_TLS_KEX: &str = "X25519MLKEM768";
pub const DEFAULT_TLS_SCHEME: &str = "hybrid-x25519-ml-kem-768";
pub const HYBRID_TLS_512: &str = "hybrid-x25519-ml-kem-512";
pub const HYBRID_TLS_768: &str = "hybrid-x25519-ml-kem-768";
pub const HYBRID_TLS_1024: &str = "hybrid-x25519-ml-kem-1024";
pub const DEFAULT_PQ_TLS_KEX: &str = "MLKEM768";
pub const DEFAULT_PQ_TLS_SCHEME: &str = "pq-ml-kem-768";
pub const PQ_TLS_512: &str = "pq-ml-kem-512";
pub const PQ_TLS_768: &str = "pq-ml-kem-768";
pub const PQ_TLS_1024: &str = "pq-ml-kem-1024";
pub const CLASSICAL_TLS_KEX: &str = "X25519";
pub const CLASSICAL_TLS_SCHEME: &str = "classic-x25519";
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TlsUseCase {
WebServer,
InternalService,
ApiGateway,
IoT,
LegacyIntegration,
FinancialServices,
Healthcare,
Government,
DatabaseConnection,
RealTimeStreaming,
}
impl TlsUseCase {
#[must_use]
pub fn description(&self) -> &'static str {
match self {
Self::WebServer => "Web server serving public clients",
Self::InternalService => "Internal microservice communication",
Self::ApiGateway => "API gateway or reverse proxy",
Self::IoT => "IoT or embedded devices",
Self::LegacyIntegration => "Legacy system integration",
Self::FinancialServices => "Financial services",
Self::Healthcare => "Healthcare systems",
Self::Government => "Government or high-security",
Self::DatabaseConnection => "Database connections",
Self::RealTimeStreaming => "Real-time streaming",
}
}
#[must_use]
pub fn all() -> &'static [TlsUseCase] {
&[
Self::WebServer,
Self::InternalService,
Self::ApiGateway,
Self::IoT,
Self::LegacyIntegration,
Self::FinancialServices,
Self::Healthcare,
Self::Government,
Self::DatabaseConnection,
Self::RealTimeStreaming,
]
}
}
#[derive(Debug, Clone, Default)]
pub struct TlsConstraints {
pub max_handshake_latency_ms: Option<u64>,
pub client_supports_pq: Option<bool>,
pub require_compatibility: bool,
pub max_client_hello_size: Option<usize>,
}
impl TlsConstraints {
#[must_use]
pub fn maximum_compatibility() -> Self {
Self {
max_handshake_latency_ms: Some(50),
client_supports_pq: Some(false),
require_compatibility: true,
max_client_hello_size: Some(512),
}
}
#[must_use]
pub fn high_security() -> Self {
Self {
max_handshake_latency_ms: None,
client_supports_pq: Some(true),
require_compatibility: false,
max_client_hello_size: None,
}
}
#[must_use]
pub fn requires_classic(&self) -> bool {
if self.client_supports_pq == Some(false) {
return true;
}
if self.require_compatibility {
return true;
}
if let Some(latency) = self.max_handshake_latency_ms
&& latency < 20
{
return true;
}
if let Some(max_size) = self.max_client_hello_size
&& max_size < 1500
{
return true;
}
false
}
#[must_use]
pub fn allows_pq(&self) -> bool {
if self.client_supports_pq == Some(false) {
return false;
}
if self.require_compatibility {
return false;
}
true
}
}
#[derive(Debug, Clone)]
pub struct TlsContext {
pub security_level: SecurityLevel,
pub performance_preference: PerformancePreference,
pub use_case: Option<TlsUseCase>,
pub pq_available: bool,
pub constraints: TlsConstraints,
}
impl Default for TlsContext {
fn default() -> Self {
Self {
security_level: SecurityLevel::High,
performance_preference: PerformancePreference::Balanced,
use_case: None,
pq_available: crate::tls::pq_enabled(),
constraints: TlsConstraints::default(),
}
}
}
impl TlsContext {
#[must_use]
pub fn with_security_level(security_level: SecurityLevel) -> Self {
Self { security_level, ..Default::default() }
}
#[must_use]
pub fn with_use_case(use_case: TlsUseCase) -> Self {
Self { use_case: Some(use_case), ..Default::default() }
}
#[must_use]
pub fn new(
security_level: SecurityLevel,
performance_preference: PerformancePreference,
use_case: Option<TlsUseCase>,
pq_available: bool,
constraints: TlsConstraints,
) -> Self {
Self { security_level, performance_preference, use_case, pq_available, constraints }
}
#[must_use]
pub fn security_level(mut self, level: SecurityLevel) -> Self {
self.security_level = level;
self
}
#[must_use]
pub fn performance_preference(mut self, pref: PerformancePreference) -> Self {
self.performance_preference = pref;
self
}
#[must_use]
pub fn use_case(mut self, use_case: TlsUseCase) -> Self {
self.use_case = Some(use_case);
self
}
#[must_use]
pub fn constraints(mut self, constraints: TlsConstraints) -> Self {
self.constraints = constraints;
self
}
#[must_use]
pub fn pq_available(mut self, available: bool) -> Self {
self.pq_available = available;
self
}
}
pub struct TlsPolicyEngine;
impl TlsPolicyEngine {
#[must_use]
pub fn recommend_mode(use_case: TlsUseCase) -> TlsMode {
match use_case {
TlsUseCase::WebServer => TlsMode::Hybrid,
TlsUseCase::InternalService => TlsMode::Hybrid,
TlsUseCase::ApiGateway => TlsMode::Hybrid,
TlsUseCase::IoT => TlsMode::Classic,
TlsUseCase::LegacyIntegration => TlsMode::Classic,
TlsUseCase::FinancialServices => TlsMode::Hybrid,
TlsUseCase::Healthcare => TlsMode::Hybrid,
TlsUseCase::Government => TlsMode::Pq,
TlsUseCase::DatabaseConnection => TlsMode::Hybrid,
TlsUseCase::RealTimeStreaming => TlsMode::Classic,
}
}
#[must_use]
pub fn select_by_security_level(level: SecurityLevel) -> TlsMode {
match level {
SecurityLevel::Quantum => TlsMode::Pq,
SecurityLevel::Standard | SecurityLevel::High | SecurityLevel::Maximum => {
TlsMode::Hybrid
}
}
}
#[must_use]
pub fn select_pq_scheme(level: SecurityLevel) -> &'static str {
match level {
SecurityLevel::Standard => PQ_TLS_512,
SecurityLevel::High => PQ_TLS_768,
SecurityLevel::Maximum | SecurityLevel::Quantum => PQ_TLS_1024,
}
}
#[must_use]
pub fn select_pq_kex(level: SecurityLevel) -> &'static str {
match level {
SecurityLevel::Standard => "MLKEM512",
SecurityLevel::High => "MLKEM768",
SecurityLevel::Maximum | SecurityLevel::Quantum => "MLKEM1024",
}
}
#[must_use]
pub fn select_hybrid_scheme(level: SecurityLevel) -> &'static str {
match level {
SecurityLevel::Standard => HYBRID_TLS_512,
SecurityLevel::High => HYBRID_TLS_768,
SecurityLevel::Maximum | SecurityLevel::Quantum => HYBRID_TLS_1024,
}
}
#[must_use]
pub fn select_hybrid_kex(level: SecurityLevel) -> &'static str {
match level {
SecurityLevel::Standard => "X25519MLKEM512",
SecurityLevel::High => "X25519MLKEM768",
SecurityLevel::Maximum | SecurityLevel::Quantum => "X25519MLKEM1024",
}
}
#[must_use]
pub fn get_scheme_identifier(mode: TlsMode, level: SecurityLevel) -> &'static str {
match mode {
TlsMode::Classic => CLASSICAL_TLS_SCHEME,
TlsMode::Hybrid => Self::select_hybrid_scheme(level),
TlsMode::Pq => Self::select_pq_scheme(level),
}
}
#[must_use]
pub fn get_kex_algorithm(mode: TlsMode, level: SecurityLevel) -> &'static str {
match mode {
TlsMode::Classic => CLASSICAL_TLS_KEX,
TlsMode::Hybrid => Self::select_hybrid_kex(level),
TlsMode::Pq => Self::select_pq_kex(level),
}
}
#[must_use]
pub fn default_scheme() -> &'static str {
DEFAULT_TLS_SCHEME
}
#[must_use]
pub fn default_pq_scheme() -> &'static str {
DEFAULT_PQ_TLS_SCHEME
}
#[must_use]
pub fn select_balanced(security: SecurityLevel, performance: PerformancePreference) -> TlsMode {
match (security, performance) {
(SecurityLevel::Quantum, _) => TlsMode::Pq,
(SecurityLevel::Standard, PerformancePreference::Speed) => TlsMode::Hybrid,
(SecurityLevel::High, PerformancePreference::Speed) => TlsMode::Hybrid,
(SecurityLevel::Maximum, PerformancePreference::Speed) => TlsMode::Hybrid,
(_, PerformancePreference::Memory) => TlsMode::Hybrid,
(_, PerformancePreference::Balanced) => TlsMode::Hybrid,
}
}
#[must_use]
pub fn select_with_context(ctx: &TlsContext) -> TlsMode {
if ctx.constraints.requires_classic() {
return TlsMode::Classic;
}
if !ctx.pq_available {
return TlsMode::Classic;
}
let base_mode = if let Some(use_case) = ctx.use_case {
Self::recommend_mode(use_case)
} else {
Self::select_balanced(ctx.security_level, ctx.performance_preference.clone())
};
if ctx.security_level == SecurityLevel::Quantum && ctx.constraints.allows_pq() {
return TlsMode::Pq;
}
if base_mode == TlsMode::Pq && !ctx.constraints.allows_pq() {
return TlsMode::Hybrid;
}
base_mode
}
#[must_use]
pub fn create_config(ctx: &TlsContext) -> TlsConfig {
let mode = Self::select_with_context(ctx);
let mut config = TlsConfig { mode, ..Default::default() };
match ctx.performance_preference {
PerformancePreference::Speed => {
config.enable_fallback = false;
}
PerformancePreference::Memory => {
config.max_fragment_size = Some(4096);
}
PerformancePreference::Balanced => {
}
}
match ctx.security_level {
SecurityLevel::Quantum | SecurityLevel::Maximum => {
config.enable_early_data = false;
}
SecurityLevel::High | SecurityLevel::Standard => {
}
}
config
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_recommend_mode_webserver_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::recommend_mode(TlsUseCase::WebServer), TlsMode::Hybrid);
}
#[test]
fn test_recommend_mode_iot_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::recommend_mode(TlsUseCase::IoT), TlsMode::Classic);
}
#[test]
fn test_recommend_mode_government_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::recommend_mode(TlsUseCase::Government), TlsMode::Pq);
}
#[test]
fn test_select_by_security_level_quantum_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_by_security_level(SecurityLevel::Quantum), TlsMode::Pq);
}
#[test]
fn test_select_by_security_level_maximum_selects_correctly_succeeds() {
assert_eq!(
TlsPolicyEngine::select_by_security_level(SecurityLevel::Maximum),
TlsMode::Hybrid
);
}
#[test]
fn test_select_by_security_level_standard_selects_correctly_succeeds() {
assert_eq!(
TlsPolicyEngine::select_by_security_level(SecurityLevel::Standard),
TlsMode::Hybrid
);
}
#[test]
fn test_select_balanced_quantum_security_selects_correctly_succeeds() {
assert_eq!(
TlsPolicyEngine::select_balanced(SecurityLevel::Quantum, PerformancePreference::Speed),
TlsMode::Pq
);
}
#[test]
fn test_select_balanced_standard_security_selects_correctly_succeeds() {
assert_eq!(
TlsPolicyEngine::select_balanced(
SecurityLevel::Standard,
PerformancePreference::Balanced
),
TlsMode::Hybrid
);
}
#[test]
fn test_context_default_returns_expected_scheme_succeeds() {
let ctx = TlsContext::default();
assert_eq!(ctx.security_level, SecurityLevel::High);
assert_eq!(ctx.performance_preference, PerformancePreference::Balanced);
}
#[test]
fn test_constraints_requires_classic_selects_correctly_succeeds() {
let constraints = TlsConstraints::maximum_compatibility();
assert!(constraints.requires_classic());
}
#[test]
fn test_constraints_allows_pq_selects_correctly_succeeds() {
let constraints = TlsConstraints::high_security();
assert!(constraints.allows_pq());
}
#[test]
fn test_use_case_all_selects_correctly_succeeds() {
let all = TlsUseCase::all();
assert_eq!(all.len(), 10);
}
#[test]
fn test_select_pq_scheme_maximum_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_pq_scheme(SecurityLevel::Maximum), PQ_TLS_1024);
}
#[test]
fn test_select_pq_scheme_high_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_pq_scheme(SecurityLevel::High), PQ_TLS_768);
}
#[test]
fn test_select_pq_scheme_standard_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_pq_scheme(SecurityLevel::Standard), PQ_TLS_512);
}
#[test]
fn test_select_pq_kex_maximum_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_pq_kex(SecurityLevel::Maximum), "MLKEM1024");
}
#[test]
fn test_select_hybrid_scheme_maximum_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_hybrid_scheme(SecurityLevel::Maximum), HYBRID_TLS_1024);
}
#[test]
fn test_select_hybrid_scheme_high_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_hybrid_scheme(SecurityLevel::High), HYBRID_TLS_768);
}
#[test]
fn test_select_hybrid_kex_high_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_hybrid_kex(SecurityLevel::High), "X25519MLKEM768");
}
#[test]
fn test_get_scheme_identifier_classic_returns_expected_scheme_succeeds() {
assert_eq!(
TlsPolicyEngine::get_scheme_identifier(TlsMode::Classic, SecurityLevel::High),
CLASSICAL_TLS_SCHEME
);
}
#[test]
fn test_get_scheme_identifier_hybrid_returns_expected_scheme_succeeds() {
assert_eq!(
TlsPolicyEngine::get_scheme_identifier(TlsMode::Hybrid, SecurityLevel::High),
HYBRID_TLS_768
);
}
#[test]
fn test_get_scheme_identifier_pq_returns_expected_scheme_succeeds() {
assert_eq!(
TlsPolicyEngine::get_scheme_identifier(TlsMode::Pq, SecurityLevel::Maximum),
PQ_TLS_1024
);
}
#[test]
fn test_get_kex_algorithm_classic_returns_expected_scheme_succeeds() {
assert_eq!(
TlsPolicyEngine::get_kex_algorithm(TlsMode::Classic, SecurityLevel::High),
CLASSICAL_TLS_KEX
);
}
#[test]
fn test_get_kex_algorithm_pq_returns_expected_scheme_succeeds() {
assert_eq!(
TlsPolicyEngine::get_kex_algorithm(TlsMode::Pq, SecurityLevel::High),
"MLKEM768"
);
}
#[test]
fn test_default_scheme_returns_expected_scheme_succeeds() {
assert_eq!(TlsPolicyEngine::default_scheme(), DEFAULT_TLS_SCHEME);
}
#[test]
fn test_default_pq_scheme_returns_expected_scheme_succeeds() {
assert_eq!(TlsPolicyEngine::default_pq_scheme(), DEFAULT_PQ_TLS_SCHEME);
}
#[test]
fn test_constants_contain_expected_values_returns_expected_scheme_succeeds() {
assert!(DEFAULT_TLS_SCHEME.contains("hybrid"));
assert!(DEFAULT_PQ_TLS_SCHEME.contains("pq"));
assert!(CLASSICAL_TLS_SCHEME.contains("classic"));
}
#[test]
fn test_use_case_descriptions_returns_expected_scheme_is_documented() {
assert_eq!(TlsUseCase::WebServer.description(), "Web server serving public clients");
assert_eq!(
TlsUseCase::InternalService.description(),
"Internal microservice communication"
);
assert_eq!(TlsUseCase::ApiGateway.description(), "API gateway or reverse proxy");
assert_eq!(TlsUseCase::IoT.description(), "IoT or embedded devices");
assert_eq!(TlsUseCase::LegacyIntegration.description(), "Legacy system integration");
assert_eq!(TlsUseCase::FinancialServices.description(), "Financial services");
assert_eq!(TlsUseCase::Healthcare.description(), "Healthcare systems");
assert_eq!(TlsUseCase::Government.description(), "Government or high-security");
assert_eq!(TlsUseCase::DatabaseConnection.description(), "Database connections");
assert_eq!(TlsUseCase::RealTimeStreaming.description(), "Real-time streaming");
}
#[test]
fn test_recommend_mode_all_use_cases_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::recommend_mode(TlsUseCase::InternalService), TlsMode::Hybrid);
assert_eq!(TlsPolicyEngine::recommend_mode(TlsUseCase::ApiGateway), TlsMode::Hybrid);
assert_eq!(
TlsPolicyEngine::recommend_mode(TlsUseCase::LegacyIntegration),
TlsMode::Classic
);
assert_eq!(TlsPolicyEngine::recommend_mode(TlsUseCase::FinancialServices), TlsMode::Hybrid);
assert_eq!(TlsPolicyEngine::recommend_mode(TlsUseCase::Healthcare), TlsMode::Hybrid);
assert_eq!(
TlsPolicyEngine::recommend_mode(TlsUseCase::DatabaseConnection),
TlsMode::Hybrid
);
assert_eq!(
TlsPolicyEngine::recommend_mode(TlsUseCase::RealTimeStreaming),
TlsMode::Classic
);
}
#[test]
fn test_tls_context_with_security_level_selects_correctly_succeeds() {
let ctx = TlsContext::with_security_level(SecurityLevel::Maximum);
assert_eq!(ctx.security_level, SecurityLevel::Maximum);
assert!(ctx.use_case.is_none());
}
#[test]
fn test_tls_context_with_use_case_selects_correctly_succeeds() {
let ctx = TlsContext::with_use_case(TlsUseCase::WebServer);
assert_eq!(ctx.use_case, Some(TlsUseCase::WebServer));
}
#[test]
fn test_tls_context_new_full_selects_correctly_succeeds() {
let constraints = TlsConstraints::high_security();
let ctx = TlsContext::new(
SecurityLevel::Quantum,
PerformancePreference::Speed,
Some(TlsUseCase::Government),
true,
constraints,
);
assert_eq!(ctx.security_level, SecurityLevel::Quantum);
assert_eq!(ctx.performance_preference, PerformancePreference::Speed);
assert_eq!(ctx.use_case, Some(TlsUseCase::Government));
assert!(ctx.pq_available);
}
#[test]
fn test_tls_context_builder_chain_selects_correctly_succeeds() {
let ctx = TlsContext::default()
.security_level(SecurityLevel::Standard)
.performance_preference(PerformancePreference::Memory)
.use_case(TlsUseCase::IoT)
.constraints(TlsConstraints::maximum_compatibility())
.pq_available(false);
assert_eq!(ctx.security_level, SecurityLevel::Standard);
assert_eq!(ctx.performance_preference, PerformancePreference::Memory);
assert_eq!(ctx.use_case, Some(TlsUseCase::IoT));
assert!(!ctx.pq_available);
}
#[test]
fn test_constraints_default_allows_pq_selects_correctly_succeeds() {
let c = TlsConstraints::default();
assert!(!c.requires_classic());
assert!(c.allows_pq());
}
#[test]
fn test_constraints_latency_requires_classic_selects_correctly_succeeds() {
let c = TlsConstraints {
max_handshake_latency_ms: Some(10), client_supports_pq: None,
require_compatibility: false,
max_client_hello_size: None,
};
assert!(c.requires_classic());
}
#[test]
fn test_constraints_large_latency_does_not_require_classic_selects_correctly_succeeds() {
let c = TlsConstraints {
max_handshake_latency_ms: Some(100), client_supports_pq: None,
require_compatibility: false,
max_client_hello_size: None,
};
assert!(!c.requires_classic());
}
#[test]
fn test_constraints_small_client_hello_requires_classic_selects_correctly_succeeds() {
let c = TlsConstraints {
max_handshake_latency_ms: None,
client_supports_pq: None,
require_compatibility: false,
max_client_hello_size: Some(512), };
assert!(c.requires_classic());
}
#[test]
fn test_constraints_large_client_hello_does_not_require_classic_selects_correctly_succeeds() {
let c = TlsConstraints {
max_handshake_latency_ms: None,
client_supports_pq: None,
require_compatibility: false,
max_client_hello_size: Some(2000), };
assert!(!c.requires_classic());
}
#[test]
fn test_constraints_compatibility_blocks_pq_selects_correctly_succeeds() {
let c = TlsConstraints {
max_handshake_latency_ms: None,
client_supports_pq: Some(true),
require_compatibility: true,
max_client_hello_size: None,
};
assert!(!c.allows_pq());
assert!(c.requires_classic());
}
#[test]
fn test_constraints_no_pq_support_blocks_pq_selects_correctly_succeeds() {
let c = TlsConstraints {
max_handshake_latency_ms: None,
client_supports_pq: Some(false),
require_compatibility: false,
max_client_hello_size: None,
};
assert!(!c.allows_pq());
assert!(c.requires_classic());
}
#[test]
fn test_select_with_context_constraints_force_classic_selects_correctly_succeeds() {
let ctx = TlsContext::default().constraints(TlsConstraints::maximum_compatibility());
assert_eq!(TlsPolicyEngine::select_with_context(&ctx), TlsMode::Classic);
}
#[test]
fn test_select_with_context_pq_unavailable_selects_correctly_succeeds() {
let ctx = TlsContext::default().pq_available(false);
assert_eq!(TlsPolicyEngine::select_with_context(&ctx), TlsMode::Classic);
}
#[test]
fn test_select_with_context_use_case_selects_correctly_succeeds() {
let ctx = TlsContext::default().use_case(TlsUseCase::Government).pq_available(true);
assert_eq!(TlsPolicyEngine::select_with_context(&ctx), TlsMode::Pq);
}
#[test]
fn test_select_with_context_quantum_security_selects_correctly_succeeds() {
let ctx = TlsContext::default().security_level(SecurityLevel::Quantum).pq_available(true);
assert_eq!(TlsPolicyEngine::select_with_context(&ctx), TlsMode::Pq);
}
#[test]
fn test_select_with_context_no_use_case_balanced_selects_correctly_succeeds() {
let ctx = TlsContext::default().pq_available(true);
assert_eq!(TlsPolicyEngine::select_with_context(&ctx), TlsMode::Hybrid);
}
#[test]
fn test_select_balanced_all_combos_selects_correctly_succeeds() {
assert_eq!(
TlsPolicyEngine::select_balanced(SecurityLevel::Standard, PerformancePreference::Speed),
TlsMode::Hybrid
);
assert_eq!(
TlsPolicyEngine::select_balanced(SecurityLevel::High, PerformancePreference::Speed),
TlsMode::Hybrid
);
assert_eq!(
TlsPolicyEngine::select_balanced(SecurityLevel::Maximum, PerformancePreference::Speed),
TlsMode::Hybrid
);
assert_eq!(
TlsPolicyEngine::select_balanced(
SecurityLevel::Standard,
PerformancePreference::Memory
),
TlsMode::Hybrid
);
assert_eq!(
TlsPolicyEngine::select_balanced(SecurityLevel::Maximum, PerformancePreference::Memory),
TlsMode::Hybrid
);
assert_eq!(
TlsPolicyEngine::select_balanced(
SecurityLevel::Standard,
PerformancePreference::Balanced
),
TlsMode::Hybrid
);
assert_eq!(
TlsPolicyEngine::select_balanced(
SecurityLevel::Maximum,
PerformancePreference::Balanced
),
TlsMode::Hybrid
);
}
#[test]
fn test_create_config_speed_preference_selects_correctly_succeeds() {
let ctx = TlsContext::default()
.performance_preference(PerformancePreference::Speed)
.pq_available(true);
let config = TlsPolicyEngine::create_config(&ctx);
assert!(!config.enable_fallback);
}
#[test]
fn test_create_config_memory_preference_selects_correctly_succeeds() {
let ctx = TlsContext::default()
.performance_preference(PerformancePreference::Memory)
.pq_available(true);
let config = TlsPolicyEngine::create_config(&ctx);
assert_eq!(config.max_fragment_size, Some(4096));
}
#[test]
fn test_create_config_maximum_security_selects_correctly_succeeds() {
let ctx = TlsContext::default().security_level(SecurityLevel::Maximum).pq_available(true);
let config = TlsPolicyEngine::create_config(&ctx);
assert!(!config.enable_early_data);
}
#[test]
fn test_create_config_high_security_selects_correctly_succeeds() {
let ctx = TlsContext::default().security_level(SecurityLevel::High).pq_available(true);
let _config = TlsPolicyEngine::create_config(&ctx);
}
#[test]
fn test_create_config_standard_security_selects_correctly_succeeds() {
let ctx = TlsContext::default().security_level(SecurityLevel::Standard).pq_available(true);
let _config = TlsPolicyEngine::create_config(&ctx);
}
#[test]
fn test_select_pq_scheme_quantum_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_pq_scheme(SecurityLevel::Quantum), PQ_TLS_1024);
}
#[test]
fn test_select_pq_kex_standard_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_pq_kex(SecurityLevel::Standard), "MLKEM512");
}
#[test]
fn test_select_pq_kex_high_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_pq_kex(SecurityLevel::High), "MLKEM768");
}
#[test]
fn test_select_pq_kex_quantum_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_pq_kex(SecurityLevel::Quantum), "MLKEM1024");
}
#[test]
fn test_select_hybrid_scheme_standard_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_hybrid_scheme(SecurityLevel::Standard), HYBRID_TLS_512);
}
#[test]
fn test_select_hybrid_scheme_quantum_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_hybrid_scheme(SecurityLevel::Quantum), HYBRID_TLS_1024);
}
#[test]
fn test_select_hybrid_kex_standard_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_hybrid_kex(SecurityLevel::Standard), "X25519MLKEM512");
}
#[test]
fn test_select_hybrid_kex_maximum_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_hybrid_kex(SecurityLevel::Maximum), "X25519MLKEM1024");
}
#[test]
fn test_select_hybrid_kex_quantum_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_hybrid_kex(SecurityLevel::Quantum), "X25519MLKEM1024");
}
#[test]
fn test_get_kex_algorithm_hybrid_returns_expected_scheme_succeeds() {
assert_eq!(
TlsPolicyEngine::get_kex_algorithm(TlsMode::Hybrid, SecurityLevel::High),
"X25519MLKEM768"
);
}
#[test]
fn test_select_by_security_level_high_selects_correctly_succeeds() {
assert_eq!(TlsPolicyEngine::select_by_security_level(SecurityLevel::High), TlsMode::Hybrid);
}
}