68 lines
3.8 KiB
Rust
68 lines
3.8 KiB
Rust
// file: crates/common/game-realtime-webtransport-lib/tests/establishment.rs
|
|
// version: 1
|
|
|
|
//! Deterministic native loopback proof for WebTransport session establishment and SHA-256 pinning.
|
|
|
|
const TEST_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5);
|
|
|
|
#[tokio::test(flavor = "current_thread")]
|
|
async fn pinned_client_and_server_establish_a_loopback_session() {
|
|
let identity = match game_realtime_webtransport_lib::WebTransportServerIdentity::generate_loopback() {
|
|
Ok(value) => value,
|
|
Err(error) => panic!("loopback identity generation failed: {error}"),
|
|
};
|
|
let certificate_hash = identity.certificate_hash().clone();
|
|
let server_config = game_realtime_webtransport_lib::WebTransportServerConfig::new(std::net::SocketAddr::from(([127, 0, 0, 1], 0)), identity);
|
|
let mut listener = match game_realtime_webtransport_lib::WebTransportListener::bind(server_config) {
|
|
Ok(value) => value,
|
|
Err(error) => panic!("WebTransport listener bind failed: {error}"),
|
|
};
|
|
let endpoint = format!("https://{}/establishment", listener.local_addr());
|
|
let client_config = match game_realtime_webtransport_lib::WebTransportClientConfig::new(endpoint.as_str(), certificate_hash) {
|
|
Ok(value) => value,
|
|
Err(error) => panic!("WebTransport client configuration failed: {error}"),
|
|
};
|
|
let pair = tokio::time::timeout(TEST_TIMEOUT, async {
|
|
return tokio::join!(listener.accept(), game_realtime_webtransport_lib::connect(&client_config));
|
|
})
|
|
.await;
|
|
let (server_session, client_session) = match pair {
|
|
Ok((Ok(server), Ok(client))) => (server, client),
|
|
Ok((Err(error), _)) => panic!("WebTransport server establishment failed: {error}"),
|
|
Ok((_, Err(error))) => panic!("WebTransport client establishment failed: {error}"),
|
|
Err(_) => panic!("WebTransport loopback establishment timed out"),
|
|
};
|
|
assert_eq!(client_session.request_url(), Some(endpoint.as_str()));
|
|
assert_eq!(server_session.request_url(), Some(endpoint.as_str()));
|
|
assert_eq!(client_session.remote_addr(), listener.local_addr());
|
|
}
|
|
|
|
#[tokio::test(flavor = "current_thread")]
|
|
async fn incorrect_certificate_pin_rejects_establishment() {
|
|
let identity = match game_realtime_webtransport_lib::WebTransportServerIdentity::generate_loopback() {
|
|
Ok(value) => value,
|
|
Err(error) => panic!("loopback identity generation failed: {error}"),
|
|
};
|
|
let server_config = game_realtime_webtransport_lib::WebTransportServerConfig::new(std::net::SocketAddr::from(([127, 0, 0, 1], 0)), identity);
|
|
let mut listener = match game_realtime_webtransport_lib::WebTransportListener::bind(server_config) {
|
|
Ok(value) => value,
|
|
Err(error) => panic!("WebTransport listener bind failed: {error}"),
|
|
};
|
|
let endpoint = format!("https://{}/wrong-pin", listener.local_addr());
|
|
let wrong_hash = game_realtime_webtransport_lib::WebTransportCertificateHash::from_sha256([0_u8; 32]);
|
|
let client_config = match game_realtime_webtransport_lib::WebTransportClientConfig::new(endpoint.as_str(), wrong_hash) {
|
|
Ok(value) => value,
|
|
Err(error) => panic!("WebTransport client configuration failed: {error}"),
|
|
};
|
|
let (server_result, client_result) = tokio::join!(
|
|
tokio::time::timeout(TEST_TIMEOUT, listener.accept()),
|
|
tokio::time::timeout(TEST_TIMEOUT, game_realtime_webtransport_lib::connect(&client_config)),
|
|
);
|
|
match client_result {
|
|
Ok(Ok(_)) => panic!("WebTransport establishment unexpectedly accepted an incorrect certificate pin"),
|
|
Ok(Err(error)) => assert_eq!(error.kind(), game_realtime_transport_lib::TransportErrorKind::Connect),
|
|
Err(_) => panic!("incorrect-pin connection attempt timed out"),
|
|
}
|
|
assert!(matches!(server_result, Err(_) | Ok(Err(_))));
|
|
}
|