TLS works \o/
So, the issues were: - webpki does not support IP addresses as DNS names in URLs, so I hacked the HttpsConnector to always provide a fixed string as the DNS name for server certificate validation - the certificate requied a SAN section which was complicated to build but eventually the solution is there in genkeys.sh
This commit is contained in:
parent
d1e8f78b2c
commit
d2814b5c33
78
Cargo.lock
generated
78
Cargo.lock
generated
@ -115,20 +115,6 @@ dependencies = [
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.2.0"
|
||||
@ -161,14 +147,6 @@ dependencies = [
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ct-logs"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
@ -455,12 +433,10 @@ version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ct-logs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustls-native-certs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-rustls 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -639,11 +615,6 @@ name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.10.0"
|
||||
@ -841,17 +812,6 @@ dependencies = [
|
||||
"webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"schannel 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"security-framework 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.2"
|
||||
@ -867,15 +827,6 @@ name = "ryu"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
@ -890,27 +841,6 @@ dependencies = [
|
||||
"untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"security-framework-sys 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.106"
|
||||
@ -1321,12 +1251,9 @@ dependencies = [
|
||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
|
||||
"checksum core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
|
||||
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||
"checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
|
||||
"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
||||
"checksum ct-logs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4d3686f5fa27dbc1d76c751300376e167c5a43387f44bb451fd1c24776e49113"
|
||||
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
"checksum err-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "82f46c91bbed409ee74495549acbfcc7fae856e712e1df15afe75d0775eedc6c"
|
||||
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
@ -1376,7 +1303,6 @@ dependencies = [
|
||||
"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
|
||||
"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
|
||||
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||
"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc"
|
||||
"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1"
|
||||
"checksum pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c"
|
||||
@ -1400,14 +1326,10 @@ dependencies = [
|
||||
"checksum rmp 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "0f10b46df14cf1ee1ac7baa4d2fbc2c52c0622a4b82fa8740e37bc452ac0184f"
|
||||
"checksum rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4c1ee98f14fe8b8e9c5ea13d25da7b2a1796169202c57a09d7288de90d56222b"
|
||||
"checksum rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1"
|
||||
"checksum rustls-native-certs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a75ffeb84a6bd9d014713119542ce415db3a3e4748f0bfce1e1416cd224a23a5"
|
||||
"checksum rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6"
|
||||
"checksum ryu 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
|
||||
"checksum schannel 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "039c25b130bd8c1321ee2d7de7fde2659fa9c2744e4bb29711cfc852ea53cd19"
|
||||
"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
"checksum sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c"
|
||||
"checksum security-framework 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "572dfa3a0785509e7a44b5b4bebcf94d41ba34e9ed9eb9df722545c3b3c4144a"
|
||||
"checksum security-framework-sys 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8ddb15a5fec93b7021b8a9e96009c5d8d51c15673569f7c0f6b7204e5b7b404f"
|
||||
"checksum serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399"
|
||||
"checksum serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "325a073952621257820e7a3469f55ba4726d8b28657e7e36653d1c36dc2c84ae"
|
||||
"checksum serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c"
|
||||
|
@ -29,11 +29,11 @@ sha2 = "0.8"
|
||||
async-trait = "0.1.30"
|
||||
reduce = "0.1.2"
|
||||
serde_json = "1.0"
|
||||
|
||||
rustls = "0.17"
|
||||
tokio-rustls = "0.13"
|
||||
tokio-rustls = { version = "0.13", features = ["dangerous_configuration"] }
|
||||
hyper-rustls = { version = "0.20", default-features = false }
|
||||
webpki = "0.21"
|
||||
hyper-rustls = "0.20"
|
||||
#hyper-rustls = { version = "0.4", default-features = false }
|
||||
|
||||
[profile.dev]
|
||||
lto = "off"
|
||||
|
46
genkeys.sh
46
genkeys.sh
@ -10,27 +10,39 @@ cd pki
|
||||
if [ ! -f garage-ca.key ]; then
|
||||
echo "Generating Garage CA keys..."
|
||||
openssl genrsa -out garage-ca.key 4096
|
||||
openssl req -x509 -new -key garage-ca.key -subj "/C=FR/O=Garage" -days 3650 -out garage-ca.crt
|
||||
openssl req -x509 -new -nodes -key garage-ca.key -sha256 -days 3650 -out garage-ca.crt -subj "/C=FR/O=Garage"
|
||||
fi
|
||||
|
||||
if [ ! -f garage.key ]; then
|
||||
echo "Generating Garage agent keys..."
|
||||
openssl genrsa -out garage.key 4096
|
||||
openssl req -new -sha256 -key garage.key -subj "/C=FR/O=Garage/CN=*" -out garage.csr
|
||||
|
||||
if [ ! -f garage.crt ]; then
|
||||
echo "Generating Garage agent keys..."
|
||||
if [ ! -f garage.key ]; then
|
||||
openssl genrsa -out garage.key 4096
|
||||
fi
|
||||
openssl req -new -sha256 -key garage.key -subj "/C=FR/O=Garage/CN=garage" \
|
||||
-out garage.csr
|
||||
openssl req -in garage.csr -noout -text
|
||||
openssl x509 -req -in garage.csr \
|
||||
-CA garage-ca.crt -CAkey garage-ca.key -CAcreateserial \
|
||||
-out garage.crt -days 365 -sha256
|
||||
rm garage.csr
|
||||
fi
|
||||
-extensions v3_req \
|
||||
-extfile <(cat <<EOF
|
||||
[req]
|
||||
distinguished_name = req_distinguished_name
|
||||
req_extensions = v3_req
|
||||
prompt = no
|
||||
|
||||
if [ ! -f garage-client.key ]; then
|
||||
echo "Generating Garage client key..."
|
||||
openssl genrsa -out garage-client.key 4096
|
||||
openssl req -new -sha256 -key garage-client.key -subj "/C=FR/O=Garage" -out garage-client.csr
|
||||
openssl req -in garage-client.csr -noout -text
|
||||
openssl x509 -req -in garage-client.csr \
|
||||
[req_distinguished_name]
|
||||
C = FR
|
||||
O = Garage
|
||||
CN = garage
|
||||
|
||||
[v3_req]
|
||||
keyUsage = keyEncipherment, dataEncipherment
|
||||
extendedKeyUsage = serverAuth, clientAuth
|
||||
subjectAltName = @alt_names
|
||||
[alt_names]
|
||||
DNS.1 = garage
|
||||
EOF
|
||||
) \
|
||||
-CA garage-ca.crt -CAkey garage-ca.key -CAcreateserial \
|
||||
-out garage-client.crt -days 365 -sha256
|
||||
rm garage-client.csr
|
||||
-out garage.crt -days 365
|
||||
fi
|
||||
|
@ -8,7 +8,6 @@ use futures::stream::StreamExt;
|
||||
use futures_util::future::FutureExt;
|
||||
use hyper::client::{Client, HttpConnector};
|
||||
use hyper::{Body, Method, Request, StatusCode};
|
||||
use hyper_rustls::HttpsConnector;
|
||||
|
||||
use crate::data::*;
|
||||
use crate::error::Error;
|
||||
@ -93,7 +92,7 @@ pub async fn rpc_call(
|
||||
|
||||
pub enum RpcClient {
|
||||
HTTP(Client<HttpConnector, hyper::Body>),
|
||||
HTTPS(Client<HttpsConnector<HttpConnector>, hyper::Body>),
|
||||
HTTPS(Client<tls_util::HttpsConnectorFixedDnsname<HttpConnector>, hyper::Body>),
|
||||
}
|
||||
|
||||
impl RpcClient {
|
||||
@ -109,12 +108,11 @@ impl RpcClient {
|
||||
config.root_store.add(crt)?;
|
||||
}
|
||||
|
||||
config.set_single_client_cert([&ca_certs[..], &node_certs[..]].concat(), node_key)?;
|
||||
config.set_single_client_cert([&node_certs[..], &ca_certs[..]].concat(), node_key)?;
|
||||
// config.dangerous().set_certificate_verifier(Arc::new(tls_util::NoHostnameCertVerifier));
|
||||
|
||||
let mut http_connector = HttpConnector::new();
|
||||
http_connector.enforce_http(false);
|
||||
let connector =
|
||||
HttpsConnector::<HttpConnector>::from((http_connector, Arc::new(config)));
|
||||
tls_util::HttpsConnectorFixedDnsname::<HttpConnector>::new(config, "garage");
|
||||
|
||||
Ok(RpcClient::HTTPS(Client::builder().build(connector)))
|
||||
} else {
|
||||
@ -161,3 +159,4 @@ impl RpcClient {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ pub async fn run_rpc_server(
|
||||
|
||||
let mut config =
|
||||
rustls::ServerConfig::new(rustls::AllowAnyAuthenticatedClient::new(ca_store));
|
||||
config.set_single_cert([&ca_certs[..], &node_certs[..]].concat(), node_key)?;
|
||||
config.set_single_cert([&node_certs[..], &ca_certs[..]].concat(), node_key)?;
|
||||
let tls_acceptor = Arc::new(TlsAcceptor::from(Arc::new(config)));
|
||||
|
||||
let mut listener = TcpListener::bind(&bind_addr).await?;
|
||||
|
152
src/tls_util.rs
152
src/tls_util.rs
@ -1,6 +1,20 @@
|
||||
use std::{fs, io};
|
||||
use core::task::{Poll, Context};
|
||||
use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
use core::future::Future;
|
||||
|
||||
use futures_util::future::*;
|
||||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
use rustls::internal::pemfile;
|
||||
use rustls::*;
|
||||
use hyper::client::HttpConnector;
|
||||
use hyper::client::connect::Connection;
|
||||
use hyper::service::Service;
|
||||
use hyper::Uri;
|
||||
use hyper_rustls::MaybeHttpsStream;
|
||||
use tokio_rustls::TlsConnector;
|
||||
use webpki::DNSNameRef;
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
@ -44,3 +58,141 @@ pub fn load_private_key(filename: &str) -> Result<rustls::PrivateKey, Error> {
|
||||
}
|
||||
Ok(keys[0].clone())
|
||||
}
|
||||
|
||||
|
||||
// ---- AWFUL COPYPASTA FROM rustls/verifier.rs
|
||||
// ---- USED TO ALLOW TO VERIFY SERVER CERTIFICATE VALIDITY IN CHAIN
|
||||
// ---- BUT DISREGARD HOSTNAME PARAMETER
|
||||
|
||||
pub struct NoHostnameCertVerifier;
|
||||
|
||||
type SignatureAlgorithms = &'static [&'static webpki::SignatureAlgorithm];
|
||||
static SUPPORTED_SIG_ALGS: SignatureAlgorithms = &[
|
||||
&webpki::ECDSA_P256_SHA256,
|
||||
&webpki::ECDSA_P256_SHA384,
|
||||
&webpki::ECDSA_P384_SHA256,
|
||||
&webpki::ECDSA_P384_SHA384,
|
||||
&webpki::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
|
||||
&webpki::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
|
||||
&webpki::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
|
||||
&webpki::RSA_PKCS1_2048_8192_SHA256,
|
||||
&webpki::RSA_PKCS1_2048_8192_SHA384,
|
||||
&webpki::RSA_PKCS1_2048_8192_SHA512,
|
||||
&webpki::RSA_PKCS1_3072_8192_SHA384
|
||||
];
|
||||
|
||||
impl rustls::ServerCertVerifier for NoHostnameCertVerifier {
|
||||
fn verify_server_cert(&self,
|
||||
roots: &RootCertStore,
|
||||
presented_certs: &[Certificate],
|
||||
_dns_name: webpki::DNSNameRef,
|
||||
_ocsp_response: &[u8]) -> Result<rustls::ServerCertVerified, TLSError> {
|
||||
|
||||
if presented_certs.is_empty() {
|
||||
return Err(TLSError::NoCertificatesPresented);
|
||||
}
|
||||
|
||||
let cert = webpki::EndEntityCert::from(&presented_certs[0].0)
|
||||
.map_err(TLSError::WebPKIError)?;
|
||||
|
||||
let chain = presented_certs.iter()
|
||||
.skip(1)
|
||||
.map(|cert| cert.0.as_ref())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let trustroots: Vec<webpki::TrustAnchor> = roots.roots
|
||||
.iter()
|
||||
.map(|x| x.to_trust_anchor())
|
||||
.collect();
|
||||
|
||||
let now = webpki::Time::try_from(std::time::SystemTime::now())
|
||||
.map_err( |_ | TLSError::FailedToGetCurrentTime)?;
|
||||
|
||||
cert.verify_is_valid_tls_server_cert(SUPPORTED_SIG_ALGS,
|
||||
&webpki::TLSServerTrustAnchors(&trustroots), &chain, now)
|
||||
.map_err(TLSError::WebPKIError)?;
|
||||
|
||||
Ok(rustls::ServerCertVerified::assertion())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---- AWFUL COPYPASTA FROM HYPER-RUSTLS connector.rs
|
||||
// ---- ALWAYS USE `garage` AS HOSTNAME FOR TLS VERIFICATION
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HttpsConnectorFixedDnsname<T> {
|
||||
http: T,
|
||||
tls_config: Arc<rustls::ClientConfig>,
|
||||
fixed_dnsname: &'static str,
|
||||
}
|
||||
|
||||
type BoxError = Box<dyn std::error::Error + Send + Sync>;
|
||||
|
||||
impl HttpsConnectorFixedDnsname<HttpConnector> {
|
||||
pub fn new(mut tls_config: rustls::ClientConfig, fixed_dnsname: &'static str) -> Self {
|
||||
let mut http = HttpConnector::new();
|
||||
http.enforce_http(false);
|
||||
tls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
|
||||
Self {
|
||||
http,
|
||||
tls_config: Arc::new(tls_config),
|
||||
fixed_dnsname,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Service<Uri> for HttpsConnectorFixedDnsname<T>
|
||||
where
|
||||
T: Service<Uri>,
|
||||
T::Response: Connection + AsyncRead + AsyncWrite + Send + Unpin + 'static,
|
||||
T::Future: Send + 'static,
|
||||
T::Error: Into<BoxError>,
|
||||
{
|
||||
type Response = MaybeHttpsStream<T::Response>;
|
||||
type Error = BoxError;
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
type Future =
|
||||
Pin<Box<dyn Future<Output = Result<MaybeHttpsStream<T::Response>, BoxError>> + Send>>;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
match self.http.poll_ready(cx) {
|
||||
Poll::Ready(Ok(())) => Poll::Ready(Ok(())),
|
||||
Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())),
|
||||
Poll::Pending => Poll::Pending,
|
||||
}
|
||||
}
|
||||
|
||||
fn call(&mut self, dst: Uri) -> Self::Future {
|
||||
let is_https = dst.scheme_str() == Some("https");
|
||||
|
||||
if !is_https {
|
||||
let connecting_future = self.http.call(dst);
|
||||
|
||||
let f = async move {
|
||||
let tcp = connecting_future.await.map_err(Into::into)?;
|
||||
|
||||
Ok(MaybeHttpsStream::Http(tcp))
|
||||
};
|
||||
f.boxed()
|
||||
} else {
|
||||
let cfg = self.tls_config.clone();
|
||||
let connecting_future = self.http.call(dst);
|
||||
|
||||
let dnsname = DNSNameRef::try_from_ascii_str(self.fixed_dnsname)
|
||||
.expect("Invalid fixed dnsname");
|
||||
|
||||
let f = async move {
|
||||
let tcp = connecting_future.await.map_err(Into::into)?;
|
||||
let connector = TlsConnector::from(cfg);
|
||||
let tls = connector
|
||||
.connect(dnsname, tcp)
|
||||
.await
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
|
||||
Ok(MaybeHttpsStream::Https(tls))
|
||||
};
|
||||
f.boxed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user