# WSS (WebSocket Secure) Implementation Plan ## Overview This document outlines the complete implementation plan for adding WSS support to both the server and client_ws components, with optional configuration and comprehensive examples. ## Current State Analysis ### Server (src/server) - ✅ Basic TLS infrastructure with `rustls` and `rustls-pemfile` - ✅ Certificate loading functionality (`load_rustls_config`) - ✅ Optional TLS configuration in `ServerConfig` - ✅ Existing cert.pem and key.pem files for testing - ⚠️ TLS configuration could be enhanced with better error handling - ⚠️ Missing WSS-specific examples and tests ### Client (src/client_ws) - ✅ Basic TLS support with `native-tls` and `tokio-native-tls` - ✅ Cross-platform WebSocket support (native + WASM) - ⚠️ TLS connector accepts invalid certificates (development mode) - ⚠️ No automatic WSS URL detection - ⚠️ Missing WSS-specific configuration options ## Implementation Phases ### Phase 1: Server WSS Enhancement ✅ READY TO IMPLEMENT #### 1.1 Enhanced ServerConfig ```rust #[derive(Clone)] pub struct ServerConfig { pub circle_name: String, pub circle_public_key: String, pub host: String, pub port: u16, pub redis_url: String, pub enable_auth: bool, // Enhanced TLS Configuration pub enable_tls: bool, // Explicit TLS enable flag pub cert_path: Option, // Path to certificate file pub key_path: Option, // Path to private key file pub tls_port: Option, // Optional separate TLS port pub tls_accept_invalid_certs: bool, // For development } ``` #### 1.2 Improved TLS Loading - Better error messages for certificate loading failures - Validation of certificate and key file existence - Support for different certificate formats - Logging of TLS configuration status #### 1.3 Enhanced spawn_circle_server - Clear logging of HTTP vs HTTPS mode - Better error handling for TLS configuration - Support for running both HTTP and HTTPS simultaneously (if needed) ### Phase 2: Client WSS Enhancement #### 2.1 WSS URL Detection ```rust impl CircleWsClient { fn is_wss_url(&self) -> bool { self.ws_url.starts_with("wss://") } fn requires_tls(&self) -> bool { self.is_wss_url() } } ``` #### 2.2 Enhanced TLS Configuration ```rust pub struct TlsConfig { pub accept_invalid_certs: bool, pub accept_invalid_hostnames: bool, pub ca_cert_path: Option, pub client_cert_path: Option, pub client_key_path: Option, } impl CircleWsClientBuilder { pub fn with_tls_config(mut self, tls_config: TlsConfig) -> Self { self.tls_config = Some(tls_config); self } } ``` #### 2.3 Cross-Platform WSS Support - Native: Enhanced `tokio-tungstenite` with `rustls` support - WASM: Ensure `gloo-net` handles WSS URLs correctly - Consistent error handling across platforms ### Phase 3: Examples and Testing #### 3.1 Basic WSS Example ```rust // examples/wss_basic_example.rs // Demonstrates basic WSS connection without authentication ``` #### 3.2 WSS + Authentication Example ```rust // examples/wss_auth_example.rs // Demonstrates WSS connection with secp256k1 authentication ``` #### 3.3 End-to-End Secure Example ```rust // examples/wss_end_to_end_example.rs // Complete server + client WSS with authentication ``` #### 3.4 Certificate Generation Helper ```rust // examples/wss_cert_generation.rs // Helper to generate self-signed certificates for development ``` ### Phase 4: Documentation and Integration #### 4.1 Update README files - Server WSS configuration guide - Client WSS usage examples - Certificate management instructions #### 4.2 Integration Tests - WSS connection establishment - WSS + authentication flow - Certificate validation scenarios ## Technical Implementation Details ### Server Enhancements #### Enhanced Certificate Loading ```rust fn load_rustls_config( cert_path: &str, key_path: &str, ) -> Result { // Validate file existence if !std::path::Path::new(cert_path).exists() { return Err(TlsConfigError::CertificateNotFound(cert_path.to_string())); } if !std::path::Path::new(key_path).exists() { return Err(TlsConfigError::PrivateKeyNotFound(key_path.to_string())); } // Enhanced error handling for certificate loading // Support for different key formats (PKCS8, RSA, etc.) // Validation of certificate chain } ``` #### TLS Error Types ```rust #[derive(Error, Debug)] pub enum TlsConfigError { #[error("Certificate file not found: {0}")] CertificateNotFound(String), #[error("Private key file not found: {0}")] PrivateKeyNotFound(String), #[error("Invalid certificate format: {0}")] InvalidCertificate(String), #[error("Invalid private key format: {0}")] InvalidPrivateKey(String), #[error("TLS configuration error: {0}")] ConfigurationError(String), } ``` ### Client Enhancements #### WSS Connection Logic ```rust impl CircleWsClient { async fn create_tls_connector(&self) -> Result { let mut builder = TlsConnector::builder(); if let Some(tls_config) = &self.tls_config { builder.danger_accept_invalid_certs(tls_config.accept_invalid_certs); builder.danger_accept_invalid_hostnames(tls_config.accept_invalid_hostnames); // Load custom CA certificates if provided if let Some(ca_cert_path) = &tls_config.ca_cert_path { // Load and add CA certificate } } builder.build().map_err(|e| { CircleWsClientError::ConnectionError(format!("TLS configuration failed: {}", e)) }) } } ``` ### Example Structure #### Basic WSS Example ```rust #[tokio::main] async fn main() -> Result<(), Box> { // Start WSS server let config = ServerConfig { enable_tls: true, cert_path: Some("cert.pem".to_string()), key_path: Some("key.pem".to_string()), port: 8443, // ... other config }; let (server_task, _handle) = spawn_circle_server(config)?; // Connect WSS client let mut client = CircleWsClientBuilder::new("wss://localhost:8443/ws".to_string()) .with_tls_config(TlsConfig { accept_invalid_certs: true, // For development ..Default::default() }) .build(); client.connect().await?; // Test basic functionality let result = client.play("print('Hello WSS!')".to_string()).await?; println!("Result: {}", result.output); client.disconnect().await; Ok(()) } ``` #### WSS + Authentication Example ```rust #[tokio::main] async fn main() -> Result<(), Box> { // Start authenticated WSS server let config = ServerConfig { enable_tls: true, enable_auth: true, cert_path: Some("cert.pem".to_string()), key_path: Some("key.pem".to_string()), port: 8443, // ... other config }; // Connect authenticated WSS client let private_key = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"; let mut client = CircleWsClientBuilder::new("wss://localhost:8443/ws".to_string()) .with_keypair(private_key.to_string()) .with_tls_config(TlsConfig { accept_invalid_certs: true, ..Default::default() }) .build(); client.connect().await?; // Authenticate over secure connection match client.authenticate().await? { true => println!("Authenticated successfully over WSS"), false => println!("Authentication failed"), } // Test authenticated request over secure connection let result = client.play("print('Authenticated WSS request!')".to_string()).await?; println!("Secure result: {}", result.output); client.disconnect().await; Ok(()) } ``` ## Testing Strategy ### Unit Tests - TLS configuration validation - Certificate loading error handling - WSS URL detection - TLS connector creation ### Integration Tests - WSS server startup with valid certificates - WSS client connection establishment - WSS + authentication flow - Error scenarios (invalid certificates, connection failures) ### End-to-End Tests - Complete WSS server + client communication - Authentication over WSS - Multiple concurrent WSS connections - Certificate validation scenarios ## Security Considerations ### Development vs Production - **Development**: Accept self-signed certificates, invalid hostnames - **Production**: Strict certificate validation, proper CA chains ### Certificate Management - Clear documentation for certificate generation - Support for Let's Encrypt certificates - Certificate rotation considerations ### TLS Configuration - Modern TLS versions (1.2+) - Secure cipher suites - HSTS headers for web clients ## File Changes Required ### New Files - `examples/wss_basic_example.rs` - `examples/wss_auth_example.rs` - `examples/wss_end_to_end_example.rs` - `examples/wss_cert_generation.rs` - `src/server/src/tls_config.rs` (optional) - `src/client_ws/src/tls_config.rs` (optional) ### Modified Files - `src/server/src/lib.rs` - Enhanced TLS support - `src/server/cmd/main.rs` - TLS CLI options - `src/client_ws/src/lib.rs` - WSS support - `src/client_ws/Cargo.toml` - Additional TLS dependencies - `src/server/Cargo.toml` - Enhanced TLS dependencies - `src/server/README.md` - WSS documentation - `src/client_ws/README.md` - WSS usage guide ## Dependencies ### Server Additional Dependencies ```toml # Enhanced TLS support rustls-webpki = "0.103" rustls-native-certs = "0.7" ``` ### Client Additional Dependencies ```toml # Enhanced TLS support for native rustls = { version = "0.23", optional = true } tokio-rustls = { version = "0.26", optional = true } rustls-native-certs = { version = "0.7", optional = true } [features] default = ["crypto"] crypto = ["secp256k1", "sha3"] rustls-tls = ["rustls", "tokio-rustls", "rustls-native-certs"] ``` ## Implementation Order 1. **Phase 1a**: Enhance server TLS configuration and error handling 2. **Phase 1b**: Create basic WSS server example and test 3. **Phase 1c**: Validate server WSS functionality with manual testing 4. **Phase 2a**: Enhance client WSS support 5. **Phase 2b**: Create client WSS examples 6. **Phase 2c**: Test client WSS connectivity 7. **Phase 3**: Create end-to-end WSS examples 8. **Phase 4**: Integration tests and documentation ## Success Criteria - ✅ Server can start with WSS enabled using existing certificates - ✅ Client can connect to WSS server with proper TLS validation - ✅ Authentication works over WSS connections - ✅ Examples demonstrate all WSS functionality - ✅ Tests validate WSS behavior - ✅ Documentation explains WSS configuration - ✅ Cross-platform compatibility (native + WASM) ## Next Steps 1. Switch to Code mode for implementation 2. Start with Phase 1a: Server TLS enhancements 3. Create and test basic WSS server example 4. Validate functionality before proceeding to client