use crate::{
noise::{stream::NoiseStream, AntiReplayTimestamps, HandshakeAuthMode, NoiseUpgrader},
testutils::fake_socket::{ReadOnlyTestSocket, ReadWriteTestSocket},
};
use aptos_config::network_id::NetworkContext;
use aptos_crypto::{noise::NoiseSession, test_utils::TEST_SEED, x25519, Uniform as _};
use aptos_types::PeerId;
use futures::{executor::block_on, future::join};
use futures_util::io::AsyncReadExt;
use once_cell::sync::Lazy;
use rand::SeedableRng;
pub static KEYPAIRS: Lazy<(
(x25519::PrivateKey, x25519::PublicKey, PeerId),
(x25519::PrivateKey, x25519::PublicKey, PeerId),
)> = Lazy::new(|| {
let mut rng = ::rand::rngs::StdRng::from_seed(TEST_SEED);
let initiator_private_key = x25519::PrivateKey::generate(&mut rng);
let initiator_public_key = initiator_private_key.public_key();
let initiator_peer_id =
aptos_types::account_address::from_identity_public_key(initiator_public_key);
let responder_private_key = x25519::PrivateKey::generate(&mut rng);
let responder_public_key = responder_private_key.public_key();
let responder_peer_id =
aptos_types::account_address::from_identity_public_key(responder_public_key);
(
(
initiator_private_key,
initiator_public_key,
initiator_peer_id,
),
(
responder_private_key,
responder_public_key,
responder_peer_id,
),
)
});
fn generate_first_two_messages() -> (Vec<u8>, Vec<u8>) {
let (
(initiator_private_key, initiator_public_key, initiator_peer_id),
(responder_private_key, responder_public_key, responder_peer_id),
) = KEYPAIRS.clone();
let initiator = NoiseUpgrader::new(
NetworkContext::mock_with_peer_id(initiator_peer_id),
initiator_private_key,
HandshakeAuthMode::server_only(),
);
let responder = NoiseUpgrader::new(
NetworkContext::mock_with_peer_id(responder_peer_id),
responder_private_key,
HandshakeAuthMode::server_only(),
);
let (mut initiator_socket, mut responder_socket) = ReadWriteTestSocket::new_pair();
let mut init_msg = Vec::new();
let mut resp_msg = Vec::new();
initiator_socket.save_writing(&mut init_msg);
responder_socket.save_writing(&mut resp_msg);
let (initiator_session, responder_session) = block_on(join(
initiator.upgrade_outbound(initiator_socket, responder_public_key, fake_timestamp),
responder.upgrade_inbound(responder_socket),
));
let initiator_session = initiator_session.unwrap();
let (responder_session, peer_id, _) = responder_session.unwrap();
assert_eq!(initiator_session.get_remote_static(), responder_public_key);
assert_eq!(responder_session.get_remote_static(), initiator_public_key);
assert_eq!(initiator_peer_id, peer_id);
(init_msg, resp_msg)
}
pub fn generate_corpus(gen: &mut aptos_proptest_helpers::ValueGenerator) -> Vec<u8> {
let (init_msg, resp_msg) = generate_first_two_messages();
let strategy = proptest::arbitrary::any::<bool>();
if gen.generate(strategy) {
init_msg
} else {
resp_msg
}
}
fn fake_timestamp() -> [u8; AntiReplayTimestamps::TIMESTAMP_SIZE] {
[0u8; AntiReplayTimestamps::TIMESTAMP_SIZE]
}
pub fn fuzz_initiator(data: &[u8]) {
let ((initiator_private_key, _, initiator_peer_id), (_, responder_public_key, _)) =
KEYPAIRS.clone();
let initiator = NoiseUpgrader::new(
NetworkContext::mock_with_peer_id(initiator_peer_id),
initiator_private_key,
HandshakeAuthMode::server_only(),
);
let mut fake_socket = ReadOnlyTestSocket::new(data);
fake_socket.set_trailing();
let _ = block_on(initiator.upgrade_outbound(fake_socket, responder_public_key, fake_timestamp));
}
pub fn fuzz_responder(data: &[u8]) {
let (_, (responder_private_key, _, responder_peer_id)) = KEYPAIRS.clone();
let responder = NoiseUpgrader::new(
NetworkContext::mock_with_peer_id(responder_peer_id),
responder_private_key,
HandshakeAuthMode::server_only(),
);
let mut fake_socket = ReadOnlyTestSocket::new(data);
fake_socket.set_trailing();
let _ = block_on(responder.upgrade_inbound(fake_socket));
}
pub fn fuzz_post_handshake(data: &[u8]) {
if data.is_empty() {
return;
}
let mut fake_socket = ReadOnlyTestSocket::new(data);
fake_socket.set_trailing();
let noise_session = NoiseSession::new_for_testing();
let mut peer = NoiseStream::new(fake_socket, noise_session);
let _ = block_on(async move {
let mut buffer = [0u8; 1024];
let _ = peer.read(&mut buffer).await;
});
}
#[test]
fn test_noise_fuzzers() {
let (init_msg, resp_msg) = generate_first_two_messages();
fuzz_responder(&init_msg);
fuzz_initiator(&resp_msg);
fuzz_post_handshake(&resp_msg);
}