From d43b2a3c6350ab59f3905e6c24c0aa47773184c3 Mon Sep 17 00:00:00 2001 From: Lucio Franco Date: Sat, 31 Aug 2019 17:49:42 -0400 Subject: [PATCH] try openssl --- tonic/Cargo.toml | 2 + tonic/src/transport/client.rs | 3 +- tonic/src/transport/mod.rs | 1 + tonic/src/transport/openssl.rs | 69 ++++++++++++++++++++++++++++++++++ tonic/src/transport/tls.rs | 14 +++++-- 5 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 tonic/src/transport/openssl.rs diff --git a/tonic/Cargo.toml b/tonic/Cargo.toml index ba486a9..f75aca9 100644 --- a/tonic/Cargo.toml +++ b/tonic/Cargo.toml @@ -27,6 +27,8 @@ hyper = { git = "https://github.com/hyperium/hyper", optional = true} tokio = { version = "=0.2.0-alpha.4", default-features = false, features = ["tcp"], optional = true } tower-make = "=0.1.0-alpha.2" tokio-rustls = { path = "../../tokio-rustls", optional = true } +tokio-openssl = "=0.4.0-alpha.4" +openssl = "*" tower-reconnect = { path = "../../tower/tower-reconnect", optional = true } tower-buffer = { path = "../../tower/tower-buffer", optional = true } diff --git a/tonic/src/transport/client.rs b/tonic/src/transport/client.rs index e9b41e1..ac95020 100644 --- a/tonic/src/transport/client.rs +++ b/tonic/src/transport/client.rs @@ -49,7 +49,8 @@ impl Client { pub async fn connect_with_tls>(addr: Uri, ca: P) -> Result { let settings = Builder::new().http2_only(true).clone(); - let tls_connector = TlsConnector::load(ca).await?; + // let tls_connector = TlsConnector::load(ca).await?; + let tls_connector = super::openssl::TlsConnector::load(ca).await?; let maker = Connect::new(tls_connector, settings); let svc = tower_reconnect::Reconnect::new(maker, addr.clone()); diff --git a/tonic/src/transport/mod.rs b/tonic/src/transport/mod.rs index 199b2d5..7d5b22b 100644 --- a/tonic/src/transport/mod.rs +++ b/tonic/src/transport/mod.rs @@ -1,4 +1,5 @@ mod client; +mod openssl; mod tls; pub use self::client::Client; diff --git a/tonic/src/transport/openssl.rs b/tonic/src/transport/openssl.rs new file mode 100644 index 0000000..e5b522b --- /dev/null +++ b/tonic/src/transport/openssl.rs @@ -0,0 +1,69 @@ +use http::Uri; +use hyper::client::connect::HttpConnector; +use openssl::ssl::{ConnectConfiguration, SslConnector, SslMethod}; +use std::{ + future::Future, + path::Path, + pin::Pin, + sync::Arc, + task::{Context, Poll}, +}; +use tokio::{fs, net::TcpStream}; +use tokio_openssl::{connect, SslStream}; +use tower_make::MakeConnection; +use tower_service::Service; + +const ALPN_H2: &str = "h2"; + +#[derive(Clone)] +pub struct TlsConnector { + http: HttpConnector, + config: SslConnector, +} + +impl TlsConnector { + pub async fn load>(ca: P) -> Result { + let mut config = SslConnector::builder(SslMethod::tls()).unwrap(); + + config.set_alpn_protos(ALPN_H2.as_bytes()).unwrap(); + + config.set_ca_file(ca).unwrap(); + + let config = config.build(); + + let mut http = HttpConnector::new(); + http.enforce_http(false); + + Ok(Self { + http, + config, + }) + } +} + +impl Service for TlsConnector { + type Response = SslStream; + type Error = super::Error; + + type Future = + Pin> + Send + 'static>>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + MakeConnection::poll_ready(&mut self.http, cx) + .map_err(|e| super::Error::from((super::ErrorKind::Client, e.into()))) + } + + fn call(&mut self, uri: Uri) -> Self::Future { + let config = self.config.configure().unwrap(); + let tcp = self.http.make_connection(uri.clone()); + + let fut = async move { + let io = tcp.await.unwrap(); + let domain = "foo.test.google.fr"; + let tls = connect(config, &domain, io).await.unwrap(); + Ok(tls) + }; + + Box::pin(fut) + } +} diff --git a/tonic/src/transport/tls.rs b/tonic/src/transport/tls.rs index db31a09..b950ec8 100644 --- a/tonic/src/transport/tls.rs +++ b/tonic/src/transport/tls.rs @@ -9,7 +9,10 @@ use std::{ }; use tokio::{fs, net::TcpStream}; use tokio_rustls::{ - client::TlsStream, rustls::{ClientConfig, Session}, webpki::DNSNameRef, TlsConnector as RustlsConnector, + client::TlsStream, + rustls::{ClientConfig, Session}, + webpki::DNSNameRef, + TlsConnector as RustlsConnector, }; use tower_make::MakeConnection; use tower_service::Service; @@ -24,7 +27,9 @@ pub struct TlsConnector { impl TlsConnector { pub async fn load>(ca: P) -> Result { - let pem = fs::read(ca).await.map_err(|e| super::Error::from((super::ErrorKind::Client, e.into())))?; + let pem = fs::read(ca) + .await + .map_err(|e| super::Error::from((super::ErrorKind::Client, e.into())))?; Ok(TlsConnector::new(pem)) } @@ -54,12 +59,13 @@ impl Service for TlsConnector { Pin> + Send + 'static>>; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - MakeConnection::poll_ready(&mut self.http, cx).map_err(|e| super::Error::from((super::ErrorKind::Client, e.into()))) + MakeConnection::poll_ready(&mut self.http, cx) + .map_err(|e| super::Error::from((super::ErrorKind::Client, e.into()))) } fn call(&mut self, uri: Uri) -> Self::Future { let auth = uri.authority_part().unwrap(); - let dns = DNSNameRef::try_from_ascii_str("foo.test.google.fr")//auth.host()) + let dns = DNSNameRef::try_from_ascii_str("foo.test.google.fr") //auth.host()) .unwrap() .to_owned(); let config = self.config.clone();