Skip to content

Commit

Permalink
fix quic feature build.
Browse files Browse the repository at this point in the history
  • Loading branch information
fakeshadow committed Apr 26, 2024
1 parent 7ed303e commit 9ed3e49
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 128 deletions.
1 change: 1 addition & 0 deletions client/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ impl ClientBuilder {
Arc::new(Self)
}
}

impl rustls::client::ServerCertVerifier for SkipServerVerification {
fn verify_server_cert(
&self,
Expand Down
9 changes: 4 additions & 5 deletions postgres/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ edition = "2021"
# feature for single thread client that have lower overhead(no lock) at the cost of no thread safety.
single-thread = []
# feature for connecting to tls enabled server.
tls = ["xitca-tls/rustls", "sha2", "webpki-roots"]
tls = ["xitca-tls/rustls-ring-crypto", "sha2", "webpki-roots"]
# feature for using quic as client/server transport layer for better congetion handling on lossy connection.
# note: it does not work as stand alone and server side proxy for translating quic message to tcp is needed.
quic = ["quinn", "quinn-proto", "rustls-pemfile", "rustls_0dot21"]
quic = ["quinn", "quinn-proto", "rustls-pemfile", "tls"]
# feature for using tokio_uring as IO reactor.
io-uring = ["xitca-io/runtime-uring"]

Expand All @@ -34,9 +34,8 @@ xitca-tls = { version = "0.3.0", optional = true }
# quic
quinn = { version = "0.11", git = "https://github.com/quinn-rs/quinn.git", optional = true }
quinn-proto = { git = "https://github.com/quinn-rs/quinn.git", optional = true }
rustls-pemfile = { version = "1.0.2", optional = true }
rustls_0dot21 = { package = "rustls", version = "0.21", features = ["dangerous_configuration"], optional = true }
rustls-pemfile = { version = "2", optional = true }

[dev-dependencies]
rcgen = "0.11"
rcgen = "0.13"
tokio = { version = "1.30", features = ["macros", "rt"] }
46 changes: 4 additions & 42 deletions postgres/src/driver/quic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use core::{

use std::{io, sync::Arc};

use quinn::{ClientConfig, Connection, Endpoint, RecvStream, SendStream};
use quinn::{crypto::rustls::QuicClientConfig, ClientConfig, Connection, Endpoint, RecvStream, SendStream};
use xitca_io::{
bytes::{Buf, Bytes},
io::{AsyncIo, Interest, Ready},
Expand Down Expand Up @@ -215,53 +215,15 @@ impl io::Write for QuicStream {
}
}

fn dangerous_config_rustls_0dot21(alpn: Vec<Vec<u8>>) -> Arc<rustls_0dot21::ClientConfig> {
use std::time::SystemTime;

use rustls_0dot21::{
client::{ServerCertVerified, ServerCertVerifier},
Certificate, ClientConfig, ServerName,
};

#[derive(Debug)]
struct SkipServerVerification;

impl SkipServerVerification {
fn new() -> Arc<Self> {
Arc::new(Self)
}
}

impl ServerCertVerifier for SkipServerVerification {
fn verify_server_cert(
&self,
_end_entity: &Certificate,
_intermediates: &[Certificate],
_server_name: &ServerName,
_scts: &mut dyn Iterator<Item = &[u8]>,
_ocsp_response: &[u8],
_now: SystemTime,
) -> Result<ServerCertVerified, rustls_0dot21::Error> {
Ok(ServerCertVerified::assertion())
}
}

let mut cfg = ClientConfig::builder()
.with_safe_defaults()
.with_custom_certificate_verifier(SkipServerVerification::new())
.with_no_client_auth();
cfg.alpn_protocols = alpn;
Arc::new(cfg)
}

#[cold]
#[inline(never)]
pub(crate) async fn _connect_quic(host: &str, ports: &[u16]) -> Result<Connection, Error> {
let addrs = super::connect::resolve(host, ports).await?;
let mut endpoint = Endpoint::client("0.0.0.0:0".parse().unwrap())?;

let cfg = dangerous_config_rustls_0dot21(vec![QUIC_ALPN.to_vec()]);
endpoint.set_default_client_config(ClientConfig::new(cfg));
let cfg = super::tls::dangerous_config(vec![QUIC_ALPN.to_vec()]);
let cfg = QuicClientConfig::try_from(cfg).unwrap();
endpoint.set_default_client_config(ClientConfig::new(Arc::new(cfg)));

let mut err = None;

Expand Down
117 changes: 59 additions & 58 deletions postgres/src/driver/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ where
{
let name = ServerName::try_from(host).map_err(|_| Error::todo())?.to_owned();
let config = dangerous_config(Vec::new());
let config = Arc::new(config);
let session = ClientConnection::new(config, name).map_err(|_| Error::todo())?;

let stream = TlsStream::handshake(io, session).await?;
Expand All @@ -38,63 +39,7 @@ where
Ok(stream)
}

fn dangerous_config(alpn: Vec<Vec<u8>>) -> std::sync::Arc<xitca_tls::rustls::ClientConfig> {
#[derive(Debug)]
struct SkipServerVerification;

impl SkipServerVerification {
fn new() -> Arc<Self> {
Arc::new(Self)
}
}

impl rustls::client::danger::ServerCertVerifier for SkipServerVerification {
fn verify_server_cert(
&self,
_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: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
verify_tls12_signature(
message,
cert,
dss,
&rustls::crypto::aws_lc_rs::default_provider().signature_verification_algorithms,
)
}

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

fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
rustls::crypto::aws_lc_rs::default_provider()
.signature_verification_algorithms
.supported_schemes()
}
}

pub(crate) fn dangerous_config(alpn: Vec<Vec<u8>>) -> xitca_tls::rustls::ClientConfig {
let mut root_store = RootCertStore::empty();

root_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
Expand All @@ -106,5 +51,61 @@ fn dangerous_config(alpn: Vec<Vec<u8>>) -> std::sync::Arc<xitca_tls::rustls::Cli

cfg.dangerous().set_certificate_verifier(SkipServerVerification::new());

Arc::new(cfg)
cfg
}

#[derive(Debug)]
pub(crate) struct SkipServerVerification;

impl SkipServerVerification {
fn new() -> Arc<Self> {
Arc::new(Self)
}
}

impl rustls::client::danger::ServerCertVerifier for SkipServerVerification {
fn verify_server_cert(
&self,
_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: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
verify_tls12_signature(
message,
cert,
dss,
&rustls::crypto::ring::default_provider().signature_verification_algorithms,
)
}

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

fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
rustls::crypto::ring::default_provider()
.signature_verification_algorithms
.supported_schemes()
}
}
19 changes: 6 additions & 13 deletions postgres/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,9 @@ fn _assert_driver_send() {
#[cfg(all(feature = "tls", feature = "quic"))]
#[cfg(test)]
mod test {
use std::{future::IntoFuture, sync::Arc};
use std::future::IntoFuture;

use quinn::ServerConfig;
use rustls_0dot21::{Certificate, PrivateKey};
use quinn::{rustls::pki_types::PrivatePkcs8KeyDer, ServerConfig};

use crate::{proxy::Proxy, AsyncLendingIterator, Config, Postgres, QuicStream};

Expand All @@ -154,17 +153,10 @@ mod test {
let name = vec!["127.0.0.1".to_string(), "localhost".to_string()];
let cert = rcgen::generate_simple_self_signed(name).unwrap();

let key = PrivateKey(cert.serialize_private_key_der());
let cert = vec![Certificate(cert.serialize_der().unwrap())];
let key = PrivatePkcs8KeyDer::from(cert.key_pair.serialize_der()).into();
let cert = cert.cert.der().clone();

let mut config = rustls_0dot21::ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(cert, key)
.unwrap();

config.alpn_protocols = vec![b"quic".to_vec()];
let config = ServerConfig::with_crypto(Arc::new(config));
let config = ServerConfig::with_single_cert(vec![cert], key).unwrap();

let upstream = tokio::net::lookup_host("localhost:5432").await.unwrap().next().unwrap();

Expand All @@ -180,6 +172,7 @@ mod test {
cfg.dbname("postgres").user("postgres").password("postgres");

let conn = crate::driver::quic::_connect_quic("127.0.0.1", &[5432]).await.unwrap();

let stream = conn.open_bi().await.unwrap();
let (cli, task) = Postgres::new(cfg).connect_io(QuicStream::from(stream)).await.unwrap();

Expand Down
17 changes: 7 additions & 10 deletions postgres/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ use std::{
sync::Arc,
};

use quinn::{Endpoint, Incoming, ServerConfig};
use rustls_0dot21::{Certificate, PrivateKey};
use quinn::{crypto::rustls::QuicServerConfig, Endpoint, Incoming, ServerConfig};
use tracing::error;
use xitca_io::{
io::{AsyncIo, Interest},
Expand Down Expand Up @@ -100,21 +99,19 @@ impl Proxy {
fn cfg_from_cert(cert: impl AsRef<Path>, key: impl AsRef<Path>) -> Result<ServerConfig, Error> {
let cert = fs::read(cert)?;
let key = fs::read(key)?;
let key = rustls_pemfile::pkcs8_private_keys(&mut &*key).unwrap().remove(0);
let key = PrivateKey(key);
let key = rustls_pemfile::pkcs8_private_keys(&mut &*key).next().unwrap().unwrap();
let key = quinn::rustls::pki_types::PrivateKeyDer::from(key);

let cert = rustls_pemfile::certs(&mut &*cert)?
.into_iter()
.map(Certificate)
.collect();
let cert = rustls_pemfile::certs(&mut &*cert).collect::<Result<_, _>>().unwrap();

let mut config = rustls_0dot21::ServerConfig::builder()
.with_safe_defaults()
let mut config = quinn::rustls::ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(cert, key)?;

config.alpn_protocols = vec![QUIC_ALPN.to_vec()];

let config = QuicServerConfig::try_from(config).unwrap();

Ok(ServerConfig::with_crypto(Arc::new(config)))
}

Expand Down

0 comments on commit 9ed3e49

Please sign in to comment.