Skip to content

Commit

Permalink
Add a failing test with post quantum key exchange
Browse files Browse the repository at this point in the history
  • Loading branch information
stormshield-gt committed Oct 28, 2024
1 parent 6051c30 commit a6cc784
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 6 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ rustc-hash = "2"
rustls = { version = "0.23.5", default-features = false, features = ["std"] }
rustls-pemfile = "2"
rustls-platform-verifier = "0.3"
rustls-post-quantum = "0.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1"
slab = "0.4.6"
Expand Down
1 change: 1 addition & 0 deletions quinn/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ directories-next = { workspace = true }
rand = { workspace = true }
rcgen = { workspace = true }
rustls-pemfile = { workspace = true }
rustls-post-quantum = { workspace = true }
clap = { workspace = true }
tokio = { workspace = true, features = ["rt", "rt-multi-thread", "time", "macros"] }
tracing-subscriber = { workspace = true }
Expand Down
10 changes: 4 additions & 6 deletions quinn/tests/many_connections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ struct Shared {
#[test]
#[ignore]
fn connect_n_nodes_to_1_and_send_1mb_data() {
tracing::subscriber::set_global_default(
tracing_subscriber::FmtSubscriber::builder()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.finish(),
)
.unwrap();
let _ = tracing_subscriber::FmtSubscriber::builder()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.with_test_writer()
.try_init();

let runtime = Builder::new_current_thread().enable_all().build().unwrap();
let _guard = runtime.enter();
Expand Down
109 changes: 109 additions & 0 deletions quinn/tests/post_quantum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#![cfg(feature = "rustls-aws-lc-rs")]
use quinn::{
crypto::rustls::{HandshakeData, QuicClientConfig, QuicServerConfig},
Endpoint,
};
use rustls::{
pki_types::{CertificateDer, PrivatePkcs8KeyDer},
NamedGroup,
};
use std::{
error::Error,
net::{Ipv4Addr, SocketAddr},
sync::Arc,
};
use tracing::info;

#[tokio::test]
async fn post_quantum_key_exchange() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
let _ = tracing_subscriber::FmtSubscriber::builder()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.with_test_writer()
.try_init();

rustls_post_quantum::provider().install_default().unwrap();
let server_addr = (Ipv4Addr::LOCALHOST, 8080).into();

let (endpoint, server_cert) = make_server_endpoint(server_addr)?;
// accept a single connection
tokio::spawn(async move {
let incoming_conn = endpoint.accept().await.unwrap();
let conn = incoming_conn.await.unwrap();
info!(
"[server] connection accepted: addr={}",
conn.remote_address()
);
assert_eq!(
conn.handshake_data()
.unwrap()
.downcast::<HandshakeData>()
.unwrap()
.negociated_key_exchange_group,
X25519_KYBER768_DRAFT00
)
// Dropping all handles associated with a connection implicitly closes it
});

let endpoint = make_client_endpoint((Ipv4Addr::UNSPECIFIED, 0).into(), &[&server_cert])?;
// connect to server
let connection = endpoint
.connect(server_addr, "localhost")
.unwrap()
.await
.unwrap();
info!("[client] connected: addr={}", connection.remote_address());

// Waiting for a stream will complete with an error when the server closes the connection
let _ = connection.accept_uni().await;

// Make sure the server has a chance to clean up
endpoint.wait_idle().await;

Ok(())
}

fn make_client_endpoint(
bind_addr: SocketAddr,
server_certs: &[&[u8]],
) -> Result<Endpoint, Box<dyn Error + Send + Sync + 'static>> {
let mut certs = rustls::RootCertStore::empty();
for cert in server_certs {
certs.add(CertificateDer::from(*cert))?;
}
let rustls_config = rustls::ClientConfig::builder()
.with_root_certificates(certs)
.with_no_client_auth();

let client_cfg =
quinn::ClientConfig::new(Arc::new(QuicClientConfig::try_from(rustls_config).unwrap()));
let mut endpoint = Endpoint::client(bind_addr)?;
endpoint.set_default_client_config(client_cfg);
Ok(endpoint)
}

fn make_server_endpoint(
bind_addr: SocketAddr,
) -> Result<(Endpoint, CertificateDer<'static>), Box<dyn Error + Send + Sync + 'static>> {
let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
let server_cert = CertificateDer::from(cert.cert);
let priv_key = PrivatePkcs8KeyDer::from(cert.key_pair.serialize_der());
let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(
QuicServerConfig::try_from(
rustls::ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(vec![server_cert.clone()], priv_key.into())
.unwrap(),
)
.unwrap(),
));

let transport_config = Arc::get_mut(&mut server_config.transport).unwrap();
transport_config.max_concurrent_uni_streams(0_u8.into());
transport_config.min_mtu(1274);

let endpoint = Endpoint::server(server_config, bind_addr)?;
Ok((endpoint, server_cert))
}

/// <https://datatracker.ietf.org/doc/html/draft-tls-westerbaan-xyber768d00-02#name-iana-considerations-23>
const X25519_KYBER768_DRAFT00: NamedGroup = NamedGroup::Unknown(0x06399);

0 comments on commit a6cc784

Please sign in to comment.