#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
use crate::protocol::handshake::*;
use crate::protocol::message::Message;
use crate::utils::replay_cache::ReplayCache;
#[test]
fn test_secure_handshake_flow() {
let mut replay_cache = ReplayCache::new();
let peer_id = "test-peer";
let (client_state, init_msg) =
client_secure_handshake_init().expect("Client init should succeed");
let (client_pub_key, timestamp, client_nonce) = match &init_msg {
Message::SecureHandshakeInit {
pub_key,
nonce,
timestamp,
} => (*pub_key, *timestamp, *nonce),
_ => panic!("Expected SecureHandshakeInit message"),
};
let (server_state, server_response) = server_secure_handshake_response(
client_pub_key,
client_nonce,
timestamp,
peer_id,
&mut replay_cache,
)
.expect("Server response should succeed");
let (server_pub_key, server_nonce, nonce_verification) = match server_response {
Message::SecureHandshakeResponse {
pub_key,
nonce,
nonce_verification,
} => (pub_key, nonce, nonce_verification),
_ => panic!("Expected SecureHandshakeResponse message"),
};
let (client_state_verified, client_confirm) = client_secure_handshake_verify(
client_state,
server_pub_key,
server_nonce,
nonce_verification,
peer_id,
&mut replay_cache,
)
.expect("Client verification should succeed");
let confirmation_hash = match client_confirm {
Message::SecureHandshakeConfirm { nonce_verification } => nonce_verification,
_ => panic!("Expected SecureHandshakeConfirm message"),
};
let server_key = server_secure_handshake_finalize(server_state, confirmation_hash)
.expect("Server finalization should succeed");
let client_key = client_derive_session_key(client_state_verified)
.expect("Client should be able to derive session key");
assert_eq!(
server_key, client_key,
"Client and server session keys must match"
);
}
#[test]
fn test_replay_attack_prevention() {
let now_ms = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;
assert!(verify_timestamp(now_ms, 30));
let old_ts = now_ms - 31000; assert!(!verify_timestamp(old_ts, 30));
let future_ts = now_ms + 3000; assert!(!verify_timestamp(future_ts, 30));
let recent_ts = now_ms - 5000; assert!(verify_timestamp(recent_ts, 30));
}
#[test]
fn test_tampering_detection() {
let mut replay_cache = ReplayCache::new();
let peer_id = "test-peer";
let (_client_state, init_message) =
client_secure_handshake_init().expect("Client init should succeed");
let (client_pub_key, timestamp, client_nonce) = match init_message {
Message::SecureHandshakeInit {
pub_key,
timestamp,
nonce,
} => (pub_key, timestamp, nonce),
_ => panic!("Expected SecureHandshakeInit message"),
};
let (_server_state, server_response) = server_secure_handshake_response(
client_pub_key,
client_nonce,
timestamp,
peer_id,
&mut replay_cache,
)
.expect("Server response should succeed");
let (server_pub_key, server_nonce, _nonce_verification) = match server_response {
Message::SecureHandshakeResponse {
pub_key,
nonce,
nonce_verification,
} => (pub_key, nonce, nonce_verification),
_ => panic!("Expected SecureHandshakeResponse message"),
};
let tampered_nonce_verification = [0u8; 32];
let (client_state_fresh, _) =
client_secure_handshake_init().expect("Client init should succeed");
let result = client_secure_handshake_verify(
client_state_fresh,
server_pub_key,
server_nonce,
tampered_nonce_verification,
peer_id,
&mut replay_cache,
);
assert!(
result.is_err(),
"Verification should fail with tampered nonce hash"
);
}
#[test]
fn test_per_session_state_isolation() {
let mut replay_cache = ReplayCache::new();
let peer_id = "test-peer";
let (client1, msg1) = client_secure_handshake_init().unwrap();
let (client2, msg2) = client_secure_handshake_init().unwrap();
let (pub_key1, ts1, nonce1) = match msg1 {
Message::SecureHandshakeInit {
pub_key,
timestamp,
nonce,
} => (pub_key, timestamp, nonce),
_ => panic!("Wrong message type"),
};
let (pub_key2, ts2, nonce2) = match msg2 {
Message::SecureHandshakeInit {
pub_key,
timestamp,
nonce,
} => (pub_key, timestamp, nonce),
_ => panic!("Wrong message type"),
};
assert_ne!(pub_key1, pub_key2);
assert_ne!(nonce1, nonce2);
let (server1, resp1) =
server_secure_handshake_response(pub_key1, nonce1, ts1, peer_id, &mut replay_cache)
.unwrap();
let (server2, resp2) =
server_secure_handshake_response(pub_key2, nonce2, ts2, peer_id, &mut replay_cache)
.unwrap();
let (server_pub1, server_nonce1, verify1) = match resp1 {
Message::SecureHandshakeResponse {
pub_key,
nonce,
nonce_verification,
} => (pub_key, nonce, nonce_verification),
_ => panic!("Wrong message type"),
};
let (server_pub2, server_nonce2, verify2) = match resp2 {
Message::SecureHandshakeResponse {
pub_key,
nonce,
nonce_verification,
} => (pub_key, nonce, nonce_verification),
_ => panic!("Wrong message type"),
};
assert_ne!(server_pub1, server_pub2);
assert_ne!(server_nonce1, server_nonce2);
let (client1_verified, confirm1) = client_secure_handshake_verify(
client1,
server_pub1,
server_nonce1,
verify1,
peer_id,
&mut replay_cache,
)
.unwrap();
let (client2_verified, confirm2) = client_secure_handshake_verify(
client2,
server_pub2,
server_nonce2,
verify2,
peer_id,
&mut replay_cache,
)
.unwrap();
let confirm_hash1 = match confirm1 {
Message::SecureHandshakeConfirm { nonce_verification } => nonce_verification,
_ => panic!("Wrong message type"),
};
let confirm_hash2 = match confirm2 {
Message::SecureHandshakeConfirm { nonce_verification } => nonce_verification,
_ => panic!("Wrong message type"),
};
assert_ne!(confirm_hash1, confirm_hash2);
let key1_server = server_secure_handshake_finalize(server1, confirm_hash1).unwrap();
let key1_client = client_derive_session_key(client1_verified).unwrap();
let key2_server = server_secure_handshake_finalize(server2, confirm_hash2).unwrap();
let key2_client = client_derive_session_key(client2_verified).unwrap();
assert_eq!(key1_server, key1_client);
assert_eq!(key2_server, key2_client);
assert_ne!(key1_server, key2_server);
}
#[test]
#[allow(clippy::unwrap_used)]
fn test_nonce_uniqueness() {
let (_s1, msg1) = client_secure_handshake_init().unwrap();
let (_s2, msg2) = client_secure_handshake_init().unwrap();
let (_s3, msg3) = client_secure_handshake_init().unwrap();
let nonce1 = match msg1 {
Message::SecureHandshakeInit { nonce, .. } => nonce,
_ => unreachable!("Expected SecureHandshakeInit"),
};
let nonce2 = match msg2 {
Message::SecureHandshakeInit { nonce, .. } => nonce,
_ => unreachable!("Expected SecureHandshakeInit"),
};
let nonce3 = match msg3 {
Message::SecureHandshakeInit { nonce, .. } => nonce,
_ => unreachable!("Expected SecureHandshakeInit"),
};
assert_ne!(nonce1, nonce2);
assert_ne!(nonce2, nonce3);
assert_ne!(nonce1, nonce3);
}