codive-tunnel 0.1.0

Shared types and cryptography for secure tunneling
Documentation
# Codive Tunnel - Secure Tunneling Protocol Library

A Rust library providing end-to-end encrypted tunneling protocol types, cryptographic primitives, and wire format encoding for secure Codive communication.

## Overview

This crate is the shared foundation for the Codive tunneling system:

- **codive-relay** uses it for protocol parsing and message routing
- **codive-cli** uses it for encryption/decryption and tunnel client logic

## Features

### Cryptography
- **XChaCha20-Poly1305**: AEAD encryption with 256-bit keys
- **Random Nonces**: 24-byte nonces generated per message (no reuse risk)
- **Secure Key Handling**: `Zeroize` trait implementation for memory safety
- **URL-Safe Key Encoding**: Base64url encoding for key sharing via URL fragments

### Protocol
- **Control Messages**: Hello, Welcome, Ping, Pong, Close, Error
- **Data Messages**: HttpRequest, HttpResponse, HttpResponseChunk, RequestError
- **Wire Format**: Efficient binary encoding with message type headers
- **Routing Headers**: Request ID routing for encrypted responses

## Usage

Add to your `Cargo.toml`:
```toml
[dependencies]
codive-tunnel = { path = "../codive-tunnel" }
```

### Key Generation and Encryption

```rust
use codive_tunnel::{TunnelKey, TunnelCrypto};

// Generate a new encryption key
let key = TunnelKey::generate();

// Share via URL fragment (never sent to server)
let url = format!("https://tunnel.example.com#E2EKey={}", key.to_base64());

// Create crypto instance
let crypto = TunnelCrypto::new(&key);

// Encrypt data
let plaintext = b"Hello, World!";
let ciphertext = crypto.encrypt(plaintext)?;

// Decrypt data
let decrypted = crypto.decrypt(&ciphertext)?;
assert_eq!(plaintext.as_slice(), decrypted.as_slice());
```

### Protocol Messages

```rust
use codive_tunnel::{ControlMessage, DataMessage, WireMessage, PROTOCOL_VERSION};

// Create a Hello message
let hello = ControlMessage::Hello {
    version: PROTOCOL_VERSION,
    requested_id: Some("my-tunnel".to_string()),
    auth_token: Some("secret".to_string()),
};

// Encode for transmission
let encoded = WireMessage::encode_control(&hello)?;

// Decode received message
let decoded = WireMessage::decode_control(&encoded)?;
```

### HTTP Request/Response

```rust
use codive_tunnel::DataMessage;
use std::collections::HashMap;

// Create an HTTP request
let request = DataMessage::HttpRequest {
    request_id: "req-123".to_string(),
    method: "GET".to_string(),
    path: "/api/status".to_string(),
    headers: HashMap::new(),
    body: None,
};

// Serialize to JSON
let json = serde_json::to_vec(&request)?;

// Create a response
let response = DataMessage::HttpResponse {
    request_id: "req-123".to_string(),
    status: 200,
    headers: [("Content-Type".to_string(), "application/json".to_string())]
        .into_iter().collect(),
    body: Some(base64::encode(b"{\"status\":\"ok\"}")),
    streaming: false,
};
```

### Wire Message Format

```rust
use codive_tunnel::{WireMessage, message_type};

// Encode encrypted data with routing header
let wire_msg = WireMessage::encode_encrypted_with_routing(
    message_type::ENCRYPTED_RESPONSE,
    "request-id-123",
    encrypted_payload,
);

// Decode with routing header
let (msg_type, request_id, payload) =
    WireMessage::decode_encrypted_with_routing(&wire_msg)?;
```

## API Reference

### Types

| Type | Description |
|------|-------------|
| `TunnelKey` | 256-bit encryption key with Zeroize |
| `TunnelCrypto` | XChaCha20-Poly1305 encrypt/decrypt |
| `ControlMessage` | Protocol control messages (Hello, Welcome, etc.) |
| `DataMessage` | Data messages (HttpRequest, HttpResponse, etc.) |
| `WireMessage` | Binary wire format encoding/decoding |

