use super::*;
#[test]
fn test_replay_window_basic() {
let mut window = ReplayWindow::new();
assert_eq!(window.rejection_reason(0), None);
assert!(window.check(0));
window.accept(0);
assert_eq!(window.highest(), 0);
assert_eq!(window.rejection_reason(0), Some(ReplayRejection::Duplicate));
assert!(!window.check(0));
assert!(window.check(1));
window.accept(1);
assert_eq!(window.highest(), 1);
window.accept(10);
assert!(window.check(5));
window.accept(5);
assert_eq!(window.rejection_reason(5), Some(ReplayRejection::Duplicate));
assert!(!window.check(5));
}
#[test]
fn test_replay_window_large_jump() {
let mut window = ReplayWindow::new();
window.accept(0);
window.accept(REPLAY_WINDOW_SIZE as u64 + 100);
assert_eq!(window.rejection_reason(0), Some(ReplayRejection::TooOld));
assert!(!window.check(0));
assert_eq!(window.rejection_reason(50), Some(ReplayRejection::TooOld));
assert!(!window.check(50));
assert_eq!(
window.rejection_reason(REPLAY_WINDOW_SIZE as u64 + 99),
None
);
assert!(window.check(REPLAY_WINDOW_SIZE as u64 + 99));
assert!(window.check(REPLAY_WINDOW_SIZE as u64 + 50));
}
#[test]
fn test_replay_window_boundary() {
let mut window = ReplayWindow::new();
window.accept(REPLAY_WINDOW_SIZE as u64 - 1);
assert!(window.check(0));
window.accept(0);
window.accept(REPLAY_WINDOW_SIZE as u64);
assert!(!window.check(0));
assert!(window.check(1));
}
#[test]
fn test_replay_window_sequential() {
let mut window = ReplayWindow::new();
for i in 0..1000 {
assert!(window.check(i), "Counter {} should be acceptable", i);
window.accept(i);
}
for i in 0..1000 {
assert!(
!window.check(i),
"Counter {} should be rejected as replay",
i
);
}
assert_eq!(window.highest(), 999);
}
#[test]
fn test_replay_window_reset() {
let mut window = ReplayWindow::new();
window.accept(100);
assert_eq!(window.highest(), 100);
assert!(!window.check(100));
window.reset();
assert_eq!(window.highest(), 0);
assert!(window.check(100));
}
#[test]
fn test_session_replay_protection() {
let keypair1 = generate_keypair();
let keypair2 = generate_keypair();
let mut init = HandshakeState::new_initiator(keypair1, keypair2.public_key());
init.set_local_epoch(generate_epoch());
let mut resp = HandshakeState::new_responder(keypair2);
resp.set_local_epoch(generate_epoch());
let msg1 = init.write_message_1().unwrap();
resp.read_message_1(&msg1).unwrap();
let msg2 = resp.write_message_2().unwrap();
init.read_message_2(&msg2).unwrap();
let mut sender = init.into_session().unwrap();
let mut receiver = resp.into_session().unwrap();
let counter = sender.current_send_counter();
let ciphertext = sender.encrypt(b"test message").unwrap();
let plaintext = receiver
.decrypt_with_replay_check(&ciphertext, counter)
.unwrap();
assert_eq!(plaintext, b"test message");
let result = receiver.decrypt_with_replay_check(&ciphertext, counter);
assert!(matches!(result, Err(NoiseError::ReplayDetected(_))));
assert!(receiver.check_replay(counter).is_err());
}