Use 's2n-quic' TLS server builder.

This commit is contained in:
Wesley Rosenblum 2024-04-05 14:19:55 -07:00 committed by Sergio Benitez
parent a742d3da4f
commit 07e4170b72
3 changed files with 25 additions and 30 deletions

View File

@ -37,7 +37,7 @@ use futures::Stream;
use tokio::sync::Mutex;
use tokio_stream::StreamExt;
use crate::tls::TlsConfig;
use crate::tls::{TlsConfig, Error};
use crate::listener::{Listener, Connection, Endpoint};
type H3Conn = h3::server::Connection<quic_h3::Connection, bytes::Bytes>;
@ -62,43 +62,29 @@ pub struct QuicRx(h3::server::RequestStream<quic_h3::RecvStream, Bytes>);
pub struct QuicTx(h3::server::RequestStream<quic_h3::SendStream<Bytes>, Bytes>);
impl QuicListener {
pub async fn bind(address: SocketAddr, tls: TlsConfig) -> Result<Self, io::Error> {
use quic::provider::tls::rustls::{rustls, DEFAULT_CIPHERSUITES, Server as H3TlsServer};
pub async fn bind(address: SocketAddr, tls: TlsConfig) -> Result<Self, Error> {
use quic::provider::tls::rustls::Server as H3TlsServer;
// FIXME: Remove this as soon as `s2n_quic` is on rustls >= 0.22.
let cert_chain = tls.load_certs()
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?
let cert_chain = tls.load_certs()?
.into_iter()
.map(|v| v.to_vec())
.map(rustls::Certificate)
.collect::<Vec<_>>();
let key = tls.load_key()
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?
.secret_der()
.to_vec();
let mut h3tls = rustls::server::ServerConfig::builder()
.with_cipher_suites(DEFAULT_CIPHERSUITES)
.with_safe_default_kx_groups()
.with_safe_default_protocol_versions()
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("bad TLS config: {}", e)))?
.with_client_cert_verifier(rustls::server::NoClientAuth::boxed())
.with_single_cert(cert_chain, rustls::PrivateKey(key))
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("bad TLS config: {}", e)))?;
h3tls.alpn_protocols = vec![b"h3".to_vec()];
h3tls.ignore_client_order = tls.prefer_server_cipher_order;
h3tls.session_storage = rustls::server::ServerSessionMemoryCache::new(1024);
h3tls.ticketer = rustls::Ticketer::new()
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("bad TLS ticketer: {}", e)))?;
let h3tls = H3TlsServer::builder()
.with_application_protocols(["h3"].into_iter())
.map_err(|e| Error::Bind(e))?
.with_certificate(cert_chain, tls.load_key()?.secret_der())
.map_err(|e| Error::Bind(e))?
.with_prefer_server_cipher_suite_order(tls.prefer_server_cipher_order)
.map_err(|e| Error::Bind(e))?
.build()
.map_err(|e| Error::Bind(e))?;
let listener = quic::Server::builder()
.with_tls(H3TlsServer::new(h3tls))
.unwrap_or_else(|e| match e { })
.with_tls(h3tls)?
.with_io(address)?
.start()
.map_err(io::Error::other)?;
.map_err(|e| Error::Bind(Box::new(e)))?;
Ok(QuicListener {
tls,

View File

@ -108,7 +108,10 @@ impl Rocket<Ignite> {
let endpoint = h12listener.endpoint()?;
#[cfg(feature = "http3-preview")]
if let (Some(addr), Some(tls)) = (endpoint.tcp(), endpoint.tls_config()) {
let h3listener = crate::listener::quic::QuicListener::bind(addr, tls.clone()).await?;
let h3listener = crate::listener::quic::QuicListener::bind(addr, tls.clone())
.map_err(|e| ErrorKind::Bind(Some(endpoint.clone()), Box::new(e)))
.await?;
let rocket = self.into_orbit(vec![h3listener.endpoint()?, endpoint]);
let rocket = post_bind_callback(rocket).await?;

View File

@ -96,3 +96,9 @@ impl From<KeyError> for Error {
Error::PrivKey(value)
}
}
impl From<std::convert::Infallible> for Error {
fn from(v: std::convert::Infallible) -> Self {
v.into()
}
}