Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update rustls to 0.23 and ring to 0.17 #1715

Merged
merged 12 commits into from
Apr 22, 2024
4 changes: 2 additions & 2 deletions bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ anyhow = "1.0.22"
bytes = "1"
hdrhistogram = { version = "7.2", default-features = false }
quinn = { path = "../quinn" }
rcgen = "0.12.0"
rustls = { version = "0.21.0", default-features = false, features = ["quic"] }
rcgen = "0.13"
rustls = { version = "0.23", default-features = false, features = ["ring", "std"] }
clap = { version = "4", features = ["derive"] }
tokio = { version = "1.0.1", features = ["rt", "sync"] }
tracing = "0.1.10"
Expand Down
9 changes: 5 additions & 4 deletions bench/src/bin/bulk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{

use anyhow::{Context, Result};
use clap::Parser;
use rustls::pki_types::{CertificateDer, PrivatePkcs8KeyDer};
use tokio::sync::Semaphore;
use tracing::{info, trace};

Expand All @@ -21,14 +22,14 @@ fn main() {
configure_tracing_subscriber();

let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
let key = rustls::PrivateKey(cert.serialize_private_key_der());
let cert = rustls::Certificate(cert.serialize_der().unwrap());
let key = PrivatePkcs8KeyDer::from(cert.key_pair.serialize_der());
let cert = CertificateDer::from(cert.cert);

let server_span = tracing::error_span!("server");
let runtime = rt();
let (server_addr, endpoint) = {
let _guard = server_span.enter();
server_endpoint(&runtime, cert.clone(), key, &opt)
server_endpoint(&runtime, cert.clone(), key.into(), &opt)
};

let server_thread = std::thread::spawn(move || {
Expand Down Expand Up @@ -111,7 +112,7 @@ async fn server(endpoint: quinn::Endpoint, opt: Opt) -> Result<()> {

async fn client(
server_addr: SocketAddr,
server_cert: rustls::Certificate,
server_cert: CertificateDer<'static>,
opt: Opt,
) -> Result<ClientStats> {
let (endpoint, connection) = connect_client(server_addr, server_cert, opt).await?;
Expand Down
34 changes: 22 additions & 12 deletions bench/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ use std::{
use anyhow::{Context, Result};
use bytes::Bytes;
use clap::Parser;
use rustls::RootCertStore;
use quinn::crypto::rustls::QuicClientConfig;
use rustls::{
pki_types::{CertificateDer, PrivateKeyDer},
RootCertStore,
};
use tokio::runtime::{Builder, Runtime};
use tracing::trace;

Expand All @@ -27,8 +31,8 @@ pub fn configure_tracing_subscriber() {
/// Creates a server endpoint which runs on the given runtime
pub fn server_endpoint(
rt: &tokio::runtime::Runtime,
cert: rustls::Certificate,
key: rustls::PrivateKey,
cert: CertificateDer<'static>,
key: PrivateKeyDer<'static>,
opt: &Opt,
) -> (SocketAddr, quinn::Endpoint) {
let cert_chain = vec![cert];
Expand All @@ -50,23 +54,28 @@ pub fn server_endpoint(
/// Create a client endpoint and client connection
pub async fn connect_client(
server_addr: SocketAddr,
server_cert: rustls::Certificate,
server_cert: CertificateDer<'_>,
opt: Opt,
) -> Result<(quinn::Endpoint, quinn::Connection)> {
let endpoint =
quinn::Endpoint::client(SocketAddr::new(IpAddr::V6(Ipv6Addr::LOCALHOST), 0)).unwrap();

let mut roots = RootCertStore::empty();
roots.add(&server_cert)?;
let crypto = rustls::ClientConfig::builder()
.with_cipher_suites(&[opt.cipher.as_rustls()])
.with_safe_default_kx_groups()
roots.add(server_cert)?;

let default_provider = rustls::crypto::ring::default_provider();
let provider = rustls::crypto::CryptoProvider {
cipher_suites: vec![opt.cipher.as_rustls()],
..default_provider
};

let crypto = rustls::ClientConfig::builder_with_provider(provider.into())
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_root_certificates(roots)
.with_no_client_auth();

let mut client_config = quinn::ClientConfig::new(Arc::new(crypto));
let mut client_config = quinn::ClientConfig::new(Arc::new(QuicClientConfig::try_from(crypto)?));
client_config.transport_config(Arc::new(transport_config(&opt)));

let connection = endpoint
Expand Down Expand Up @@ -223,10 +232,11 @@ pub enum CipherSuite {

impl CipherSuite {
pub fn as_rustls(self) -> rustls::SupportedCipherSuite {
use rustls::crypto::ring::cipher_suite;
match self {
CipherSuite::Aes128 => rustls::cipher_suite::TLS13_AES_128_GCM_SHA256,
CipherSuite::Aes256 => rustls::cipher_suite::TLS13_AES_256_GCM_SHA384,
CipherSuite::Chacha20 => rustls::cipher_suite::TLS13_CHACHA20_POLY1305_SHA256,
CipherSuite::Aes128 => cipher_suite::TLS13_AES_128_GCM_SHA256,
CipherSuite::Aes256 => cipher_suite::TLS13_AES_256_GCM_SHA384,
CipherSuite::Chacha20 => cipher_suite::TLS13_CHACHA20_POLY1305_SHA256,
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions perf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ anyhow = "1.0.22"
hdrhistogram = { version = "7.2", default-features = false }
quinn = { path = "../quinn" }
quinn-proto = { path = "../quinn-proto" }
rcgen = "0.12.0"
rustls = { version = "0.21.0", default-features = false, features = ["dangerous_configuration"] }
rustls-pemfile = "1.0.0"
rcgen = "0.13"
rustls = { version = "0.23", default-features = false, features = ["ring", "std"] }
rustls-pemfile = "2"
serde = { version = "1.0", features = ["derive"], optional = true }
serde_json = { version = "1.0", optional = true }
socket2 = "0.5"
Expand Down
86 changes: 62 additions & 24 deletions perf/src/bin/perf_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use std::{
use anyhow::{Context, Result};
use bytes::Bytes;
use clap::Parser;
use quinn::TokioRuntime;
use quinn::{crypto::rustls::QuicClientConfig, TokioRuntime};
use rustls::pki_types::{CertificateDer, ServerName, UnixTime};
use tokio::sync::Semaphore;
use tracing::{debug, error, info};

Expand Down Expand Up @@ -115,12 +116,17 @@ async fn run(opt: Opt) -> Result<()> {

let endpoint = quinn::Endpoint::new(Default::default(), None, socket, Arc::new(TokioRuntime))?;

let mut crypto = rustls::ClientConfig::builder()
.with_cipher_suites(perf::PERF_CIPHER_SUITES)
.with_safe_default_kx_groups()
let default_provider = rustls::crypto::ring::default_provider();
let provider = Arc::new(rustls::crypto::CryptoProvider {
cipher_suites: perf::PERF_CIPHER_SUITES.into(),
..default_provider
});

let mut crypto = rustls::ClientConfig::builder_with_provider(provider.clone())
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_custom_certificate_verifier(SkipServerVerification::new())
.dangerous()
.with_custom_certificate_verifier(SkipServerVerification::new(provider))
.with_no_client_auth();
crypto.alpn_protocols = vec![b"perf".to_vec()];

Expand All @@ -131,17 +137,17 @@ async fn run(opt: Opt) -> Result<()> {
let mut transport = quinn::TransportConfig::default();
transport.initial_mtu(opt.initial_mtu);

let mut cfg = if opt.no_protection {
quinn::ClientConfig::new(Arc::new(NoProtectionClientConfig::new(Arc::new(crypto))))
} else {
quinn::ClientConfig::new(Arc::new(crypto))
};
cfg.transport_config(Arc::new(transport));
let crypto = Arc::new(QuicClientConfig::try_from(crypto)?);
let mut config = quinn::ClientConfig::new(match opt.no_protection {
true => Arc::new(NoProtectionClientConfig::new(crypto)),
false => crypto,
});
config.transport_config(Arc::new(transport));

let stream_stats = OpenStreamStats::default();

let connection = endpoint
.connect_with(cfg, addr, host_name)?
.connect_with(config, addr, host_name)?
.await
.context("connecting")?;

Expand Down Expand Up @@ -355,24 +361,56 @@ async fn request_bi(
Ok(())
}

struct SkipServerVerification;
#[derive(Debug)]
struct SkipServerVerification(Arc<rustls::crypto::CryptoProvider>);

impl SkipServerVerification {
fn new() -> Arc<Self> {
Arc::new(Self)
fn new(provider: Arc<rustls::crypto::CryptoProvider>) -> Arc<Self> {
Arc::new(Self(provider))
}
}

impl rustls::client::ServerCertVerifier for SkipServerVerification {
impl rustls::client::danger::ServerCertVerifier for SkipServerVerification {
fn verify_server_cert(
&self,
_end_entity: &rustls::Certificate,
_intermediates: &[rustls::Certificate],
_server_name: &rustls::ServerName,
_scts: &mut dyn Iterator<Item = &[u8]>,
_ocsp_response: &[u8],
_now: std::time::SystemTime,
) -> Result<rustls::client::ServerCertVerified, rustls::Error> {
Ok(rustls::client::ServerCertVerified::assertion())
_end_entity: &CertificateDer<'_>,
_intermediates: &[CertificateDer<'_>],
_server_name: &ServerName<'_>,
_ocsp: &[u8],
_now: UnixTime,
) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
Ok(rustls::client::danger::ServerCertVerified::assertion())
}

fn verify_tls12_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
rustls::crypto::verify_tls12_signature(
message,
cert,
dss,
&self.0.signature_verification_algorithms,
)
}

fn verify_tls13_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
rustls::crypto::verify_tls13_signature(
message,
cert,
dss,
&self.0.signature_verification_algorithms,
)
}

fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
self.0.signature_verification_algorithms.supported_schemes()
}
}
48 changes: 26 additions & 22 deletions perf/src/bin/perf_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ use std::{fs, net::SocketAddr, path::PathBuf, sync::Arc, time::Duration};
use anyhow::{Context, Result};
use bytes::Bytes;
use clap::Parser;
use quinn::TokioRuntime;
use quinn::{crypto::rustls::QuicServerConfig, TokioRuntime};
use rustls::pki_types::{CertificateDer, PrivatePkcs8KeyDer};
use tracing::{debug, error, info};

use perf::{bind_socket, noprotection::NoProtectionServerConfig};
use perf::{bind_socket, noprotection::NoProtectionServerConfig, PERF_CIPHER_SUITES};

#[derive(Parser)]
#[clap(name = "server")]
Expand Down Expand Up @@ -56,30 +57,33 @@ async fn run(opt: Opt) -> Result<()> {
(Some(key), Some(cert)) => {
let key = fs::read(key).context("reading key")?;
let cert = fs::read(cert).expect("reading cert");

let mut certs = Vec::new();
for cert in rustls_pemfile::certs(&mut cert.as_ref()).context("parsing cert")? {
certs.push(rustls::Certificate(cert));
}

(rustls::PrivateKey(key), certs)
(
PrivatePkcs8KeyDer::from(key),
rustls_pemfile::certs(&mut cert.as_ref())
.collect::<Result<_, _>>()
.context("parsing cert")?,
)
}
_ => {
let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
(
rustls::PrivateKey(cert.serialize_private_key_der()),
vec![rustls::Certificate(cert.serialize_der().unwrap())],
PrivatePkcs8KeyDer::from(cert.key_pair.serialize_der()),
vec![CertificateDer::from(cert.cert)],
)
}
};

let mut crypto = rustls::ServerConfig::builder()
.with_cipher_suites(perf::PERF_CIPHER_SUITES)
.with_safe_default_kx_groups()
let default_provider = rustls::crypto::ring::default_provider();
let provider = rustls::crypto::CryptoProvider {
cipher_suites: PERF_CIPHER_SUITES.into(),
..default_provider
};

let mut crypto = rustls::ServerConfig::builder_with_provider(provider.into())
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_no_client_auth()
.with_single_cert(cert, key)
.with_single_cert(cert, key.into())
.unwrap();
crypto.alpn_protocols = vec![b"perf".to_vec()];

Expand All @@ -90,18 +94,18 @@ async fn run(opt: Opt) -> Result<()> {
let mut transport = quinn::TransportConfig::default();
transport.initial_mtu(opt.initial_mtu);

let mut server_config = if opt.no_protection {
quinn::ServerConfig::with_crypto(Arc::new(NoProtectionServerConfig::new(Arc::new(crypto))))
} else {
quinn::ServerConfig::with_crypto(Arc::new(crypto))
};
server_config.transport_config(Arc::new(transport));
let crypto = Arc::new(QuicServerConfig::try_from(crypto)?);
let mut config = quinn::ServerConfig::with_crypto(match opt.no_protection {
true => Arc::new(NoProtectionServerConfig::new(crypto)),
false => crypto,
});
config.transport_config(Arc::new(transport));

let socket = bind_socket(opt.listen, opt.send_buffer_size, opt.recv_buffer_size)?;

let endpoint = quinn::Endpoint::new(
Default::default(),
Some(server_config),
Some(config),
socket,
Arc::new(TokioRuntime),
)
Expand Down
7 changes: 4 additions & 3 deletions perf/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::net::SocketAddr;

use anyhow::{Context, Result};
use rustls::crypto::ring::cipher_suite;
use socket2::{Domain, Protocol, Socket, Type};
use tracing::warn;

Expand Down Expand Up @@ -51,7 +52,7 @@ pub fn bind_socket(
}

pub static PERF_CIPHER_SUITES: &[rustls::SupportedCipherSuite] = &[
rustls::cipher_suite::TLS13_AES_128_GCM_SHA256,
rustls::cipher_suite::TLS13_AES_256_GCM_SHA384,
rustls::cipher_suite::TLS13_CHACHA20_POLY1305_SHA256,
cipher_suite::TLS13_AES_128_GCM_SHA256,
cipher_suite::TLS13_AES_256_GCM_SHA384,
cipher_suite::TLS13_CHACHA20_POLY1305_SHA256,
];
Loading