Skip to content

Commit 140d753

Browse files
Add a failing tests for post-quantum key exchange with severals min MTU
1 parent ee737de commit 140d753

File tree

4 files changed

+124
-6
lines changed

4 files changed

+124
-6
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ rustc-hash = "2"
3737
rustls = { version = "0.23.5", default-features = false, features = ["std"] }
3838
rustls-pemfile = "2"
3939
rustls-platform-verifier = "0.4"
40+
rustls-post-quantum = "0.1"
4041
serde = { version = "1.0", features = ["derive"] }
4142
serde_json = "1"
4243
slab = "0.4.6"

quinn/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ directories-next = { workspace = true }
6464
rand = { workspace = true }
6565
rcgen = { workspace = true }
6666
rustls-pemfile = { workspace = true }
67+
rustls-post-quantum = { workspace = true }
6768
clap = { workspace = true }
6869
tokio = { workspace = true, features = ["rt", "rt-multi-thread", "time", "macros"] }
6970
tracing-subscriber = { workspace = true }

quinn/tests/many_connections.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,10 @@ struct Shared {
1919
#[test]
2020
#[ignore]
2121
fn connect_n_nodes_to_1_and_send_1mb_data() {
22-
tracing::subscriber::set_global_default(
23-
tracing_subscriber::FmtSubscriber::builder()
24-
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
25-
.finish(),
26-
)
27-
.unwrap();
22+
let _ = tracing_subscriber::FmtSubscriber::builder()
23+
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
24+
.with_test_writer()
25+
.try_init();
2826

2927
let runtime = Builder::new_current_thread().enable_all().build().unwrap();
3028
let _guard = runtime.enter();

quinn/tests/post_quantum.rs

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#![cfg(feature = "rustls-aws-lc-rs")]
2+
use quinn::{
3+
crypto::rustls::{HandshakeData, QuicClientConfig, QuicServerConfig},
4+
Endpoint,
5+
};
6+
use rustls::{
7+
pki_types::{CertificateDer, PrivatePkcs8KeyDer},
8+
NamedGroup,
9+
};
10+
use std::{
11+
error::Error,
12+
net::{Ipv4Addr, SocketAddr},
13+
sync::Arc,
14+
};
15+
use tracing::info;
16+
17+
#[tokio::test]
18+
async fn post_quantum_key_worse_case_header() {
19+
check_post_quantum_key_exchange(1274).await;
20+
}
21+
22+
#[tokio::test]
23+
async fn post_quantum_key_exchange_large_mtu() {
24+
check_post_quantum_key_exchange(1400).await;
25+
}
26+
27+
async fn check_post_quantum_key_exchange(min_mtu: u16) {
28+
let _ = tracing_subscriber::FmtSubscriber::builder()
29+
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
30+
.with_test_writer()
31+
.try_init();
32+
33+
rustls_post_quantum::provider().install_default().unwrap();
34+
let server_addr = (Ipv4Addr::LOCALHOST, 8080).into();
35+
36+
let (endpoint, server_cert) = make_server_endpoint(server_addr, min_mtu).unwrap();
37+
// accept a single connection
38+
tokio::spawn(async move {
39+
let incoming_conn = endpoint.accept().await.unwrap();
40+
let conn = incoming_conn.await.unwrap();
41+
info!(
42+
"[server] connection accepted: addr={}",
43+
conn.remote_address()
44+
);
45+
assert_eq!(
46+
conn.handshake_data()
47+
.unwrap()
48+
.downcast::<HandshakeData>()
49+
.unwrap()
50+
.negotiated_key_exchange_group,
51+
X25519_KYBER768_DRAFT00
52+
)
53+
// Dropping all handles associated with a connection implicitly closes it
54+
});
55+
56+
let endpoint =
57+
make_client_endpoint((Ipv4Addr::UNSPECIFIED, 0).into(), &[&server_cert]).unwrap();
58+
// connect to server
59+
let connection = endpoint
60+
.connect(server_addr, "localhost")
61+
.unwrap()
62+
.await
63+
.unwrap();
64+
info!("[client] connected: addr={}", connection.remote_address());
65+
66+
// Waiting for a stream will complete with an error when the server closes the connection
67+
let _ = connection.accept_uni().await;
68+
69+
// Make sure the server has a chance to clean up
70+
endpoint.wait_idle().await;
71+
}
72+
73+
fn make_client_endpoint(
74+
bind_addr: SocketAddr,
75+
server_certs: &[&[u8]],
76+
) -> Result<Endpoint, Box<dyn Error + Send + Sync + 'static>> {
77+
let mut certs = rustls::RootCertStore::empty();
78+
for cert in server_certs {
79+
certs.add(CertificateDer::from(*cert))?;
80+
}
81+
let rustls_config = rustls::ClientConfig::builder()
82+
.with_root_certificates(certs)
83+
.with_no_client_auth();
84+
85+
let client_cfg =
86+
quinn::ClientConfig::new(Arc::new(QuicClientConfig::try_from(rustls_config).unwrap()));
87+
let mut endpoint = Endpoint::client(bind_addr)?;
88+
endpoint.set_default_client_config(client_cfg);
89+
Ok(endpoint)
90+
}
91+
92+
fn make_server_endpoint(
93+
bind_addr: SocketAddr,
94+
min_mtu: u16,
95+
) -> Result<(Endpoint, CertificateDer<'static>), Box<dyn Error + Send + Sync + 'static>> {
96+
let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
97+
let server_cert = CertificateDer::from(cert.cert);
98+
let priv_key = PrivatePkcs8KeyDer::from(cert.key_pair.serialize_der());
99+
let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(
100+
QuicServerConfig::try_from(
101+
rustls::ServerConfig::builder()
102+
.with_no_client_auth()
103+
.with_single_cert(vec![server_cert.clone()], priv_key.into())
104+
.unwrap(),
105+
)
106+
.unwrap(),
107+
));
108+
109+
let transport_config = Arc::get_mut(&mut server_config.transport).unwrap();
110+
transport_config.max_concurrent_uni_streams(0_u8.into());
111+
transport_config.min_mtu(min_mtu);
112+
113+
let endpoint = Endpoint::server(server_config, bind_addr)?;
114+
Ok((endpoint, server_cert))
115+
}
116+
117+
/// <https://datatracker.ietf.org/doc/html/draft-tls-westerbaan-xyber768d00-02#name-iana-considerations-23>
118+
const X25519_KYBER768_DRAFT00: NamedGroup = NamedGroup::Unknown(0x06399);

0 commit comments

Comments
 (0)