1 #![cfg(any(feature = "default-resolver", feature = "ring-accelerated"))]
2 #![allow(clippy::needless_range_loop)]
3 #![allow(non_snake_case)]
4 
5 use hex::FromHex;
6 use snow::{
7     resolvers::{CryptoResolver, DefaultResolver},
8     Builder,
9 };
10 
11 use rand_core::{impls, CryptoRng, RngCore};
12 use snow::{params::*, types::*};
13 use x25519_dalek as x25519;
14 
15 #[derive(Default)]
16 struct CountingRng(u64);
17 
18 impl RngCore for CountingRng {
next_u32(&mut self) -> u3219     fn next_u32(&mut self) -> u32 {
20         self.next_u64() as u32
21     }
22 
next_u64(&mut self) -> u6423     fn next_u64(&mut self) -> u64 {
24         self.0 += 1;
25         self.0
26     }
27 
fill_bytes(&mut self, dest: &mut [u8])28     fn fill_bytes(&mut self, dest: &mut [u8]) {
29         impls::fill_bytes_via_next(self, dest)
30     }
31 
try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error>32     fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
33         self.fill_bytes(dest);
34         Ok(())
35     }
36 }
37 
38 impl CryptoRng for CountingRng {}
39 impl Random for CountingRng {}
40 
get_inc_key(start: u8) -> [u8; 32]41 fn get_inc_key(start: u8) -> [u8; 32] {
42     let mut k = [0u8; 32];
43     for i in 0..32 {
44         k[i] = start + i as u8;
45     }
46     k
47 }
48 
49 #[allow(unused)]
50 struct TestResolver {
51     next_byte: u8,
52     parent:    DefaultResolver,
53 }
54 
55 #[allow(unused)]
56 impl TestResolver {
new(next_byte: u8) -> Self57     pub fn new(next_byte: u8) -> Self {
58         TestResolver { next_byte, parent: DefaultResolver }
59     }
60 
next_byte(&mut self, next_byte: u8)61     pub fn next_byte(&mut self, next_byte: u8) {
62         self.next_byte = next_byte;
63     }
64 }
65 
66 impl CryptoResolver for TestResolver {
resolve_rng(&self) -> Option<Box<dyn Random>>67     fn resolve_rng(&self) -> Option<Box<dyn Random>> {
68         let rng = CountingRng(self.next_byte as u64);
69         Some(Box::new(rng))
70     }
71 
resolve_dh(&self, choice: &DHChoice) -> Option<Box<dyn Dh>>72     fn resolve_dh(&self, choice: &DHChoice) -> Option<Box<dyn Dh>> {
73         self.parent.resolve_dh(choice)
74     }
75 
resolve_hash(&self, choice: &HashChoice) -> Option<Box<dyn Hash>>76     fn resolve_hash(&self, choice: &HashChoice) -> Option<Box<dyn Hash>> {
77         self.parent.resolve_hash(choice)
78     }
79 
resolve_cipher(&self, choice: &CipherChoice) -> Option<Box<dyn Cipher>>80     fn resolve_cipher(&self, choice: &CipherChoice) -> Option<Box<dyn Cipher>> {
81         self.parent.resolve_cipher(choice)
82     }
83 }
84 
85 #[test]
test_protocol_name()86 fn test_protocol_name() {
87     let protocol_spec: NoiseParams = "Noise_NK_25519_ChaChaPoly_BLAKE2s".parse().unwrap();
88 
89     assert_eq!(protocol_spec.base, BaseChoice::Noise);
90     assert_eq!(protocol_spec.handshake.pattern, HandshakePattern::NK);
91     assert_eq!(protocol_spec.cipher, CipherChoice::ChaChaPoly);
92     assert_eq!(protocol_spec.hash, HashChoice::Blake2s);
93 
94     let protocol_spec: Result<NoiseParams, _> = "Noise_NK_25519_ChaChaPoly_FAKE2X".parse();
95     if protocol_spec.is_ok() {
96         panic!("invalid protocol was parsed inaccurately");
97     }
98 
99     let protocol_spec: Result<NoiseParams, _> = "Noise_NK_25519_ChaChaPoly".parse();
100     if protocol_spec.is_ok() {
101         panic!("invalid protocol was parsed inaccurately");
102     }
103 }
104 
105 #[test]
test_noise_state_change()106 fn test_noise_state_change() {
107     let params: NoiseParams = "Noise_NN_25519_ChaChaPoly_SHA256".parse().unwrap();
108     let mut h_i = Builder::new(params.clone()).build_initiator().unwrap();
109     let mut h_r = Builder::new(params).build_responder().unwrap();
110 
111     let mut buffer_msg = [0u8; 200];
112     let mut buffer_out = [0u8; 200];
113     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
114     h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
115 
116     let len = h_r.write_message(b"defg", &mut buffer_msg).unwrap();
117     h_i.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
118 
119     assert!(h_i.is_handshake_finished());
120     assert!(h_r.is_handshake_finished());
121     let _ = h_i.into_transport_mode().unwrap();
122     let _ = h_r.into_transport_mode().unwrap();
123 }
124 
125 #[test]
test_sanity_chachapoly_session()126 fn test_sanity_chachapoly_session() {
127     let params: NoiseParams = "Noise_NN_25519_ChaChaPoly_SHA256".parse().unwrap();
128     let mut h_i = Builder::new(params.clone()).build_initiator().unwrap();
129     let mut h_r = Builder::new(params).build_responder().unwrap();
130 
131     let mut buffer_msg = [0u8; 200];
132     let mut buffer_out = [0u8; 200];
133     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
134     h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
135 
136     let len = h_r.write_message(b"defg", &mut buffer_msg).unwrap();
137     h_i.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
138 
139     let mut h_i = h_i.into_transport_mode().unwrap();
140     let mut h_r = h_r.into_transport_mode().unwrap();
141 
142     let len = h_i.write_message(b"hack the planet", &mut buffer_msg).unwrap();
143     let len = h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
144     assert_eq!(&buffer_out[..len], b"hack the planet");
145 }
146 
147 #[test]
test_sanity_aesgcm_session()148 fn test_sanity_aesgcm_session() {
149     let params: NoiseParams = "Noise_NN_25519_AESGCM_SHA256".parse().unwrap();
150     let mut h_i = Builder::new(params.clone()).build_initiator().unwrap();
151     let mut h_r = Builder::new(params).build_responder().unwrap();
152 
153     let mut buffer_msg = [0u8; 200];
154     let mut buffer_out = [0u8; 200];
155     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
156     h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
157 
158     let len = h_r.write_message(b"defg", &mut buffer_msg).unwrap();
159     h_i.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
160 
161     let mut h_i = h_i.into_transport_mode().unwrap();
162     let mut h_r = h_r.into_transport_mode().unwrap();
163 
164     let len = h_i.write_message(b"hack the planet", &mut buffer_msg).unwrap();
165     let len = h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
166     assert_eq!(&buffer_out[..len], b"hack the planet");
167 }
168 
169 #[test]
test_Npsk0_chachapoly_expected_value()170 fn test_Npsk0_chachapoly_expected_value() {
171     let params: NoiseParams = "Noise_Npsk0_25519_ChaChaPoly_SHA256".parse().unwrap();
172     let mut h_i = Builder::new(params)
173         .remote_public_key(&x25519::x25519(get_inc_key(0), x25519::X25519_BASEPOINT_BYTES))
174         .psk(0, &get_inc_key(1))
175         .fixed_ephemeral_key_for_testing_only(&get_inc_key(32))
176         .build_initiator()
177         .unwrap();
178 
179     let mut buf = [0u8; 200];
180     let len = h_i.write_message(&[], &mut buf).unwrap();
181     assert_eq!(len, 48);
182 
183     let expected = Vec::<u8>::from_hex("358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254deb8a4f6190117dea09aad7546a4658c").unwrap();
184 
185     println!("\nreality:  {}", hex::encode(&buf[..len]));
186     println!("expected: {}", hex::encode(&expected));
187     assert_eq!(&buf[..len], &expected[..]);
188 }
189 
190 #[test]
test_Npsk0_aesgcm_expected_value()191 fn test_Npsk0_aesgcm_expected_value() {
192     let params: NoiseParams = "Noise_Npsk0_25519_AESGCM_SHA256".parse().unwrap();
193     let mut h_i = Builder::new(params)
194         .remote_public_key(&x25519::x25519(get_inc_key(0), x25519::X25519_BASEPOINT_BYTES))
195         .psk(0, &get_inc_key(1))
196         .fixed_ephemeral_key_for_testing_only(&get_inc_key(32))
197         .build_initiator()
198         .unwrap();
199 
200     let mut buf = [0u8; 200];
201     let len = h_i.write_message(&[], &mut buf).unwrap();
202     assert_eq!(len, 48);
203 
204     let expected = Vec::<u8>::from_hex("358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542044ae563929068930dcf04674526cb9").unwrap();
205 
206     println!("\nreality:  {}", hex::encode(&buf[..len]));
207     println!("expected: {}", hex::encode(&expected));
208     assert_eq!(&buf[..len], &expected[..]);
209 }
210 
211 #[test]
test_Npsk0_expected_value()212 fn test_Npsk0_expected_value() {
213     let params: NoiseParams = "Noise_Npsk0_25519_ChaChaPoly_SHA256".parse().unwrap();
214     let mut h_i = Builder::new(params)
215         .remote_public_key(&x25519::x25519(get_inc_key(0), x25519::X25519_BASEPOINT_BYTES))
216         .psk(0, &get_inc_key(1))
217         .fixed_ephemeral_key_for_testing_only(&get_inc_key(32))
218         .build_initiator()
219         .unwrap();
220 
221     let mut buf = [0u8; 200];
222     let len = h_i.write_message(&[], &mut buf).unwrap();
223     assert_eq!(len, 48);
224 
225     let expected = Vec::<u8>::from_hex("358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254deb8a4f6190117dea09aad7546a4658c").unwrap();
226 
227     println!("\nreality:  {}", hex::encode(&buf[..len]));
228     println!("expected: {}", hex::encode(&expected));
229     assert_eq!(&buf[..len], &expected[..]);
230 }
231 
232 #[test]
test_Xpsk0_expected_value()233 fn test_Xpsk0_expected_value() {
234     let params: NoiseParams = "Noise_Xpsk0_25519_ChaChaPoly_SHA256".parse().unwrap();
235     let mut h_i = Builder::new(params)
236         .local_private_key(&get_inc_key(0))
237         .remote_public_key(&x25519::x25519(get_inc_key(32), x25519::X25519_BASEPOINT_BYTES))
238         .psk(0, &get_inc_key(1))
239         .fixed_ephemeral_key_for_testing_only(&get_inc_key(64))
240         .build_initiator()
241         .unwrap();
242 
243     let mut buf = [0u8; 200];
244     let len = h_i.write_message(&[], &mut buf).unwrap();
245     assert_eq!(len, 96);
246 
247     let expected = Vec::<u8>::from_hex("79a631eede1bf9c98f12032cdeadd0e7a079398fc786b88cc846ec89af85a51ad51eef529db0dd9127d4aa59a9183e118337d75a4e55e7e00f85c3d20ede536dd0112eec8c3b2a514018a90ab685b027dd24aa0c70b0c0f00524cc23785028b9").unwrap();
248 
249     println!("\nreality:  {}", hex::encode(&buf[..len]));
250     println!("expected: {}", hex::encode(&expected));
251     assert_eq!(&buf[..len], &expected[..]);
252 }
253 
254 #[test]
255 #[cfg(feature = "hfs")]
256 #[cfg(feature = "pqclean_kyber1024")]
test_NNhfs_sanity_session()257 fn test_NNhfs_sanity_session() {
258     // Due to how PQClean is implemented, we cannot do deterministic testing of the protocol.
259     // Instead, we will see if the protocol runs smoothly.
260     let params: NoiseParams = "Noise_NNhfs_25519+Kyber1024_ChaChaPoly_SHA256".parse().unwrap();
261     let mut h_i = Builder::new(params.clone()).build_initiator().unwrap();
262     let mut h_r = Builder::new(params).build_responder().unwrap();
263 
264     let mut buffer_msg = [0u8; 4096];
265     let mut buffer_out = [0u8; 4096];
266     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
267     h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
268 
269     let len = h_r.write_message(b"defg", &mut buffer_msg).unwrap();
270     h_i.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
271 
272     let mut h_i = h_i.into_transport_mode().unwrap();
273     let mut h_r = h_r.into_transport_mode().unwrap();
274 
275     let len = h_i.write_message(b"hack the planet", &mut buffer_msg).unwrap();
276     let len = h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
277     assert_eq!(&buffer_out[..len], b"hack the planet");
278 }
279 
280 #[test]
test_XXpsk0_expected_value()281 fn test_XXpsk0_expected_value() {
282     let params: NoiseParams = "Noise_XXpsk0_25519_ChaChaPoly_SHA256".parse().unwrap();
283     let mut h_i = Builder::new(params.clone())
284         .local_private_key(&get_inc_key(0))
285         .remote_public_key(&x25519::x25519(get_inc_key(1), x25519::X25519_BASEPOINT_BYTES))
286         .prologue(&[1u8, 2, 3])
287         .psk(0, &get_inc_key(4))
288         .fixed_ephemeral_key_for_testing_only(&get_inc_key(32))
289         .build_initiator()
290         .unwrap();
291     let mut h_r = Builder::new(params)
292         .local_private_key(&get_inc_key(1))
293         .remote_public_key(&x25519::x25519(get_inc_key(0), x25519::X25519_BASEPOINT_BYTES))
294         .prologue(&[1u8, 2, 3])
295         .psk(0, &get_inc_key(4))
296         .fixed_ephemeral_key_for_testing_only(&get_inc_key(33))
297         .build_responder()
298         .unwrap();
299 
300     let mut buf = [0u8; 1024];
301     let mut buf2 = [0u8; 1024];
302 
303     let len = h_i.write_message(b"abc", &mut buf).unwrap();
304     assert_eq!(len, 51);
305     let len = h_r.read_message(&buf[..len], &mut buf2).unwrap();
306     assert_eq!(&buf2[..len], b"abc");
307 
308     let len = h_r.write_message(b"defg", &mut buf).unwrap();
309     assert_eq!(len, 100);
310     let len = h_i.read_message(&buf[..len], &mut buf2).unwrap();
311     assert_eq!(&buf2[..len], b"defg");
312 
313     let len = h_i.write_message(&[], &mut buf).unwrap();
314     assert_eq!(len, 64);
315     let len = h_r.read_message(&buf[..len], &mut buf2).unwrap();
316     assert_eq!(len, 0);
317 
318     let expected = Vec::<u8>::from_hex("072b7bbd237ac602c4aa938db36998f31ca4750752d1758d59850c627d0bdbc51205592c3baa101b4a31f062695b7c1dbee99d5123fbd2ad03052078c570e028").unwrap();
319     println!("\nreality:  {}", hex::encode(&buf[..64]));
320     println!("expected: {}", hex::encode(&expected));
321     assert_eq!(&buf[..64], &expected[..]);
322 }
323 
324 #[test]
test_NNpsk0_sanity_session()325 fn test_NNpsk0_sanity_session() {
326     let params: NoiseParams = "Noise_NNpsk0_25519_ChaChaPoly_SHA256".parse().unwrap();
327     let mut h_i = Builder::new(params.clone()).psk(0, &[32u8; 32]).build_initiator().unwrap();
328     let mut h_r = Builder::new(params).psk(0, &[32u8; 32]).build_responder().unwrap();
329 
330     let mut buffer_msg = [0u8; 200];
331     let mut buffer_out = [0u8; 200];
332     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
333     h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
334 
335     let len = h_r.write_message(b"defg", &mut buffer_msg).unwrap();
336     h_i.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
337 
338     let mut h_i = h_i.into_transport_mode().unwrap();
339     let mut h_r = h_r.into_transport_mode().unwrap();
340 
341     let len = h_i.write_message(b"hack the planet", &mut buffer_msg).unwrap();
342     let len = h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
343     assert_eq!(&buffer_out[..len], b"hack the planet");
344 }
345 
346 #[test]
test_XXpsk3_sanity_session()347 fn test_XXpsk3_sanity_session() {
348     let params: NoiseParams = "Noise_XXpsk3_25519_ChaChaPoly_SHA256".parse().unwrap();
349     let b_i = Builder::new(params.clone());
350     let b_r = Builder::new(params);
351     let static_i = b_i.generate_keypair().unwrap();
352     let static_r = b_r.generate_keypair().unwrap();
353     let mut h_i = b_i
354         .psk(3, &[32u8; 32])
355         .local_private_key(&static_i.private)
356         .remote_public_key(&static_r.public)
357         .build_initiator()
358         .unwrap();
359     let mut h_r = b_r
360         .psk(3, &[32u8; 32])
361         .local_private_key(&static_r.private)
362         .remote_public_key(&static_i.public)
363         .build_responder()
364         .unwrap();
365 
366     let mut buffer_msg = [0u8; 200];
367     let mut buffer_out = [0u8; 200];
368     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
369     h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
370 
371     let len = h_r.write_message(b"defg", &mut buffer_msg).unwrap();
372     h_i.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
373 
374     let len = h_i.write_message(b"hij", &mut buffer_msg).unwrap();
375     h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
376 
377     let mut h_i = h_i.into_transport_mode().unwrap();
378     let mut h_r = h_r.into_transport_mode().unwrap();
379 
380     let len = h_i.write_message(b"hack the planet", &mut buffer_msg).unwrap();
381     let len = h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
382     assert_eq!(&buffer_out[..len], b"hack the planet");
383 }
384 
385 #[test]
test_rekey()386 fn test_rekey() {
387     let params: NoiseParams = "Noise_NN_25519_ChaChaPoly_SHA256".parse().unwrap();
388     let mut h_i = Builder::new(params.clone()).build_initiator().unwrap();
389     let mut h_r = Builder::new(params).build_responder().unwrap();
390 
391     let mut buffer_msg = [0u8; 200];
392     let mut buffer_out = [0u8; 200];
393     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
394     h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
395 
396     let len = h_r.write_message(b"defg", &mut buffer_msg).unwrap();
397     h_i.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
398 
399     let mut h_i = h_i.into_transport_mode().unwrap();
400     let mut h_r = h_r.into_transport_mode().unwrap();
401 
402     // test message initiator->responder before rekeying initiator
403     let len = h_i.write_message(b"hack the planet", &mut buffer_msg).unwrap();
404     let len = h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
405     assert_eq!(&buffer_out[..len], b"hack the planet");
406 
407     // rekey outgoing on initiator
408     h_i.rekey_outgoing();
409     let len = h_i.write_message(b"hack the planet", &mut buffer_msg).unwrap();
410     assert!(h_r.read_message(&buffer_msg[..len], &mut buffer_out).is_err());
411 
412     // rekey incoming on responder
413     h_r.rekey_incoming();
414     let len = h_i.write_message(b"hack the planet", &mut buffer_msg).unwrap();
415     let len = h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
416     assert_eq!(&buffer_out[..len], b"hack the planet");
417 
418     // rekey outgoing on responder
419     h_r.rekey_outgoing();
420     let len = h_r.write_message(b"hack the planet", &mut buffer_msg).unwrap();
421     assert!(h_i.read_message(&buffer_msg[..len], &mut buffer_out).is_err());
422 
423     // rekey incoming on initiator
424     h_i.rekey_incoming();
425     let len = h_r.write_message(b"hack the planet", &mut buffer_msg).unwrap();
426     let len = h_i.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
427     assert_eq!(&buffer_out[..len], b"hack the planet");
428 }
429 
430 #[test]
test_rekey_manually()431 fn test_rekey_manually() {
432     let params: NoiseParams = "Noise_NN_25519_ChaChaPoly_SHA256".parse().unwrap();
433     let mut h_i = Builder::new(params.clone()).build_initiator().unwrap();
434     let mut h_r = Builder::new(params).build_responder().unwrap();
435 
436     let mut buffer_msg = [0u8; 200];
437     let mut buffer_out = [0u8; 200];
438     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
439     h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
440 
441     let len = h_r.write_message(b"defg", &mut buffer_msg).unwrap();
442     h_i.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
443 
444     let mut h_i = h_i.into_transport_mode().unwrap();
445     let mut h_r = h_r.into_transport_mode().unwrap();
446 
447     // test message initiator->responder before rekeying initiator
448     let len = h_i.write_message(b"hack the planet", &mut buffer_msg).unwrap();
449     let len = h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
450     assert_eq!(&buffer_out[..len], b"hack the planet");
451 
452     // rekey initiator (on initiator)
453     h_i.rekey_manually(Some(&[1u8; 32]), None);
454     let len = h_i.write_message(b"hack the planet", &mut buffer_msg).unwrap();
455     assert!(h_r.read_message(&buffer_msg[..len], &mut buffer_out).is_err());
456 
457     // rekey initiator (on responder)
458     h_r.rekey_manually(Some(&[1u8; 32]), None);
459     let len = h_i.write_message(b"hack the planet", &mut buffer_msg).unwrap();
460     let len = h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
461     assert_eq!(&buffer_out[..len], b"hack the planet");
462 
463     // rekey responder (on responder)
464     h_r.rekey_manually(None, Some(&[1u8; 32]));
465     let len = h_r.write_message(b"hack the planet", &mut buffer_msg).unwrap();
466     assert!(h_i.read_message(&buffer_msg[..len], &mut buffer_out).is_err());
467 
468     // rekey responder (on initiator)
469     h_i.rekey_manually(None, Some(&[1u8; 32]));
470     let len = h_r.write_message(b"hack the planet", &mut buffer_msg).unwrap();
471     let len = h_i.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
472     assert_eq!(&buffer_out[..len], b"hack the planet");
473 }
474 
475 #[test]
test_handshake_message_exceeds_max_len()476 fn test_handshake_message_exceeds_max_len() {
477     let params: NoiseParams = "Noise_NN_25519_ChaChaPoly_SHA256".parse().unwrap();
478     let mut h_i = Builder::new(params).build_initiator().unwrap();
479 
480     let mut buffer_out = [0u8; 65535 * 2];
481     assert!(h_i.write_message(&[0u8; 65530], &mut buffer_out).is_err());
482 }
483 
484 #[test]
test_handshake_message_undersized_output_buffer()485 fn test_handshake_message_undersized_output_buffer() {
486     let params: NoiseParams = "Noise_NN_25519_ChaChaPoly_SHA256".parse().unwrap();
487     let mut h_i = Builder::new(params).build_initiator().unwrap();
488 
489     let mut buffer_out = [0u8; 200];
490     assert!(h_i.write_message(&[0u8; 400], &mut buffer_out).is_err());
491 }
492 
493 #[test]
test_transport_message_exceeds_max_len()494 fn test_transport_message_exceeds_max_len() {
495     let params: NoiseParams = "Noise_N_25519_ChaChaPoly_SHA256".parse().unwrap();
496     let mut noise = Builder::new(params).remote_public_key(&[1u8; 32]).build_initiator().unwrap();
497 
498     let mut buffer_out = [0u8; 65535 * 2];
499     noise.write_message(&[0u8; 0], &mut buffer_out).unwrap();
500     let mut noise = noise.into_transport_mode().unwrap();
501     assert!(noise.write_message(&[0u8; 65534], &mut buffer_out).is_err());
502 }
503 
504 #[test]
test_transport_message_undersized_output_buffer()505 fn test_transport_message_undersized_output_buffer() {
506     let params: NoiseParams = "Noise_N_25519_ChaChaPoly_SHA256".parse().unwrap();
507     let mut noise = Builder::new(params).remote_public_key(&[1u8; 32]).build_initiator().unwrap();
508 
509     let mut buffer_out = [0u8; 200];
510     noise.write_message(&[0u8; 0], &mut buffer_out).unwrap();
511     let mut noise = noise.into_transport_mode().unwrap();
512     assert!(noise.write_message(&[0u8; 300], &mut buffer_out).is_err());
513 }
514 
515 #[test]
test_oneway_initiator_enforcements()516 fn test_oneway_initiator_enforcements() {
517     let params: NoiseParams = "Noise_N_25519_ChaChaPoly_SHA256".parse().unwrap();
518     let mut noise = Builder::new(params).remote_public_key(&[1u8; 32]).build_initiator().unwrap();
519 
520     let mut buffer_out = [0u8; 1024];
521     noise.write_message(&[0u8; 0], &mut buffer_out).unwrap();
522     let mut noise = noise.into_transport_mode().unwrap();
523     assert!(noise.read_message(&[0u8; 1024], &mut buffer_out).is_err());
524 }
525 
526 #[test]
test_oneway_responder_enforcements()527 fn test_oneway_responder_enforcements() {
528     let params: NoiseParams = "Noise_N_25519_ChaChaPoly_SHA256".parse().unwrap();
529     let resp_builder = Builder::new(params.clone());
530     let rpk = resp_builder.generate_keypair().unwrap();
531 
532     let mut resp = resp_builder.local_private_key(&rpk.private).build_responder().unwrap();
533     let mut init = Builder::new(params).remote_public_key(&rpk.public).build_initiator().unwrap();
534 
535     let mut buffer_resp = [0u8; 65535];
536     let mut buffer_init = [0u8; 65535];
537     let len = init.write_message(&[0u8; 0], &mut buffer_init).unwrap();
538     resp.read_message(&buffer_init[..len], &mut buffer_resp).unwrap();
539     let mut init = init.into_transport_mode().unwrap();
540     let mut resp = resp.into_transport_mode().unwrap();
541 
542     assert!(init.read_message(&[0u8; 1024], &mut buffer_init).is_err());
543     assert!(resp.write_message(&[0u8; 1024], &mut buffer_resp).is_err());
544 }
545 
546 #[test]
test_buffer_issues()547 fn test_buffer_issues() {
548     let params: NoiseParams = "Noise_NN_25519_ChaChaPoly_SHA256".parse().unwrap();
549     let mut h_i = Builder::new(params.clone()).build_initiator().unwrap();
550     let mut h_r = Builder::new(params).build_responder().unwrap();
551 
552     let mut buffer_msg = [0u8; 200];
553     let mut buffer_out = [0u8; 2];
554     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
555     let res = h_r.read_message(&buffer_msg[..len], &mut buffer_out);
556 
557     assert!(res.is_err());
558 }
559 
560 #[test]
test_read_buffer_issues()561 fn test_read_buffer_issues() {
562     let params: NoiseParams = "Noise_XK_25519_ChaChaPoly_BLAKE2s".parse().unwrap();
563 
564     let builder_r = snow::Builder::new(params.clone());
565     let keypair_r = builder_r.generate_keypair().unwrap();
566     let mut h_r = builder_r.local_private_key(&keypair_r.private).build_responder().unwrap();
567 
568     let builder_i = snow::Builder::new(params);
569     let key_i = builder_i.generate_keypair().unwrap().private;
570     let mut h_i = builder_i
571         .local_private_key(&key_i)
572         .remote_public_key(&keypair_r.public)
573         .build_initiator()
574         .unwrap();
575 
576     let mut buffer_msg = [0u8; 65535];
577     let mut buffer_out = [0u8; 65535];
578     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
579     let res = h_r.read_message(&buffer_msg[..len], &mut buffer_out);
580 
581     assert!(res.is_ok());
582 
583     let len = h_r.write_message(b"abc", &mut buffer_msg).unwrap();
584     let res = h_i.read_message(&buffer_msg[..len], &mut buffer_out);
585 
586     assert!(res.is_ok());
587 
588     let _len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
589     let res = h_r.read_message(&buffer_msg[..2], &mut buffer_out);
590 
591     assert!(res.is_err());
592 }
593 
594 #[test]
test_buffer_issues_encrypted_handshake()595 fn test_buffer_issues_encrypted_handshake() {
596     let params: NoiseParams = "Noise_IKpsk2_25519_ChaChaPoly_SHA256".parse().unwrap();
597 
598     let b_i = Builder::new(params.clone());
599     let b_r = Builder::new(params);
600 
601     let static_i = b_i.generate_keypair().unwrap();
602     let static_r = b_r.generate_keypair().unwrap();
603 
604     let mut h_i = b_i
605         .psk(2, &[32u8; 32])
606         .local_private_key(&static_i.private)
607         .remote_public_key(&static_r.public)
608         .build_initiator()
609         .unwrap();
610     let mut h_r = b_r
611         .psk(2, &[32u8; 32])
612         .local_private_key(&static_r.private)
613         .remote_public_key(&static_i.public)
614         .build_responder()
615         .unwrap();
616 
617     let mut buffer_msg = [0u8; 200];
618     let mut buffer_out = [0u8; 2];
619     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
620     let res = h_r.read_message(&buffer_msg[..len], &mut buffer_out);
621 
622     assert!(res.is_err());
623 }
624 
625 #[test]
test_send_trait()626 fn test_send_trait() {
627     use std::{sync::mpsc::channel, thread};
628 
629     let (tx, rx) = channel();
630     thread::spawn(move || {
631         let session = Builder::new("Noise_NN_25519_ChaChaPoly_BLAKE2s".parse().unwrap())
632             .build_initiator()
633             .unwrap();
634         tx.send(session).unwrap();
635     });
636     let _session = rx.recv().expect("failed to receive noise session");
637 }
638 
639 #[test]
test_checkpointing()640 fn test_checkpointing() {
641     let params: NoiseParams = "Noise_XXpsk2_25519_ChaChaPoly_SHA256".parse().unwrap();
642 
643     let b_i = Builder::new(params.clone());
644     let b_r = Builder::new(params);
645 
646     let static_i = b_i.generate_keypair().unwrap();
647     let static_r = b_r.generate_keypair().unwrap();
648 
649     let mut h_i = b_i
650         .psk(2, &[32u8; 32])
651         .local_private_key(&static_i.private)
652         .remote_public_key(&static_r.public)
653         .build_initiator()
654         .unwrap();
655     let mut h_r = b_r
656         .psk(2, &[32u8; 32])
657         .local_private_key(&static_r.private)
658         .remote_public_key(&static_i.public)
659         .build_responder()
660         .unwrap();
661 
662     let mut buffer_msg = [0u8; 200];
663     let mut buffer_bad = [0u8; 48];
664 
665     let res = h_i.write_message(b"abc", &mut buffer_bad);
666     assert!(res.is_err(), "write_message() should have failed for insufficiently-sized buffer");
667 
668     let len = h_i
669         .write_message(b"abc", &mut buffer_msg)
670         .expect("write_message() should have succeeded for correctly-sized buffer");
671 
672     let mut buffer_bad = [0u8; 2];
673     let mut buffer_ok = [0u8; 200];
674     let res = h_r.read_message(&buffer_msg[..len], &mut buffer_bad);
675     assert!(res.is_err(), "read_message() should have failed for insufficiently-sized buffer");
676 
677     let _res = h_r
678         .read_message(&buffer_msg[..len], &mut buffer_ok)
679         .expect("read_message() should have succeeded");
680 }
681 
682 #[test]
test_get_remote_static()683 fn test_get_remote_static() {
684     let params: NoiseParams = "Noise_XX_25519_ChaChaPoly_SHA256".parse().unwrap();
685     let mut h_i =
686         Builder::new(params.clone()).local_private_key(&get_inc_key(0)).build_initiator().unwrap();
687     let mut h_r =
688         Builder::new(params).local_private_key(&get_inc_key(1)).build_responder().unwrap();
689 
690     let mut buf = [0u8; 1024];
691     let mut buf2 = [0u8; 1024];
692 
693     // XX(s, rs):
694     assert!(h_i.get_remote_static().is_none());
695     assert!(h_r.get_remote_static().is_none());
696 
697     // -> e
698     let len = h_i.write_message(&[], &mut buf).unwrap();
699     let _ = h_r.read_message(&buf[..len], &mut buf2).unwrap();
700 
701     assert!(h_i.get_remote_static().is_none());
702     assert!(h_r.get_remote_static().is_none());
703 
704     // <- e, ee s, es
705     let len = h_r.write_message(&[], &mut buf).unwrap();
706     let _ = h_i.read_message(&buf[..len], &mut buf2).unwrap();
707 
708     assert_eq!(
709         h_i.get_remote_static().unwrap(),
710         &x25519::x25519(get_inc_key(1), x25519::X25519_BASEPOINT_BYTES)
711     );
712     assert!(h_r.get_remote_static().is_none());
713 
714     // -> s, se
715     let len = h_i.write_message(&[], &mut buf).unwrap();
716     let _ = h_r.read_message(&buf[..len], &mut buf2).unwrap();
717 
718     assert_eq!(
719         h_i.get_remote_static().unwrap(),
720         &x25519::x25519(get_inc_key(1), x25519::X25519_BASEPOINT_BYTES)
721     );
722     assert_eq!(
723         h_r.get_remote_static().unwrap(),
724         &x25519::x25519(get_inc_key(0), x25519::X25519_BASEPOINT_BYTES)
725     );
726 }
727 
728 #[test]
test_set_psk()729 fn test_set_psk() {
730     let params: NoiseParams = "Noise_XXpsk3_25519_ChaChaPoly_SHA256".parse().unwrap();
731     let mut h_i =
732         Builder::new(params.clone()).local_private_key(&get_inc_key(0)).build_initiator().unwrap();
733     let mut h_r =
734         Builder::new(params).local_private_key(&get_inc_key(1)).build_responder().unwrap();
735 
736     let mut buf = [0u8; 1024];
737     let mut buf2 = [0u8; 1024];
738 
739     let psk = get_inc_key(3);
740 
741     // XX(s, rs):
742     // -> e
743     let len = h_i.write_message(&[], &mut buf).unwrap();
744     let _ = h_r.read_message(&buf[..len], &mut buf2).unwrap();
745 
746     // <- e, ee s, es
747     let len = h_r.write_message(&[], &mut buf).unwrap();
748     let _ = h_i.read_message(&buf[..len], &mut buf2).unwrap();
749 
750     h_i.set_psk(3, &psk).unwrap();
751     h_r.set_psk(3, &psk).unwrap();
752 
753     // -> s, se, psk
754     let len = h_i.write_message(&[], &mut buf).unwrap();
755     let _ = h_r.read_message(&buf[..len], &mut buf2).unwrap();
756 }
757 
758 #[test]
test_stateless_sanity_session()759 fn test_stateless_sanity_session() {
760     let params: NoiseParams = "Noise_NN_25519_ChaChaPoly_SHA256".parse().unwrap();
761     let mut h_i = Builder::new(params.clone()).build_initiator().unwrap();
762     let mut h_r = Builder::new(params).build_responder().unwrap();
763 
764     let mut buffer_msg = [0u8; 200];
765     let mut buffer_out = [0u8; 200];
766     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
767     h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
768 
769     let len = h_r.write_message(b"defg", &mut buffer_msg).unwrap();
770     h_i.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
771 
772     let h_i = h_i.into_stateless_transport_mode().unwrap();
773     let h_r = h_r.into_stateless_transport_mode().unwrap();
774 
775     let len = h_i.write_message(1337, b"hack the planet", &mut buffer_msg).unwrap();
776     let len = h_r.read_message(1337, &buffer_msg[..len], &mut buffer_out).unwrap();
777     assert_eq!(&buffer_out[..len], b"hack the planet");
778 }
779 
780 #[test]
test_handshake_read_oob_error()781 fn test_handshake_read_oob_error() {
782     let params: NoiseParams = "Noise_NN_25519_ChaChaPoly_SHA256".parse().unwrap();
783     let mut h_i = Builder::new(params.clone()).build_initiator().unwrap();
784     let mut h_r = Builder::new(params).build_responder().unwrap();
785 
786     let mut buffer_msg = [0u8; 200];
787     let mut buffer_out = [0u8; 200];
788     let len = h_i.write_message(b"abc", &mut buffer_msg).unwrap();
789     h_r.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
790 
791     let len = h_r.write_message(b"defg", &mut buffer_msg).unwrap();
792     h_i.read_message(&buffer_msg[..len], &mut buffer_out).unwrap();
793 
794     // This shouldn't panic, but it *should* return an error.
795     let _ = h_i.read_message(&buffer_msg[..len], &mut buffer_out);
796 }
797