### Control Messages

| Message | Direction | Purpose |
|---------|-----------|---------|
| `Hello` | Agent → Relay | Initial handshake with auth |
| `Welcome` | Relay → Agent | Tunnel ID and URL assignment |
| `Ping` | Both | Keep-alive request |
| `Pong` | Both | Keep-alive response |
| `Close` | Both | Graceful disconnect |
| `Error` | Relay → Agent | Error notification |
| `ClientConnected` | Relay → Agent | Client connected to tunnel |
| `ClientDisconnected` | Relay → Agent | Client disconnected |

### Data Messages

| Message | Direction | Purpose |
|---------|-----------|---------|
| `HttpRequest` | Relay → Agent | Incoming HTTP request |
| `HttpResponse` | Agent → Relay | HTTP response |
| `HttpResponseChunk` | Agent → Relay | Streaming response chunk |
| `RequestError` | Agent → Relay | Request processing error |

### Message Type Constants

```rust
pub mod message_type {
    pub const CONTROL: u8 = 0x00;
    pub const ENCRYPTED_REQUEST: u8 = 0x01;
    pub const ENCRYPTED_RESPONSE: u8 = 0x02;
    pub const ENCRYPTED_CHUNK: u8 = 0x03;
}
```

## Wire Protocol

### Binary Format

```
Control Messages:
┌─────────┬─────────────────────┐
│ 0x00    │ JSON payload        │
└─────────┴─────────────────────┘

Encrypted Messages:
┌─────────┬─────────────────────┐
│ type    │ encrypted payload   │
└─────────┴─────────────────────┘

Encrypted with Routing Header:
┌─────────┬─────────┬───────────────┬─────────────────────┐
│ type    │ id_len  │ request_id    │ encrypted payload   │
└─────────┴─────────┴───────────────┴─────────────────────┘
```

### Encryption Format

```
Ciphertext:
┌─────────────────────┬─────────────────────┬─────────────────────┐
│ nonce (24 bytes)    │ ciphertext          │ auth tag (16 bytes) │
└─────────────────────┴─────────────────────┴─────────────────────┘
```

## Security Considerations

### Key Exchange
- Keys are shared via URL fragment (`#E2EKey=...`)
- Fragments are never sent to the server in HTTP requests
- Keys should be rotated periodically for long-lived tunnels

### Memory Safety
- `TunnelKey` implements `Zeroize` and `ZeroizeOnDrop`
- Key material is cleared from memory when dropped
- No key logging in debug output (`Debug` shows `[REDACTED]`)

### Nonce Safety
- 24-byte random nonces (XChaCha20)
- Extremely low collision probability (2^-96)
- No nonce counter needed

## Testing

```bash
# Run all tests
cargo test -p codive-tunnel

# Run with output
cargo test -p codive-tunnel -- --nocapture

# Run specific test
cargo test -p codive-tunnel test_encrypt_decrypt
```

Test coverage: **62 tests**
- Crypto tests: Key generation, encryption, decryption, tampering detection
- Protocol tests: Message serialization, wire encoding
- Integration tests: Full E2E flows, streaming, error handling

## Dependencies

- `chacha20poly1305` - AEAD encryption
- `zeroize` - Secure memory clearing
- `rand` - Cryptographic RNG
- `base64` - URL-safe encoding
- `serde` / `serde_json` - Serialization

## Contributing

See the [codive-relay README](../codive-relay/README.md) for contribution guidelines.

### Adding New Message Types

1. Add variant to `ControlMessage` or `DataMessage` in `protocol.rs`
2. Update `serde` attributes if needed
3. Add tests for serialization roundtrip
4. Update wire format handling if binary encoding changes

## License

MIT License - see LICENSE file for details.