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