382 lines
11 KiB
Markdown
382 lines
11 KiB
Markdown
# 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<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
|
|
```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<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
|
|
```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<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
|
|
```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<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
|
|
```rust
|
|
#[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
|
|
```rust
|
|
#[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
|
|
```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 |