TLS Configuration
Extensions that make outbound HTTPS connections (e.g., fetching remote data, calling REST APIs) need a way to inject TLS configuration — client certificates for mTLS, custom CA bundles, or restricted cipher suites.
The tls module
provides the [TlsConfigProvider] trait so that extensions can supply their TLS
setup through a uniform interface, regardless of which TLS library they use
(rustls, native-tls, etc.).
Design
The trait is type-erased via Arc<dyn Any + Send + Sync> so that quack-rs
does not depend on any specific TLS library. The implementing extension downcasts
the returned Arc to its concrete config type.
Implementing a TLS Provider
#![allow(unused)] fn main() { use quack_rs::tls::{TlsConfigProvider, TlsVersion}; use quack_rs::error::ExtensionError; use std::any::Any; use std::sync::Arc; struct MyTlsProvider { // In practice: Arc<rustls::ClientConfig> config: Arc<String>, mtls_enabled: bool, } impl TlsConfigProvider for MyTlsProvider { fn client_config(&self) -> Result<Arc<dyn Any + Send + Sync>, ExtensionError> { Ok(self.config.clone()) } fn provider_name(&self) -> &str { "my-extension-tls" } fn config_type_name(&self) -> &str { "rustls::ClientConfig" } fn min_tls_version(&self) -> TlsVersion { TlsVersion::Tls12 // Minimum recommended } fn supports_mtls(&self) -> bool { self.mtls_enabled } fn accepts_invalid_certs(&self) -> bool { false // MUST default to false } } }
Security Requirements
Implementations must:
- Return
falsefromaccepts_invalid_certs()unless explicitly configured otherwise by the user. Certificate validation bypass (CWE-295) should never be the default. - Return
TlsVersion::Tls12or higher frommin_tls_version(). TLS 1.0 and 1.1 are deprecated per RFC 8996. - Emit an
ExtensionWarningviaWarningCollectorwhen certificate validation is disabled or when using a TLS version below 1.2.
Auditing a Provider
The audit_tls_provider() function checks common misconfigurations:
#![allow(unused)] fn main() { use quack_rs::tls::audit_tls_provider; use quack_rs::warning::WarningCollector; // let warnings = audit_tls_provider(&my_provider); // let collector = WarningCollector::new(); // for w in warnings { // collector.emit(w); // } }
It detects:
- Certificate verification bypass (CWE-295) — emits
TLS_NO_VERIFYwarning - Deprecated TLS versions (CWE-327) — emits
TLS_DEPRECATED_VERSIONwarning
Downcasting Safely
Never use .unwrap() or .expect() when downcasting in FFI callback contexts
(see Pitfall L3). Always handle the None case gracefully:
#![allow(unused)] fn main() { use std::any::Any; use std::sync::Arc; use quack_rs::error::ExtensionError; fn use_config(config: Arc<dyn Any + Send + Sync>) -> Result<(), ExtensionError> { // let rustls_config = config.downcast_ref::<rustls::ClientConfig>() // .ok_or(ExtensionError::new("expected rustls::ClientConfig"))?; Ok(()) } }