Source code
Revision control
Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
//! Noise handshake tests.
use noise::*;
use nss_rs::ec::{ecdh_keygen, EcCurve};
/// Test KNpsk0 flow (QR-initiated transaction)
#[test]
fn qr_initiated() {
nss_rs::init().expect("nss_rs::init");
let initiator_identity = ecdh_keygen(&EcCurve::P256).expect("initiator_identity");
let initiator_pub = initiator_identity.public.key_data().expect("initiator_pub");
assert_eq!(65, initiator_pub.len());
assert_eq!(4, initiator_pub[0]);
let psk = nss_rs::random();
let initiator_hs = InitiatorHandshake::new_qr_initiated(&psk, initiator_identity)
.expect("initial_handshake_message");
let mut responder = Responder::new_qr_initiated(
&psk,
initiator_pub.as_slice().try_into().unwrap(),
initiator_hs.initial_message(),
)
.expect("build_responder");
let mut initiator = initiator_hs
.process_handshake_response(&responder.response_message)
.expect("process_handshake_response");
assert_eq!(responder.handshake_hash, initiator.handshake_hash);
// responder -> initiator
let msg = b"Hi initiator!";
let ct = responder.encrypt(msg).unwrap();
assert_ne!(msg, ct.as_slice());
let pt = initiator.decrypt(&ct).unwrap();
assert_eq!(msg, pt.as_slice());
// Decrypting the responder's message again should fail
assert!(initiator.decrypt(&ct).is_err());
// initiator -> responder
let msg = b"G'day, responder!";
let ct = initiator.encrypt(msg).unwrap();
assert_ne!(msg, ct.as_slice());
let pt = responder.decrypt(&ct).unwrap();
assert_eq!(msg, pt.as_slice());
// Decrypting the initiator's message again should fail
assert!(responder.decrypt(&ct).is_err());
}
/// Test NKpsk0 flow (state-assisted transaction)
#[test]
fn state_assisted() {
nss_rs::init().expect("nss_rs::init");
let initiator_identity = ecdh_keygen(&EcCurve::P256).expect("initiator_identity");
let initiator_pub = initiator_identity.public.key_data().expect("initiator_pub");
assert_eq!(65, initiator_pub.len());
assert_eq!(4, initiator_pub[0]);
let responder_identity = ecdh_keygen(&EcCurve::P256).expect("responder_identity");
let responder_pub = responder_identity.public.key_data().expect("responder_pub");
assert_eq!(65, responder_pub.len());
assert_eq!(4, responder_pub[0]);
let psk = nss_rs::random();
let initiator_hs =
InitiatorHandshake::new_state_assisted(&psk, responder_pub.as_slice().try_into().unwrap())
.expect("initial_handshake_message");
let mut responder =
Responder::new_state_assisted(&psk, responder_identity, initiator_hs.initial_message())
.expect("build_responder");
let mut initiator = initiator_hs
.process_handshake_response(&responder.response_message)
.expect("process_handshake_response");
assert_eq!(responder.handshake_hash, initiator.handshake_hash);
// responder -> initiator
let msg = b"Hi initiator!";
let ct = responder.encrypt(msg).unwrap();
assert_ne!(msg, ct.as_slice());
let pt = initiator.decrypt(&ct).unwrap();
assert_eq!(msg, pt.as_slice());
// initiator -> responder
let msg = b"G'day, responder!";
let ct = initiator.encrypt(msg).unwrap();
assert_ne!(msg, ct.as_slice());
let pt = responder.decrypt(&ct).unwrap();
assert_eq!(msg, pt.as_slice());
}
/// Test incorrect psk flows
#[test]
fn errors() {
nss_rs::init().expect("nss_rs::init");
let initiator_identity = ecdh_keygen(&EcCurve::P256).expect("initiator_identity");
let initiator_pub: [u8; 65] = initiator_identity
.public
.key_data()
.expect("initiator_pub")
.try_into()
.unwrap();
assert_eq!(4, initiator_pub[0]);
let responder_identity = ecdh_keygen(&EcCurve::P256).expect("responder_identity");
let responder_pub: [u8; 65] = responder_identity
.public
.key_data()
.expect("responder_pub")
.try_into()
.unwrap();
assert_eq!(4, responder_pub[0]);
let psk = nss_rs::random();
let initiator_hs = InitiatorHandshake::new_qr_initiated(&psk, initiator_identity)
.expect("initial_handshake_message");
// Invalid initiator message
assert_eq!(
true,
Responder::new_qr_initiated(&psk, &initiator_pub, &initiator_hs.initial_message()[..64],)
.is_err()
);
// Set invalid point form
let mut initiator_msg = initiator_hs.initial_message().clone();
assert_eq!(4, initiator_msg[0]);
initiator_msg[0] = 1;
assert_eq!(
true,
Responder::new_qr_initiated(&psk, &initiator_pub, &initiator_msg).is_err()
);
// Reset point form
initiator_msg[0] = 4;
let responder =
Responder::new_qr_initiated(&psk, &initiator_pub, &initiator_msg).expect("build_responder");
// Return an incorrect responder message.
// We can only do this once, because process_handshake_response mutates internal state.
let mut responder_msg = responder.response_message.clone();
// Set invalid point form
assert_eq!(4, responder_msg[0]);
responder_msg[0] = 1;
assert_eq!(
true,
initiator_hs
.process_handshake_response(&responder_msg)
.is_err()
);
}