tox_core/relay/
codec.rs

1/*! Codec implementation for encoding/decoding TCP Packets in terms of tokio-io
2*/
3
4use std::io::Error as IoError;
5
6use tox_binary_io::*;
7use tox_packet::relay::*;
8use crate::relay::secure::*;
9use crate::stats::*;
10
11use failure::Fail;
12use nom::{Needed, Offset, Err, error::ErrorKind};
13use bytes::{BytesMut, Buf};
14use tokio_util::codec::{Decoder, Encoder};
15
16/// Error that can happen when decoding `Packet` from bytes
17#[derive(Debug, Fail)]
18pub enum DecodeError {
19    /// Error indicates that received encrypted packet can't be parsed
20    #[fail(display = "Deserialize EncryptedPacket error: {:?}, buffer: {:?}", error, buf)]
21    DeserializeEncryptedError {
22        /// Parsing error
23        error: ErrorKind,
24        /// TCP buffer
25        buf: Vec<u8>,
26    },
27    /// Error indicates that received encrypted packet can't be decrypted
28    #[fail(display = "Decrypt EncryptedPacket error")]
29    DecryptError,
30    /// Error indicates that more data is needed to parse decrypted packet
31    #[fail(display = "Decrypted packet should not be incomplete: {:?}, packet: {:?}", needed, packet)]
32    IncompleteDecryptedPacket {
33        /// Required data size to be parsed
34        needed: Needed,
35        /// Received packet
36        packet: Vec<u8>,
37    },
38    /// Error indicates that decrypted packet can't be parsed
39    #[fail(display = "Deserialize decrypted packet error: {:?}, packet: {:?}", error, packet)]
40    DeserializeDecryptedError {
41        /// Parsing error
42        error: ErrorKind,
43        /// Received packet
44        packet: Vec<u8>,
45    },
46    /// General IO error
47    #[fail(display = "IO error: {:?}", error)]
48    IoError {
49        /// IO error
50        #[fail(cause)]
51        error: IoError
52    },
53}
54
55impl From<IoError> for DecodeError {
56    fn from(error: IoError) -> DecodeError {
57        DecodeError::IoError {
58            error
59        }
60    }
61}
62
63/// Error that can happen when encoding `Packet` to bytes
64#[derive(Debug, Fail)]
65pub enum EncodeError {
66    /// Error indicates that `Packet` is invalid and can't be serialized
67    #[fail(display = "Serialize Packet error: {:?}", error)]
68    SerializeError {
69        /// Serialization error
70        error: GenError
71    },
72    /// General IO error
73    #[fail(display = "IO error: {:?}", error)]
74    IoError {
75        /// IO error
76        #[fail(cause)]
77        error: IoError
78    },
79}
80
81impl From<IoError> for EncodeError {
82    fn from(error: IoError) -> EncodeError {
83        EncodeError::IoError {
84            error
85        }
86    }
87}
88
89/// implements tokio-io's Decoder and Encoder to deal with Packet
90pub struct Codec {
91    channel: Channel,
92    stats: Stats
93}
94
95impl Codec {
96    /// create a new Codec with the given Channel
97    pub fn new(channel: Channel, stats: Stats) -> Codec {
98        Codec {
99            channel,
100            stats
101        }
102    }
103}
104
105impl Decoder for Codec {
106    type Item = Packet;
107    type Error = DecodeError;
108
109    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
110        // deserialize EncryptedPacket
111        let (consumed, encrypted_packet) = match EncryptedPacket::from_bytes(buf) {
112            Err(Err::Incomplete(_)) => {
113                return Ok(None)
114            },
115            Err(Err::Error(error)) => {
116                let (_, kind) = error;
117                return Err(DecodeError::DeserializeEncryptedError { error: kind, buf: buf.to_vec() })
118            },
119            Err(Err::Failure(error)) => {
120                let (_, kind) = error;
121                return Err(DecodeError::DeserializeEncryptedError { error: kind, buf: buf.to_vec() })
122            },
123            Ok((i, encrypted_packet)) => {
124                (buf.offset(i), encrypted_packet)
125            }
126        };
127
128        // decrypt payload
129        let decrypted_data = self.channel.decrypt(&encrypted_packet.payload)
130            .map_err(|()| DecodeError::DecryptError)?;
131
132        // deserialize Packet
133        match Packet::from_bytes(&decrypted_data) {
134            Err(Err::Incomplete(needed)) => Err(DecodeError::IncompleteDecryptedPacket { needed, packet: decrypted_data }),
135            Err(Err::Error(error)) => {
136                let (_, kind) = error;
137                Err(DecodeError::DeserializeDecryptedError { error: kind, packet: decrypted_data })
138            },
139            Err(Err::Failure(error)) => {
140                let (_, kind) = error;
141                Err(DecodeError::DeserializeDecryptedError { error: kind, packet: decrypted_data })
142            },
143            Ok((_i, packet)) => {
144                // Add 1 to incoming counter
145                self.stats.counters.increase_incoming();
146
147                buf.advance(consumed);
148                Ok(Some(packet))
149            }
150        }
151    }
152}
153
154impl Encoder<Packet> for Codec {
155    type Error = EncodeError;
156
157    fn encode(&mut self, packet: Packet, buf: &mut BytesMut) -> Result<(), Self::Error> {
158        // Add 1 to outgoing counter
159        self.stats.counters.increase_outgoing();
160
161        // serialize Packet
162        let mut packet_buf = [0; MAX_TCP_PACKET_SIZE];
163        let (_, packet_size) = packet.to_bytes((&mut packet_buf, 0))
164            .map_err(|error| EncodeError::SerializeError { error })?;
165
166        // encrypt it
167        let encrypted = self.channel.encrypt(&packet_buf[..packet_size]);
168
169        // create EncryptedPacket
170        let encrypted_packet = EncryptedPacket { payload: encrypted };
171
172        // serialize EncryptedPacket to binary form
173        let mut encrypted_packet_buf = [0; MAX_TCP_ENC_PACKET_SIZE];
174        let (_, encrypted_packet_size) = encrypted_packet.to_bytes((&mut encrypted_packet_buf, 0))
175            .expect("EncryptedPacket serialize failed");  // there is nothing to fail since
176                                                                // serialized Packet is not longer than 2032 bytes
177                                                                // and we provided 2050 bytes for EncryptedPacket
178        buf.extend_from_slice(&encrypted_packet_buf[..encrypted_packet_size]);
179        Ok(())
180    }
181}
182
183#[cfg(test)]
184mod tests {
185    use tox_crypto::*;
186    use tox_packet::dht::CryptoData;
187    use tox_packet::onion::*;
188    use tox_packet::ip_port::*;
189    use crate::relay::codec::*;
190    use tox_packet::relay::connection_id::ConnectionId;
191
192    use std::io::{ErrorKind as IoErrorKind};
193    use std::net::{
194      IpAddr,
195      Ipv4Addr,
196      Ipv6Addr,
197    };
198
199    #[test]
200    fn decode_error_from_io() {
201        let error = IoError::new(IoErrorKind::Other, "io error");
202        let decode_error = DecodeError::from(error);
203        assert_eq!(unpack!(decode_error, DecodeError::IoError, error).kind(), IoErrorKind::Other);
204    }
205
206    #[test]
207    fn encode_error_from_io() {
208        let error = IoError::new(IoErrorKind::Other, "io error");
209        let encode_error = EncodeError::from(error);
210        assert_eq!(unpack!(encode_error, EncodeError::IoError, error).kind(), IoErrorKind::Other);
211    }
212
213    fn create_channels() -> (Channel, Channel) {
214        let alice_session = Session::random();
215        let bob_session = Session::random();
216
217        // assume we got Alice's PK & Nonce via handshake
218        let alice_pk = *alice_session.pk();
219        let alice_nonce = *alice_session.nonce();
220
221        // assume we got Bob's PK & Nonce via handshake
222        let bob_pk = *bob_session.pk();
223        let bob_nonce = *bob_session.nonce();
224
225        // Now both Alice and Bob may create secure Channels
226        let alice_channel = Channel::new(&alice_session, &bob_pk, &bob_nonce);
227        let bob_channel = Channel::new(&bob_session, &alice_pk, &alice_nonce);
228
229        (alice_channel, bob_channel)
230    }
231
232    #[test]
233    fn encode_decode() {
234        crypto_init().unwrap();
235        let (pk, _) = gen_keypair();
236        let (alice_channel, bob_channel) = create_channels();
237        let mut buf = BytesMut::new();
238        let stats = Stats::new();
239        let mut alice_codec = Codec::new(alice_channel, stats.clone());
240        let mut bob_codec = Codec::new(bob_channel, stats);
241
242        let test_packets = vec![
243            Packet::RouteRequest( RouteRequest { pk } ),
244            Packet::RouteResponse( RouteResponse { connection_id: ConnectionId::from_index(42), pk } ),
245            Packet::ConnectNotification( ConnectNotification { connection_id: ConnectionId::from_index(42) } ),
246            Packet::DisconnectNotification( DisconnectNotification { connection_id: ConnectionId::from_index(42) } ),
247            Packet::PingRequest( PingRequest { ping_id: 4242 } ),
248            Packet::PongResponse( PongResponse { ping_id: 4242 } ),
249            Packet::OobSend( OobSend { destination_pk: pk, data: vec![13; 42] } ),
250            Packet::OobReceive( OobReceive { sender_pk: pk, data: vec![13; 24] } ),
251            Packet::OnionRequest( OnionRequest {
252                nonce: gen_nonce(),
253                ip_port: IpPort {
254                    protocol: ProtocolType::TCP,
255                    ip_addr: IpAddr::V4(Ipv4Addr::new(5, 6, 7, 8)),
256                    port: 12345,
257                },
258                temporary_pk: gen_keypair().0,
259                payload: vec![13; 207]
260            } ),
261            Packet::OnionRequest( OnionRequest {
262                nonce: gen_nonce(),
263                ip_port: IpPort {
264                    protocol: ProtocolType::TCP,
265                    ip_addr: IpAddr::V6(Ipv6Addr::new(5, 6, 7, 8, 5, 6, 7, 8)),
266                    port: 54321,
267                },
268                temporary_pk: gen_keypair().0,
269                payload: vec![13; 201]
270            } ),
271            Packet::OnionResponse( OnionResponse {
272                payload: InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse {
273                    sendback_data: 12345,
274                    nonce: gen_nonce(),
275                    payload: vec![42; 123]
276                })
277            } ),
278            Packet::OnionResponse( OnionResponse {
279                payload: InnerOnionResponse::OnionDataResponse(OnionDataResponse {
280                    nonce: gen_nonce(),
281                    temporary_pk: gen_keypair().0,
282                    payload: vec![42; 123]
283                })
284            } ),
285            Packet::Data( Data {
286                connection_id: ConnectionId::from_index(42),
287                data: DataPayload::CryptoData(CryptoData {
288                    nonce_last_bytes: 42,
289                    payload: vec![42; 123],
290                }),
291            } )
292        ];
293        for packet in test_packets {
294            alice_codec.encode(packet.clone(), &mut buf).expect("Alice should encode");
295            let res = bob_codec.decode(&mut buf).unwrap().expect("Bob should decode");
296            assert_eq!(packet, res);
297
298            bob_codec.encode(packet.clone(), &mut buf).expect("Bob should encode");
299            let res = alice_codec.decode(&mut buf).unwrap().expect("Alice should decode");
300            assert_eq!(packet, res);
301        }
302    }
303    #[test]
304    fn decode_encrypted_packet_incomplete() {
305        crypto_init().unwrap();
306        let (alice_channel, _) = create_channels();
307        let mut buf = BytesMut::new();
308        buf.extend_from_slice(b"\x00");
309        let stats = Stats::new();
310        let mut alice_codec = Codec::new(alice_channel, stats);
311
312        // not enought bytes to decode EncryptedPacket
313        assert_eq!(alice_codec.decode(&mut buf).unwrap(), None);
314    }
315    #[test]
316    fn decode_encrypted_packet_zero_length() {
317        crypto_init().unwrap();
318        let (alice_channel, _) = create_channels();
319        let mut buf = BytesMut::new();
320        buf.extend_from_slice(b"\x00\x00");
321        let stats = Stats::new();
322        let mut alice_codec = Codec::new(alice_channel, stats);
323
324        // 0-length payload is invalid
325        assert!(alice_codec.decode(&mut buf).is_err());
326    }
327    #[test]
328    fn decode_encrypted_packet_wrong_key() {
329        crypto_init().unwrap();
330        let (alice_channel, _) = create_channels();
331        let (mallory_channel, _) = create_channels();
332
333        let stats = Stats::new();
334        let mut alice_codec = Codec::new(alice_channel, stats.clone());
335        let mut mallory_codec = Codec::new(mallory_channel, stats);
336
337        let mut buf = BytesMut::new();
338        let packet = Packet::PingRequest( PingRequest { ping_id: 4242 } );
339
340        alice_codec.encode(packet, &mut buf).expect("Alice should encode");
341        // Mallory cannot decode the payload of EncryptedPacket
342        assert!(mallory_codec.decode(&mut buf).err().is_some());
343    }
344    #[test]
345    fn decode_packet_imcomplete() {
346        crypto_init().unwrap();
347        let (alice_channel, _) = create_channels();
348
349        let mut buf = BytesMut::new();
350        let stats = Stats::new();
351        let mut bob_codec = Codec::new(alice_channel, stats);
352
353        // not enough bytes to decode Packet
354        assert!(bob_codec.decode(&mut buf).unwrap().is_none());
355    }
356    #[test]
357    fn decode_packet_error() {
358        crypto_init().unwrap();
359        let alice_session = Session::random();
360
361        // assume we got Alice's PK via handshake
362        let alice_pk = *alice_session.pk();
363
364        // assume we got Bob's PK & Nonce via handshake
365        let (bob_pk, bob_sk) = gen_keypair();
366        let bob_nonce = gen_nonce();
367
368        // Now both Alice and Bob may create secure Channels
369        let alice_channel = Channel::new(&alice_session, &bob_pk, &bob_nonce);
370
371        let stats = Stats::new();
372        let mut alice_codec = Codec::new(alice_channel, stats);
373
374        // packet with invalid id
375        let payload = seal(&[0x0F], &bob_nonce, &alice_pk, &bob_sk);
376        let packet = EncryptedPacket {
377            payload,
378        };
379        let mut packet_bytes = [0; 32];
380        let (_, size) = packet.to_bytes((&mut packet_bytes, 0)).unwrap();
381
382        let mut buf = BytesMut::new();
383        buf.extend_from_slice(&packet_bytes[..size]);
384
385        assert!(alice_codec.decode(&mut buf).is_err());
386    }
387
388    #[test]
389    fn encode_packet_too_big() {
390        crypto_init().unwrap();
391        let (alice_channel, _) = create_channels();
392        let mut buf = BytesMut::new();
393        let stats = Stats::new();
394        let mut alice_codec = Codec::new(alice_channel, stats);
395        let packet = Packet::Data( Data {
396            connection_id: ConnectionId::from_index(42),
397            data: DataPayload::CryptoData(CryptoData {
398                nonce_last_bytes: 42,
399                payload: vec![42; 2030],
400            })
401        } );
402
403        // Alice cannot serialize Packet because it is too long
404        assert!(alice_codec.encode(packet, &mut buf).is_err());
405    }
406}