1pub mod decoder;
2
3use crate::core::transport::crypto::{AssociatedData, CryptError, Decrypter, Nonce};
4use crate::core::transport::{auth::Verifier, wire::packet::Packet};
5use decoder::Decoder;
6use derive_more::{Display, Error};
7use std::time::Duration;
8
9#[derive(Debug, Display, Error)]
10pub enum InputProcessorError {
11 EncodePacket(serde_cbor::Error),
12 UnableToVerifySignature,
13 InvalidPacketSignature,
14 DecodeData(decoder::DecoderError),
15 DecryptData(CryptError),
16}
17
18#[derive(Debug, Clone)]
19pub struct InputProcessor<V, D>
20where
21 V: Verifier,
22 D: Decrypter,
23{
24 decoder: Decoder,
25 verifier: V,
26 decrypter: D,
27}
28
29impl<V, D> InputProcessor<V, D>
30where
31 V: Verifier,
32 D: Decrypter,
33{
34 pub fn new(packet_ttl: Duration, verifier: V, decrypter: D) -> Self {
35 let decoder = Decoder::new(packet_ttl);
36 Self {
37 decoder,
38 verifier,
39 decrypter,
40 }
41 }
42
43 pub fn process(
44 &mut self,
45 data: &[u8],
46 ) -> Result<Option<Vec<u8>>, InputProcessorError> {
47 if data.is_empty() {
48 return Ok(None);
49 }
50
51 let p = Packet::from_slice(data)
53 .map_err(InputProcessorError::EncodePacket)?;
54
55 if !verify_packet(&self.verifier, &p)? {
58 return Err(InputProcessorError::InvalidPacketSignature);
59 }
60
61 let group_id = p.id();
62 let nonce = p.nonce().cloned();
63
64 self.decoder.remove_expired();
66
67 let do_decode = add_packet_and_verify(&mut self.decoder, p)?;
69 if do_decode {
70 let data = decode_and_decrypt(
72 group_id,
73 &self.decoder,
74 &self.decrypter,
75 nonce,
76 )?;
77
78 self.decoder.remove_group(group_id);
80
81 Ok(Some(data))
82 } else {
83 Ok(None)
84 }
85 }
86}
87
88fn verify_packet<V>(
89 verifier: &V,
90 packet: &Packet,
91) -> Result<bool, InputProcessorError>
92where
93 V: Verifier,
94{
95 let signature = packet.signature();
96 let content = packet
97 .content_for_signature()
98 .map_err(|_| InputProcessorError::UnableToVerifySignature)?;
99 Ok(verifier.verify(&content, signature))
100}
101
102fn add_packet_and_verify(
105 decoder: &mut Decoder,
106 packet: Packet,
107) -> Result<bool, InputProcessorError> {
108 let id = packet.id();
109
110 decoder
112 .add_packet(packet)
113 .map_err(InputProcessorError::DecodeData)?;
114
115 Ok(decoder.verify(id))
116}
117
118fn decode_and_decrypt<D>(
121 group_id: u32,
122 decoder: &Decoder,
123 decrypter: &D,
124 nonce: Option<Nonce>,
125) -> Result<Vec<u8>, InputProcessorError>
126where
127 D: Decrypter,
128{
129 let data = decoder
131 .decode(group_id)
132 .map_err(InputProcessorError::DecodeData)?;
133
134 let data = decrypter
136 .decrypt(&data, &AssociatedData::from(nonce))
137 .map_err(InputProcessorError::DecryptData)?;
138
139 Ok(data)
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145 use crate::core::transport::auth::NoopAuthenticator;
146 use crate::core::transport::crypto::NoopBicrypter;
147 use crate::core::transport::wire::{
148 output::encoder::{EncodeArgs, Encoder},
149 packet::{PacketEncryption, PacketType},
150 };
151 use std::time::Duration;
152
153 fn new_processor() -> InputProcessor<NoopAuthenticator, NoopBicrypter> {
154 InputProcessor::new(
155 Duration::from_secs(1),
156 NoopAuthenticator,
157 NoopBicrypter,
158 )
159 }
160
161 #[test]
162 fn input_processor_process_should_fail_if_unable_to_convert_bytes_to_packet(
163 ) {
164 let mut processor = new_processor();
165
166 match processor.process(&[0; 5]) {
167 Err(InputProcessorError::EncodePacket(_)) => (),
168 Err(x) => panic!("Unexpected error: {:?}", x),
169 Ok(x) => panic!("Unexpected result: {:?}", x),
170 }
171 }
172
173 #[test]
174 fn input_processor_process_should_fail_if_unable_to_add_packet_to_decoder()
175 {
176 let mut processor = new_processor();
177 let id = 0;
178 let encryption = PacketEncryption::None;
179 let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
180 let signer = NoopAuthenticator;
181 let mut encoder = Encoder::default();
182
183 let max_packet_size = encoder
187 .estimate_packet_size(
188 1,
189 PacketType::Final { encryption },
190 &signer,
191 )
192 .unwrap();
193
194 let p = &encoder
198 .encode(EncodeArgs {
199 id,
200 encryption,
201 data: &data,
202 max_packet_size,
203 signer: &signer,
204 })
205 .unwrap()[0];
206 let data = p.to_vec().unwrap();
207 assert_eq!(
208 processor.process(&data).is_ok(),
209 true,
210 "Failed to receive first packet!"
211 );
212
213 match processor.process(&data) {
216 Err(InputProcessorError::DecodeData(_)) => (),
217 Err(x) => panic!("Unexpected error: {:?}", x),
218 Ok(x) => panic!("Unexpected result: {:?}", x),
219 }
220 }
221
222 #[test]
223 fn input_processor_process_should_return_none_if_zero_bytes_received() {
224 let mut processor = new_processor();
225
226 match processor.process(&[0; 0]) {
227 Ok(None) => (),
228 Ok(Some(x)) => panic!("Unexpected result: {:?}", x),
229 Err(x) => panic!("Unexpected error: {:?}", x),
230 }
231 }
232
233 #[test]
234 fn input_processor_process_should_return_none_if_received_packet_does_not_complete_data(
235 ) {
236 let mut processor = new_processor();
237
238 let id = 0;
239 let encryption = PacketEncryption::None;
240 let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
241 let signer = NoopAuthenticator;
242 let mut encoder = Encoder::default();
243
244 let max_packet_size = encoder
248 .estimate_packet_size(
249 1,
250 PacketType::Final { encryption },
251 &signer,
252 )
253 .unwrap();
254
255 let p = &encoder
258 .encode(EncodeArgs {
259 id,
260 encryption,
261 data: &data,
262 max_packet_size,
263 signer: &NoopAuthenticator,
264 })
265 .unwrap()[0];
266 let data = p.to_vec().unwrap();
267 match processor.process(&data) {
268 Ok(None) => (),
269 Ok(Some(x)) => panic!("Unexpected result: {:?}", x),
270 Err(x) => panic!("Unexpected error: {:?}", x),
271 }
272 }
273
274 #[test]
275 fn input_processor_process_should_return_some_data_if_received_packet_does_complete_data(
276 ) {
277 let mut processor = new_processor();
278 let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
279
280 let p = &Encoder::default()
282 .encode(EncodeArgs {
283 id: 0,
284 encryption: PacketEncryption::None,
285 data: &data,
286 max_packet_size: 100,
287 signer: &NoopAuthenticator,
288 })
289 .unwrap()[0];
290 let pdata = p.to_vec().unwrap();
291 match processor.process(&pdata) {
292 Ok(Some(input_processor_process_data)) => {
293 assert_eq!(
294 input_processor_process_data, data,
295 "Received unexpected data: {:?}",
296 input_processor_process_data
297 );
298 }
299 Ok(None) => panic!("Unexpectedly received no data"),
300 Err(x) => panic!("Unexpected error: {:?}", x),
301 }
302 }
303
304 #[test]
305 fn input_processor_process_should_remove_expired_packet_groups() {
306 let mut processor = InputProcessor::new(
309 Duration::new(0, 0),
310 NoopAuthenticator,
311 NoopBicrypter,
312 );
313 let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
314 let mut encoder = Encoder::default();
315
316 let packets = &mut Encoder::default()
318 .encode(EncodeArgs {
319 id: 0,
320 encryption: PacketEncryption::None,
321 data: &data,
322 max_packet_size: encoder
323 .estimate_packet_size(
324 1,
325 PacketType::NotFinal,
326 &NoopAuthenticator,
327 )
328 .unwrap()
329 + data.len(),
330 signer: &NoopAuthenticator,
331 })
332 .unwrap();
333 assert!(packets.len() > 1, "Did not produce many small packets");
334
335 for p in packets.iter() {
336 let pdata = p.to_vec().unwrap();
337 assert!(
338 processor.process(&pdata).unwrap().is_none(),
339 "Unexpectedly got result from process with ttl of zero"
340 );
341 }
342 }
343
344 #[test]
345 fn input_processor_process_should_remove_the_decoder_packet_group_if_does_complete_data(
346 ) {
347 let mut processor = new_processor();
348 let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
349
350 let p = &Encoder::default()
352 .encode(EncodeArgs {
353 id: 0,
354 encryption: PacketEncryption::None,
355 data: &data,
356 max_packet_size: 100,
357 signer: &NoopAuthenticator,
358 })
359 .unwrap()[0];
360 let pdata = p.to_vec().unwrap();
361 processor.process(&pdata).unwrap();
362
363 assert_eq!(processor.decoder.len(), 0);
364 }
365
366 #[cfg(test)]
367 mod crypt {
368 use super::*;
369 use crate::core::transport::crypto::{CryptError, Decrypter, Encrypter};
370
371 #[derive(Clone)]
372 struct BadDecrypter;
373 impl Decrypter for BadDecrypter {
374 fn decrypt(
375 &self,
376 _: &[u8],
377 _: &AssociatedData,
378 ) -> Result<Vec<u8>, CryptError> {
379 Err(CryptError::DecryptFailed(From::from("Some error")))
380 }
381 }
382 impl Encrypter for BadDecrypter {
383 fn encrypt(
384 &self,
385 _: &[u8],
386 _: &AssociatedData,
387 ) -> Result<Vec<u8>, CryptError> {
388 Err(CryptError::EncryptFailed(From::from("Some error")))
389 }
390
391 fn new_encrypt_associated_data(
392 &self,
393 ) -> crate::core::transport::crypto::AssociatedData {
394 crate::core::transport::crypto::AssociatedData::None
395 }
396 }
397
398 fn new_processor() -> InputProcessor<NoopAuthenticator, BadDecrypter> {
399 InputProcessor::new(
400 Duration::from_secs(1),
401 NoopAuthenticator,
402 BadDecrypter,
403 )
404 }
405
406 #[test]
407 fn input_processor_process_should_fail_if_unable_to_decrypt_data() {
408 let mut processor = new_processor();
409
410 let id = 0;
411 let encryption = PacketEncryption::None;
412 let data = vec![1, 2, 3];
413 let signer = NoopAuthenticator;
414 let mut encoder = Encoder::default();
415
416 let max_packet_size = encoder
420 .estimate_packet_size(
421 1,
422 PacketType::Final { encryption },
423 &signer,
424 )
425 .unwrap();
426
427 let packets = encoder
429 .encode(EncodeArgs {
430 id,
431 encryption,
432 data: &data.clone(),
433 max_packet_size,
434 signer: &NoopAuthenticator,
435 })
436 .unwrap();
437
438 for p in packets[..packets.len() - 1].iter() {
440 let pdata = p.to_vec().unwrap();
441 assert_eq!(
442 processor.process(&pdata).is_ok(),
443 true,
444 "Unexpectedly failed to receive packet"
445 );
446 }
447
448 let final_packet = packets.last().unwrap();
450 let pdata = final_packet.to_vec().unwrap();
451 match processor.process(&pdata) {
452 Err(super::InputProcessorError::DecryptData(_)) => (),
453 Err(x) => panic!("Unexpected error: {:?}", x),
454 Ok(x) => panic!("Unexpected result: {:?}", x),
455 }
456 }
457 }
458}