circles/docs/aidocs/WSS_IMPLEMENTATION_PLAN.md
2025-07-08 22:49:47 +02:00

11 KiB

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

#[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<String>,  // Path to certificate file
    pub key_path: Option<String>,   // Path to private key file
    pub tls_port: Option<u16>,      // 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

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

pub struct TlsConfig {
    pub accept_invalid_certs: bool,
    pub accept_invalid_hostnames: bool,
    pub ca_cert_path: Option<String>,
    pub client_cert_path: Option<String>,
    pub client_key_path: Option<String>,
}

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

// examples/wss_basic_example.rs
// Demonstrates basic WSS connection without authentication

3.2 WSS + Authentication Example

// examples/wss_auth_example.rs
// Demonstrates WSS connection with secp256k1 authentication

3.3 End-to-End Secure Example

// examples/wss_end_to_end_example.rs
// Complete server + client WSS with authentication

3.4 Certificate Generation Helper

// 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

fn load_rustls_config(
    cert_path: &str,
    key_path: &str,
) -> Result<RustlsServerConfig, TlsConfigError> {
    // 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

#[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

impl CircleWsClient {
    async fn create_tls_connector(&self) -> Result<TlsConnector, CircleWsClientError> {
        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

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 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

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 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

# Enhanced TLS support
rustls-webpki = "0.103"
rustls-native-certs = "0.7"

Client Additional Dependencies

# 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