Skip to main content

vcl_protocol/
connection.rs

1use crate::packet::VCLPacket;
2use crate::crypto::{KeyPair, encrypt_payload, decrypt_payload};
3use crate::handshake::{HandshakeMessage, create_client_hello, process_client_hello, process_server_hello};
4use ed25519_dalek::SigningKey;
5use x25519_dalek::EphemeralSecret;
6use rand::rngs::OsRng;
7use tokio::net::UdpSocket;
8use std::net::SocketAddr;
9use std::collections::HashSet;
10use std::time::{Duration, Instant};
11
12pub struct VCLConnection {
13    socket: UdpSocket,
14    keypair: KeyPair,
15    sequence: u64,
16    last_hash: Vec<u8>,
17    peer_addr: Option<SocketAddr>,
18    peer_public_key: Option<Vec<u8>>,
19    shared_secret: Option<[u8; 32]>,
20    is_server: bool,
21    last_sequence: u64,
22    seen_nonces: HashSet<[u8; 24]>,
23    closed: bool,
24    last_activity: Instant,
25    timeout_secs: u64,
26}
27
28impl VCLConnection {
29    pub async fn bind(addr: &str) -> Result<Self, String> {
30        let socket = UdpSocket::bind(addr).await.map_err(|e| e.to_string())?;
31        Ok(VCLConnection {
32            socket,
33            keypair: KeyPair::generate(),
34            sequence: 0,
35            last_hash: vec![0; 32],
36            peer_addr: None,
37            peer_public_key: None,
38            shared_secret: None,
39            is_server: false,
40            last_sequence: 0,
41            seen_nonces: HashSet::new(),
42            closed: false,
43            last_activity: Instant::now(),
44            timeout_secs: 60,
45        })
46    }
47
48    pub fn set_timeout(&mut self, secs: u64) {
49        self.timeout_secs = secs;
50    }
51
52    pub fn get_timeout(&self) -> u64 {
53        self.timeout_secs
54    }
55
56    pub fn last_activity(&self) -> Instant {
57        self.last_activity
58    }
59
60    pub fn set_shared_key(&mut self, private_key: &[u8]) {
61        let key_bytes: &[u8; 32] = private_key.try_into().unwrap();
62        let signing_key = SigningKey::from_bytes(key_bytes);
63        let verifying_key = signing_key.verifying_key();
64        
65        self.keypair.private_key = private_key.to_vec();
66        self.keypair.public_key = verifying_key.to_bytes().to_vec();
67    }
68
69    pub async fn connect(&mut self, addr: &str) -> Result<(), String> {
70        let parsed: SocketAddr = addr.parse().map_err(|e: std::net::AddrParseError| e.to_string())?;
71        self.peer_addr = Some(parsed);
72        
73        let (hello_msg, ephemeral) = create_client_hello();
74        
75        let hello_bytes = bincode::serialize(&hello_msg).map_err(|e| e.to_string())?;
76        self.socket.send_to(&hello_bytes, parsed).await.map_err(|e| e.to_string())?;
77        
78        let mut buf = vec![0u8; 65535];
79        let (len, _) = self.socket.recv_from(&mut buf).await.map_err(|e| e.to_string())?;
80        let server_hello: HandshakeMessage = bincode::deserialize(&buf[..len]).map_err(|e| e.to_string())?;
81        
82        if let HandshakeMessage::ServerHello { public_key } = server_hello {
83            let shared = process_server_hello(ephemeral, public_key);
84            if let Some(secret) = shared {
85                self.shared_secret = Some(secret);
86            } else {
87                return Err("Handshake failed".to_string());
88            }
89        } else {
90            return Err("Expected ServerHello".to_string());
91        }
92        
93        self.last_activity = Instant::now();
94        Ok(())
95    }
96
97    pub async fn accept_handshake(&mut self) -> Result<(), String> {
98        let ephemeral = EphemeralSecret::random_from_rng(OsRng);
99        
100        let mut buf = vec![0u8; 65535];
101        let (len, addr) = self.socket.recv_from(&mut buf).await.map_err(|e| e.to_string())?;
102        self.peer_addr = Some(addr);
103        
104        let client_hello: HandshakeMessage = bincode::deserialize(&buf[..len]).map_err(|e| e.to_string())?;
105        
106        if let HandshakeMessage::ClientHello { public_key } = client_hello {
107            let (server_hello, shared) = process_client_hello(ephemeral, public_key);
108            
109            let hello_bytes = bincode::serialize(&server_hello).map_err(|e| e.to_string())?;
110            self.socket.send_to(&hello_bytes, addr).await.map_err(|e| e.to_string())?;
111            
112            if let Some(secret) = shared {
113                self.shared_secret = Some(secret);
114                self.is_server = true;
115            } else {
116                return Err("Handshake failed".to_string());
117            }
118        } else {
119            return Err("Expected ClientHello".to_string());
120        }
121        
122        self.last_activity = Instant::now();
123        Ok(())
124    }
125
126    pub async fn send(&mut self, data: &[u8]) -> Result<(), String> {
127        if self.closed {
128            return Err("Connection closed".to_string());
129        }
130        
131        self.check_timeout()?;
132        
133        let key = self.shared_secret.ok_or("No shared secret")?;
134        let (encrypted_payload, nonce) = encrypt_payload(data, &key);
135        
136        let mut packet = VCLPacket::new(self.sequence, self.last_hash.clone(), encrypted_payload, nonce);
137        packet.sign(&self.keypair.private_key);
138        
139        let serialized = packet.serialize();
140        let addr = self.peer_addr.ok_or("No peer address")?;
141        self.socket.send_to(&serialized, addr).await.map_err(|e| e.to_string())?;
142        
143        self.last_hash = packet.compute_hash();
144        self.sequence += 1;
145        self.last_activity = Instant::now();
146        Ok(())
147    }
148
149    pub async fn recv(&mut self) -> Result<VCLPacket, String> {
150        if self.closed {
151            return Err("Connection closed".to_string());
152        }
153        
154        self.check_timeout()?;
155        
156        let mut buf = vec![0u8; 65535];
157        let (len, addr) = self.socket.recv_from(&mut buf).await.map_err(|e| e.to_string())?;
158        if self.peer_addr.is_none() {
159            self.peer_addr = Some(addr);
160        }
161        
162        let packet = VCLPacket::deserialize(&buf[..len])?;
163        
164        if self.last_sequence > 0 && packet.sequence <= self.last_sequence {
165            return Err("Replay detected: old sequence number".to_string());
166        }
167        
168        if self.seen_nonces.contains(&packet.nonce) {
169            return Err("Replay detected: duplicate nonce".to_string());
170        }
171        self.seen_nonces.insert(packet.nonce);
172        
173        if self.seen_nonces.len() > 1000 {
174            self.seen_nonces.clear();
175        }
176        
177        if !packet.validate_chain(&self.last_hash) {
178            return Err("Chain validation failed".to_string());
179        }
180        
181        let verify_key = self.peer_public_key.as_ref().unwrap_or(&self.keypair.public_key);
182        if !packet.verify(verify_key) {
183            return Err("Signature validation failed".to_string());
184        }
185        
186        self.last_hash = packet.compute_hash();
187        self.last_sequence = packet.sequence;
188        self.last_activity = Instant::now();
189        
190        let key = self.shared_secret.ok_or("No shared secret")?;
191        let decrypted = decrypt_payload(&packet.payload, &key, &packet.nonce)?;
192        
193        Ok(VCLPacket {
194            version: packet.version,
195            sequence: packet.sequence,
196            prev_hash: packet.prev_hash,
197            nonce: packet.nonce,
198            payload: decrypted,
199            signature: packet.signature,
200        })
201    }
202
203    fn check_timeout(&self) -> Result<(), String> {
204        let elapsed = self.last_activity.elapsed();
205        if elapsed.as_secs() > self.timeout_secs {
206            return Err("Connection timeout: no activity for too long".to_string());
207        }
208        Ok(())
209    }
210
211    pub fn close(&mut self) -> Result<(), String> {
212        if self.closed {
213            return Err("Connection already closed".to_string());
214        }
215        
216        self.closed = true;
217        self.sequence = 0;
218        self.last_hash = vec![0; 32];
219        self.last_sequence = 0;
220        self.seen_nonces.clear();
221        self.shared_secret = None;
222        
223        Ok(())
224    }
225
226    pub fn is_closed(&self) -> bool {
227        self.closed
228    }
229
230    pub fn get_public_key(&self) -> Vec<u8> {
231        self.keypair.public_key.clone()
232    }
233
234    pub fn get_shared_secret(&self) -> Option<[u8; 32]> {
235        self.shared_secret
236    }
237}