fix(transport): Remove support for OpenSSL (#141)
BREAKING CHANGE: Remove support for OpenSSL within the transport.
This commit is contained in:
committed by
Lucio Franco
parent
c63c107560
commit
85060500f3
@@ -74,12 +74,12 @@ jobs:
|
|||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: cargo test --all --all-features
|
run: cargo test --all --all-features
|
||||||
|
|
||||||
interop-unix:
|
interop:
|
||||||
name: Interop Tests (Rustls & OpenSSL)
|
name: Interop Tests
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macOS-latest]
|
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||||
rust: [stable]
|
rust: [stable]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@@ -98,30 +98,3 @@ jobs:
|
|||||||
- name: Run interop tests with Rustls
|
- name: Run interop tests with Rustls
|
||||||
run: ./tonic-interop/test.sh --use_tls tls_rustls
|
run: ./tonic-interop/test.sh --use_tls tls_rustls
|
||||||
shell: bash
|
shell: bash
|
||||||
- name: Run interop tests with OpenSSL
|
|
||||||
run: ./tonic-interop/test.sh --use_tls tls_openssl
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
interop-windows:
|
|
||||||
name: Interop Tests (Rustls) (Windows)
|
|
||||||
runs-on: windows-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
rust: [stable]
|
|
||||||
|
|
||||||
env:
|
|
||||||
RUSTFLAGS: "-D warnings"
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: hecrj/setup-rust-action@master
|
|
||||||
with:
|
|
||||||
rust-version: ${{ matrix.rust }}
|
|
||||||
- name: Install rustfmt
|
|
||||||
run: rustup component add rustfmt
|
|
||||||
- uses: actions/checkout@master
|
|
||||||
- name: Run interop tests
|
|
||||||
run: ./tonic-interop/test.sh
|
|
||||||
shell: bash
|
|
||||||
- name: Run interop tests with Rustls
|
|
||||||
run: ./tonic-interop/test.sh --use_tls tls_rustls
|
|
||||||
shell: bash
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ contains the tools to build clients and servers from [`protobuf`] definitions.
|
|||||||
- Bi-directional streaming
|
- Bi-directional streaming
|
||||||
- High performance async io
|
- High performance async io
|
||||||
- Interoperability
|
- Interoperability
|
||||||
- TLS backed via either [`openssl`] or [`rustls`]
|
- TLS backed by [`rustls`]
|
||||||
- Load balancing
|
- Load balancing
|
||||||
- Custom metadata
|
- Custom metadata
|
||||||
- Authentication
|
- Authentication
|
||||||
@@ -97,7 +97,6 @@ terms or conditions.
|
|||||||
[`prost`]: https://github.com/danburkert/prost
|
[`prost`]: https://github.com/danburkert/prost
|
||||||
[`protobuf`]: https://developers.google.com/protocol-buffers
|
[`protobuf`]: https://developers.google.com/protocol-buffers
|
||||||
[`rustls`]: https://github.com/ctz/rustls
|
[`rustls`]: https://github.com/ctz/rustls
|
||||||
[`openssl`]: https://www.openssl.org/
|
|
||||||
[`tonic-examples`]: https://github.com/hyperium/tonic/tree/master/tonic-examples
|
[`tonic-examples`]: https://github.com/hyperium/tonic/tree/master/tonic-examples
|
||||||
[`tonic-interop`]: https://github.com/hyperium/tonic/tree/master/tonic-interop
|
[`tonic-interop`]: https://github.com/hyperium/tonic/tree/master/tonic-interop
|
||||||
[Examples]: https://github.com/hyperium/tonic/tree/master/tonic-examples
|
[Examples]: https://github.com/hyperium/tonic/tree/master/tonic-examples
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ name = "gcp-client"
|
|||||||
path = "src/gcp/client.rs"
|
path = "src/gcp/client.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tonic = { path = "../tonic", features = ["rustls"] }
|
tonic = { path = "../tonic", features = ["tls"] }
|
||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
prost = "0.5"
|
prost = "0.5"
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,6 @@ edition = "2018"
|
|||||||
publish = false
|
publish = false
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["tonic"]
|
|
||||||
tls_openssl = ["tonic", "tonic/tls", "tonic/openssl"]
|
|
||||||
tls_rustls = ["tonic", "tonic/tls", "tonic/rustls"]
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "client"
|
name = "client"
|
||||||
path = "src/bin/client.rs"
|
path = "src/bin/client.rs"
|
||||||
@@ -21,7 +16,7 @@ path = "src/bin/server.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tokio = "=0.2.0-alpha.6"
|
tokio = "=0.2.0-alpha.6"
|
||||||
tonic = { path = "../tonic", optional = true }
|
tonic = { path = "../tonic", features = ["tls"] }
|
||||||
prost = "0.5"
|
prost = "0.5"
|
||||||
prost-derive = "0.5"
|
prost-derive = "0.5"
|
||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use structopt::{clap::arg_enum, StructOpt};
|
use structopt::{clap::arg_enum, StructOpt};
|
||||||
use tonic::transport::Endpoint;
|
use tonic::transport::Endpoint;
|
||||||
#[cfg(any(feature = "tls_rustls", feature = "tls_openssl"))]
|
|
||||||
use tonic::transport::{Certificate, ClientTlsConfig};
|
use tonic::transport::{Certificate, ClientTlsConfig};
|
||||||
use tonic_interop::client;
|
use tonic_interop::client;
|
||||||
|
|
||||||
@@ -33,32 +32,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.concurrency_limit(30);
|
.concurrency_limit(30);
|
||||||
|
|
||||||
if matches.use_tls {
|
if matches.use_tls {
|
||||||
#[cfg(not(any(feature = "tls_rustls", feature = "tls_openssl")))]
|
let pem = tokio::fs::read("tonic-interop/data/ca.pem").await?;
|
||||||
{
|
let ca = Certificate::from_pem(pem);
|
||||||
panic!("No TLS library feature selected");
|
endpoint = endpoint.tls_config(
|
||||||
}
|
ClientTlsConfig::with_rustls()
|
||||||
|
.ca_certificate(ca)
|
||||||
#[cfg(feature = "tls_rustls")]
|
.domain_name("foo.test.google.fr"),
|
||||||
{
|
);
|
||||||
let pem = tokio::fs::read("tonic-interop/data/ca.pem").await?;
|
|
||||||
let ca = Certificate::from_pem(pem);
|
|
||||||
endpoint = endpoint.tls_config(
|
|
||||||
ClientTlsConfig::with_rustls()
|
|
||||||
.ca_certificate(ca)
|
|
||||||
.domain_name("foo.test.google.fr"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "tls_openssl")]
|
|
||||||
{
|
|
||||||
let pem = tokio::fs::read("tonic-interop/data/ca.pem").await?;
|
|
||||||
let ca = Certificate::from_pem(pem);
|
|
||||||
endpoint = endpoint.tls_config(
|
|
||||||
ClientTlsConfig::with_openssl()
|
|
||||||
.ca_certificate(ca)
|
|
||||||
.domain_name("foo.test.google.fr"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let channel = endpoint.connect().await?;
|
let channel = endpoint.connect().await?;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use structopt::StructOpt;
|
|||||||
use tonic::body::BoxBody;
|
use tonic::body::BoxBody;
|
||||||
use tonic::client::GrpcService;
|
use tonic::client::GrpcService;
|
||||||
use tonic::transport::Server;
|
use tonic::transport::Server;
|
||||||
#[cfg(any(feature = "tls_rustls", feature = "tls_openssl"))]
|
|
||||||
use tonic::transport::{Identity, ServerTlsConfig};
|
use tonic::transport::{Identity, ServerTlsConfig};
|
||||||
use tonic_interop::{server, MergeTrailers};
|
use tonic_interop::{server, MergeTrailers};
|
||||||
|
|
||||||
@@ -50,28 +49,11 @@ async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if matches.use_tls {
|
if matches.use_tls {
|
||||||
#[cfg(not(any(feature = "tls_rustls", feature = "tls_openssl")))]
|
let cert = tokio::fs::read("tonic-interop/data/server1.pem").await?;
|
||||||
{
|
let key = tokio::fs::read("tonic-interop/data/server1.key").await?;
|
||||||
panic!("No TLS library feature selected");
|
let identity = Identity::from_pem(cert, key);
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "tls_rustls")]
|
builder = builder.tls_config(ServerTlsConfig::with_rustls().identity(identity));
|
||||||
{
|
|
||||||
let cert = tokio::fs::read("tonic-interop/data/server1.pem").await?;
|
|
||||||
let key = tokio::fs::read("tonic-interop/data/server1.key").await?;
|
|
||||||
let identity = Identity::from_pem(cert, key);
|
|
||||||
|
|
||||||
builder = builder.tls_config(ServerTlsConfig::with_rustls().identity(identity));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "tls_openssl")]
|
|
||||||
{
|
|
||||||
let cert = tokio::fs::read("tonic-interop/data/server1.pem").await?;
|
|
||||||
let key = tokio::fs::read("tonic-interop/data/server1.key").await?;
|
|
||||||
let identity = Identity::from_pem(cert, key);
|
|
||||||
|
|
||||||
builder = builder.tls_config(ServerTlsConfig::with_openssl().identity(identity));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let test_service = server::TestServiceServer::new(server::TestService::default());
|
let test_service = server::TestServiceServer::new(server::TestService::default());
|
||||||
|
|||||||
@@ -15,15 +15,8 @@ case "$OSTYPE" in
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
ARG="${1:-""}"
|
ARG="${1:-""}"
|
||||||
TLS_PROVIDER="${2:-""}"
|
|
||||||
|
|
||||||
if [[ -n "${TLS_PROVIDER}" ]] ; then
|
(cd tonic-interop && cargo build --bins)
|
||||||
FEATURES="--features ${TLS_PROVIDER}"
|
|
||||||
else
|
|
||||||
FEATURES=
|
|
||||||
fi
|
|
||||||
|
|
||||||
(cd tonic-interop && cargo build --bins ${FEATURES})
|
|
||||||
|
|
||||||
SERVER="tonic-interop/bin/server_${OS}_amd64${EXT}"
|
SERVER="tonic-interop/bin/server_${OS}_amd64${EXT}"
|
||||||
|
|
||||||
|
|||||||
+2
-10
@@ -32,11 +32,8 @@ transport = [
|
|||||||
"tower-balance",
|
"tower-balance",
|
||||||
"tower-load",
|
"tower-load",
|
||||||
]
|
]
|
||||||
openssl = ["openssl1", "tokio-openssl", "tls"]
|
tls = ["tokio-rustls"]
|
||||||
rustls = ["tokio-rustls", "tls"]
|
tls-roots = ["rustls-native-certs"]
|
||||||
openssl-roots = ["openssl-probe"]
|
|
||||||
rustls-roots = ["rustls-native-certs"]
|
|
||||||
tls = []
|
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "bench_main"
|
name = "bench_main"
|
||||||
@@ -72,11 +69,6 @@ tower-make = "=0.3.0-alpha.2a"
|
|||||||
tower-balance = { version = "=0.3.0-alpha.2", optional = true }
|
tower-balance = { version = "=0.3.0-alpha.2", optional = true }
|
||||||
tower-load = { version = "=0.3.0-alpha.2", optional = true }
|
tower-load = { version = "=0.3.0-alpha.2", optional = true }
|
||||||
|
|
||||||
# openssl
|
|
||||||
tokio-openssl = { version = "=0.4.0-alpha.6", optional = true }
|
|
||||||
openssl1 = { package = "openssl", version = "0.10", optional = true }
|
|
||||||
openssl-probe = { version = "0.1", optional = true }
|
|
||||||
|
|
||||||
# rustls
|
# rustls
|
||||||
tokio-rustls = { version = "=0.12.0-alpha.5", optional = true }
|
tokio-rustls = { version = "=0.12.0-alpha.5", optional = true }
|
||||||
rustls-native-certs = { version = "0.1", optional = true }
|
rustls-native-certs = { version = "0.1", optional = true }
|
||||||
|
|||||||
+6
-12
@@ -20,16 +20,11 @@
|
|||||||
//! implementation based on [`hyper`], [`tower`] and [`tokio`]. Enabled by default.
|
//! implementation based on [`hyper`], [`tower`] and [`tokio`]. Enabled by default.
|
||||||
//! - `codegen`: Enables all the required exports and optional dependencies required
|
//! - `codegen`: Enables all the required exports and optional dependencies required
|
||||||
//! for [`tonic-build`]. Enabled by default.
|
//! for [`tonic-build`]. Enabled by default.
|
||||||
//! - `openssl`: Enables the `openssl` based tls options for the `transport` feature`. Not
|
//! - `tls`: Enables the `ruslts` based TLS options for the `transport` feature`. Not
|
||||||
//! enabled by default.
|
//! enabled by default.
|
||||||
//! - `openssl-roots`: Adds system trust roots to `openssl`-based gRPC clients using the
|
//! - `tls-roots`: Adds system trust roots to `rustls`-based gRPC clients using the
|
||||||
//! `openssl-probe` crate. Not enabled by default. `openssl` must be enabled to use
|
//! `rustls-native-certs` crate. Not enabled by default. `tls` must be enabled to use
|
||||||
//! `openssl-roots`.
|
//! `tls-roots`.
|
||||||
//! - `rustls`: Enables the `ruslts` based tls options for the `transport` feature`. Not
|
|
||||||
//! enabled by default.
|
|
||||||
//! - `rustls-roots`: Adds system trust roots to `rustls`-based gRPC clients using the
|
|
||||||
//! `rustls-native-certs` crate. Not enabled by default. `rustls` must be enabled to use
|
|
||||||
//! `rustls-roots`.
|
|
||||||
//! - `prost`: Enables the [`prost`] based gRPC [`Codec`] implementation.
|
//! - `prost`: Enables the [`prost`] based gRPC [`Codec`] implementation.
|
||||||
//!
|
//!
|
||||||
//! # Structure
|
//! # Structure
|
||||||
@@ -48,8 +43,8 @@
|
|||||||
//! and [`Server`]. These implementations are built on top of [`tokio`], [`hyper`] and [`tower`].
|
//! and [`Server`]. These implementations are built on top of [`tokio`], [`hyper`] and [`tower`].
|
||||||
//! It also provides many of the features that the core gRPC libraries provide such as load balancing,
|
//! It also provides many of the features that the core gRPC libraries provide such as load balancing,
|
||||||
//! tls, timeouts, and many more. This implementation can also be used as a reference implementation
|
//! tls, timeouts, and many more. This implementation can also be used as a reference implementation
|
||||||
//! to build even more feature rich clients and servers. This module also provides the ability to choose
|
//! to build even more feature rich clients and servers. This module also provides the ability to
|
||||||
//! between [`rustls`] and [`openssl`] for the tls backend.
|
//! enable TLS using [`rustls`], via the `tls` feature flag.
|
||||||
//!
|
//!
|
||||||
//! [gRPC]: https://grpc.io
|
//! [gRPC]: https://grpc.io
|
||||||
//! [`tonic`]: https://github.com/hyperium/tonic
|
//! [`tonic`]: https://github.com/hyperium/tonic
|
||||||
@@ -63,7 +58,6 @@
|
|||||||
//! [`Channel`]: transport/struct.Channel.html
|
//! [`Channel`]: transport/struct.Channel.html
|
||||||
//! [`Server`]: transport/struct.Server.html
|
//! [`Server`]: transport/struct.Server.html
|
||||||
//! [`rustls`]: https://docs.rs/rustls
|
//! [`rustls`]: https://docs.rs/rustls
|
||||||
//! [`openssl`]: https://www.openssl.org
|
|
||||||
//! [`client`]: client/index.html
|
//! [`client`]: client/index.html
|
||||||
//! [`transport`]: transport/index.html
|
//! [`transport`]: transport/index.html
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use super::channel::Channel;
|
|||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
use super::{
|
use super::{
|
||||||
service::TlsConnector,
|
service::TlsConnector,
|
||||||
tls::{Certificate, Identity, TlsProvider},
|
tls::{Certificate, Identity},
|
||||||
};
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use http::uri::{InvalidUriBytes, Uri};
|
use http::uri::{InvalidUriBytes, Uri};
|
||||||
@@ -223,13 +223,9 @@ impl fmt::Debug for Endpoint {
|
|||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ClientTlsConfig {
|
pub struct ClientTlsConfig {
|
||||||
provider: TlsProvider,
|
|
||||||
domain: Option<String>,
|
domain: Option<String>,
|
||||||
cert: Option<Certificate>,
|
cert: Option<Certificate>,
|
||||||
identity: Option<Identity>,
|
identity: Option<Identity>,
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
openssl_raw: Option<openssl1::ssl::SslConnector>,
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
rustls_raw: Option<tokio_rustls::rustls::ClientConfig>,
|
rustls_raw: Option<tokio_rustls::rustls::ClientConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,7 +233,6 @@ pub struct ClientTlsConfig {
|
|||||||
impl fmt::Debug for ClientTlsConfig {
|
impl fmt::Debug for ClientTlsConfig {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("ClientTlsConfig")
|
f.debug_struct("ClientTlsConfig")
|
||||||
.field("provider", &self.provider)
|
|
||||||
.field("domain", &self.domain)
|
.field("domain", &self.domain)
|
||||||
.field("cert", &self.cert)
|
.field("cert", &self.cert)
|
||||||
.field("identity", &self.identity)
|
.field("identity", &self.identity)
|
||||||
@@ -247,35 +242,19 @@ impl fmt::Debug for ClientTlsConfig {
|
|||||||
|
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
impl ClientTlsConfig {
|
impl ClientTlsConfig {
|
||||||
/// Creates a new `ClientTlsConfig` using OpenSSL.
|
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
pub fn with_openssl() -> Self {
|
|
||||||
Self::new(TlsProvider::OpenSsl)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new `ClientTlsConfig` using Rustls.
|
/// Creates a new `ClientTlsConfig` using Rustls.
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
pub fn with_rustls() -> Self {
|
pub fn with_rustls() -> Self {
|
||||||
Self::new(TlsProvider::Rustls)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new(provider: TlsProvider) -> Self {
|
|
||||||
ClientTlsConfig {
|
ClientTlsConfig {
|
||||||
provider,
|
|
||||||
domain: None,
|
domain: None,
|
||||||
cert: None,
|
cert: None,
|
||||||
identity: None,
|
identity: None,
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
openssl_raw: None,
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
rustls_raw: None,
|
rustls_raw: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the domain name against which to verify the server's TLS certificate.
|
/// Sets the domain name against which to verify the server's TLS certificate.
|
||||||
///
|
///
|
||||||
/// This has no effect if `rustls_client_config` or `openssl_connector` is used to configure
|
/// This has no effect if `rustls_client_config` is used to configure Rustls.
|
||||||
/// Rustls or OpenSSL respectively.
|
|
||||||
pub fn domain_name(self, domain_name: impl Into<String>) -> Self {
|
pub fn domain_name(self, domain_name: impl Into<String>) -> Self {
|
||||||
ClientTlsConfig {
|
ClientTlsConfig {
|
||||||
domain: Some(domain_name.into()),
|
domain: Some(domain_name.into()),
|
||||||
@@ -285,8 +264,7 @@ impl ClientTlsConfig {
|
|||||||
|
|
||||||
/// Sets the CA Certificate against which to verify the server's TLS certificate.
|
/// Sets the CA Certificate against which to verify the server's TLS certificate.
|
||||||
///
|
///
|
||||||
/// This has no effect if `rustls_client_config` or `openssl_connector` is used to configure
|
/// This has no effect if `rustls_client_config` is used to configure Rustls.
|
||||||
/// Rustls or OpenSSL respectively.
|
|
||||||
pub fn ca_certificate(self, ca_certificate: Certificate) -> Self {
|
pub fn ca_certificate(self, ca_certificate: Certificate) -> Self {
|
||||||
ClientTlsConfig {
|
ClientTlsConfig {
|
||||||
cert: Some(ca_certificate),
|
cert: Some(ca_certificate),
|
||||||
@@ -296,8 +274,7 @@ impl ClientTlsConfig {
|
|||||||
|
|
||||||
/// Sets the client identity to present to the server.
|
/// Sets the client identity to present to the server.
|
||||||
///
|
///
|
||||||
/// This has no effect if `rustls_client_config` or `openssl_connector` is used to configure
|
/// This has no effect if `rustls_client_config` is used to configure Rustls.
|
||||||
/// Rustls or OpenSSL respectively.
|
|
||||||
pub fn identity(self, identity: Identity) -> Self {
|
pub fn identity(self, identity: Identity) -> Self {
|
||||||
ClientTlsConfig {
|
ClientTlsConfig {
|
||||||
identity: Some(identity),
|
identity: Some(identity),
|
||||||
@@ -305,21 +282,9 @@ impl ClientTlsConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use options specified by the given `SslConnector` to configure TLS.
|
|
||||||
///
|
|
||||||
/// This overrides all other TLS options set via other means.
|
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
pub fn openssl_connector(self, connector: openssl1::ssl::SslConnector) -> Self {
|
|
||||||
ClientTlsConfig {
|
|
||||||
openssl_raw: Some(connector),
|
|
||||||
..self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Use options specified by the given `ClientConfig` to configure TLS.
|
/// Use options specified by the given `ClientConfig` to configure TLS.
|
||||||
///
|
///
|
||||||
/// This overrides all other TLS options set via other means.
|
/// This overrides all other TLS options set via other means.
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
pub fn rustls_client_config(self, config: tokio_rustls::rustls::ClientConfig) -> Self {
|
pub fn rustls_client_config(self, config: tokio_rustls::rustls::ClientConfig) -> Self {
|
||||||
ClientTlsConfig {
|
ClientTlsConfig {
|
||||||
rustls_raw: Some(config),
|
rustls_raw: Some(config),
|
||||||
@@ -332,25 +297,11 @@ impl ClientTlsConfig {
|
|||||||
None => uri.to_string(),
|
None => uri.to_string(),
|
||||||
Some(domain) => domain.clone(),
|
Some(domain) => domain.clone(),
|
||||||
};
|
};
|
||||||
match self.provider {
|
match &self.rustls_raw {
|
||||||
#[cfg(feature = "openssl")]
|
None => {
|
||||||
TlsProvider::OpenSsl => match &self.openssl_raw {
|
TlsConnector::new_with_rustls_cert(self.cert.clone(), self.identity.clone(), domain)
|
||||||
None => TlsConnector::new_with_openssl_cert(
|
}
|
||||||
self.cert.clone(),
|
Some(c) => TlsConnector::new_with_rustls_raw(c.clone(), domain),
|
||||||
self.identity.clone(),
|
|
||||||
domain,
|
|
||||||
),
|
|
||||||
Some(r) => TlsConnector::new_with_openssl_raw(r.clone(), domain),
|
|
||||||
},
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
TlsProvider::Rustls => match &self.rustls_raw {
|
|
||||||
None => TlsConnector::new_with_rustls_cert(
|
|
||||||
self.cert.clone(),
|
|
||||||
self.identity.clone(),
|
|
||||||
domain,
|
|
||||||
),
|
|
||||||
Some(c) => TlsConnector::new_with_rustls_raw(c.clone(), domain),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
//! Batteries included server and client.
|
//! Batteries included server and client.
|
||||||
//!
|
//!
|
||||||
//! This module provides a set of batteries included, fully featured and
|
//! This module provides a set of batteries included, fully featured and
|
||||||
//! fast set of HTTP/2 server and client's. These components each provide either an
|
//! fast set of HTTP/2 server and client's. These components each provide a or
|
||||||
//! `openssl` or `rustls` tls backend when the respective feature flags are enabled.
|
//! `rustls` tls backend when the respective feature flag is enabled, and
|
||||||
//!They also provide may configurable knobs that can be used to tune how they work.
|
//! provides builders to configure transport behavior.
|
||||||
//!
|
//!
|
||||||
//! # Features
|
//! # Features
|
||||||
//!
|
//!
|
||||||
//! - TLS support via either [OpenSSL] or [rustls].
|
//! - TLS support via [rustls].
|
||||||
//! - Load balancing
|
//! - Load balancing
|
||||||
//! - Timeouts
|
//! - Timeouts
|
||||||
//! - Concurrency Limits
|
//! - Concurrency Limits
|
||||||
@@ -89,7 +89,6 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! [OpenSSL]: https://www.openssl.org/
|
|
||||||
//! [rustls]: https://docs.rs/rustls/0.16.0/rustls/
|
//! [rustls]: https://docs.rs/rustls/0.16.0/rustls/
|
||||||
|
|
||||||
pub mod channel;
|
pub mod channel;
|
||||||
|
|||||||
@@ -2,11 +2,7 @@
|
|||||||
|
|
||||||
use super::service::{layer_fn, BoxedIo, Or, Routes, ServiceBuilderExt};
|
use super::service::{layer_fn, BoxedIo, Or, Routes, ServiceBuilderExt};
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
use super::{
|
use super::{service::TlsAcceptor, tls::Identity, Certificate};
|
||||||
service::TlsAcceptor,
|
|
||||||
tls::{Identity, TlsProvider},
|
|
||||||
Certificate,
|
|
||||||
};
|
|
||||||
use crate::body::BoxBody;
|
use crate::body::BoxBody;
|
||||||
use futures_core::Stream;
|
use futures_core::Stream;
|
||||||
use futures_util::{future, ready, try_future::MapErr, TryFutureExt, TryStreamExt};
|
use futures_util::{future, ready, try_future::MapErr, TryFutureExt, TryStreamExt};
|
||||||
@@ -332,48 +328,25 @@ impl fmt::Debug for Server {
|
|||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ServerTlsConfig {
|
pub struct ServerTlsConfig {
|
||||||
provider: TlsProvider,
|
|
||||||
identity: Option<Identity>,
|
identity: Option<Identity>,
|
||||||
client_ca_root: Option<Certificate>,
|
client_ca_root: Option<Certificate>,
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
openssl_raw: Option<openssl1::ssl::SslAcceptor>,
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
rustls_raw: Option<tokio_rustls::rustls::ServerConfig>,
|
rustls_raw: Option<tokio_rustls::rustls::ServerConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
impl fmt::Debug for ServerTlsConfig {
|
impl fmt::Debug for ServerTlsConfig {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("ServerTlsConfig")
|
f.debug_struct("ServerTlsConfig").finish()
|
||||||
.field("provider", &self.provider)
|
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
impl ServerTlsConfig {
|
impl ServerTlsConfig {
|
||||||
/// Creates a new `ServerTlsConfig` using OpenSSL.
|
/// Creates a new `ServerTlsConfig`.
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
pub fn with_openssl() -> Self {
|
|
||||||
Self::new(TlsProvider::OpenSsl)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new `ServerTlsConfig` using Rustls.
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
pub fn with_rustls() -> Self {
|
pub fn with_rustls() -> Self {
|
||||||
Self::new(TlsProvider::Rustls)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new `ServerTlsConfig` backed by the specified provider. Enable the `openssl` or
|
|
||||||
/// `rustls` features of the `tonic` crate to use OpenSSL or Rustls respectively.
|
|
||||||
fn new(provider: TlsProvider) -> Self {
|
|
||||||
ServerTlsConfig {
|
ServerTlsConfig {
|
||||||
provider,
|
|
||||||
identity: None,
|
identity: None,
|
||||||
client_ca_root: None,
|
client_ca_root: None,
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
openssl_raw: None,
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
rustls_raw: None,
|
rustls_raw: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,21 +367,9 @@ impl ServerTlsConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use options specified by the given `SslAcceptor` to configure TLS.
|
|
||||||
///
|
|
||||||
/// This overrides all other TLS options set via other means.
|
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
pub fn openssl_connector(self, acceptor: openssl1::ssl::SslAcceptor) -> Self {
|
|
||||||
ServerTlsConfig {
|
|
||||||
openssl_raw: Some(acceptor),
|
|
||||||
..self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Use options specified by the given `ServerConfig` to configure TLS.
|
/// Use options specified by the given `ServerConfig` to configure TLS.
|
||||||
///
|
///
|
||||||
/// This overrides all other TLS options set via other means.
|
/// This overrides all other TLS options set via other means.
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
pub fn rustls_server_config(
|
pub fn rustls_server_config(
|
||||||
&mut self,
|
&mut self,
|
||||||
config: tokio_rustls::rustls::ServerConfig,
|
config: tokio_rustls::rustls::ServerConfig,
|
||||||
@@ -418,23 +379,12 @@ impl ServerTlsConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn tls_acceptor(&self) -> Result<TlsAcceptor, crate::Error> {
|
fn tls_acceptor(&self) -> Result<TlsAcceptor, crate::Error> {
|
||||||
match self.provider {
|
match &self.rustls_raw {
|
||||||
#[cfg(feature = "openssl")]
|
None => TlsAcceptor::new_with_rustls_identity(
|
||||||
TlsProvider::OpenSsl => match &self.openssl_raw {
|
self.identity.clone().unwrap(),
|
||||||
None => TlsAcceptor::new_with_openssl_identity(
|
self.client_ca_root.clone(),
|
||||||
self.identity.clone().unwrap(),
|
),
|
||||||
self.client_ca_root.clone(),
|
Some(config) => TlsAcceptor::new_with_rustls_raw(config.clone()),
|
||||||
),
|
|
||||||
Some(acceptor) => TlsAcceptor::new_with_openssl_raw(acceptor.clone()),
|
|
||||||
},
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
TlsProvider::Rustls => match &self.rustls_raw {
|
|
||||||
None => TlsAcceptor::new_with_rustls_identity(
|
|
||||||
self.identity.clone().unwrap(),
|
|
||||||
self.client_ca_root.clone(),
|
|
||||||
),
|
|
||||||
Some(config) => TlsAcceptor::new_with_rustls_raw(config.clone()),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,18 @@
|
|||||||
use super::io::BoxedIo;
|
use super::io::BoxedIo;
|
||||||
use crate::transport::{Certificate, Identity};
|
use crate::transport::{Certificate, Identity};
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "tls-roots")]
|
||||||
use openssl1::{
|
|
||||||
pkey::PKey,
|
|
||||||
ssl::{select_next_proto, AlpnError, SslAcceptor, SslConnector, SslMethod, SslVerifyMode},
|
|
||||||
x509::{store::X509StoreBuilder, X509},
|
|
||||||
};
|
|
||||||
#[cfg(feature = "openssl-roots")]
|
|
||||||
use openssl_probe;
|
|
||||||
#[cfg(feature = "rustls-roots")]
|
|
||||||
use rustls_native_certs;
|
use rustls_native_certs;
|
||||||
use std::{fmt, sync::Arc};
|
use std::{fmt, sync::Arc};
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "tls")]
|
||||||
use tokio_rustls::{
|
use tokio_rustls::{
|
||||||
rustls::{ClientConfig, NoClientAuth, ServerConfig, Session},
|
rustls::{ClientConfig, NoClientAuth, ServerConfig, Session},
|
||||||
webpki::DNSNameRef,
|
webpki::DNSNameRef,
|
||||||
TlsAcceptor as RustlsAcceptor, TlsConnector as RustlsConnector,
|
TlsAcceptor as RustlsAcceptor, TlsConnector as RustlsConnector,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// h2 alpn in wire format for openssl.
|
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
const ALPN_H2_WIRE: &[u8] = b"\x02h2";
|
|
||||||
/// h2 alpn in plain format for rustls.
|
/// h2 alpn in plain format for rustls.
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "tls")]
|
||||||
const ALPN_H2: &str = "h2";
|
const ALPN_H2: &str = "h2";
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -37,77 +26,20 @@ pub(crate) struct Cert {
|
|||||||
enum TlsError {
|
enum TlsError {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
H2NotNegotiated,
|
H2NotNegotiated,
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "tls")]
|
||||||
CertificateParseError,
|
CertificateParseError,
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "tls")]
|
||||||
PrivateKeyParseError,
|
PrivateKeyParseError,
|
||||||
#[cfg(feature = "openssl-roots")]
|
|
||||||
TrustAnchorsConfigurationError(openssl1::error::ErrorStack),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct TlsConnector {
|
pub(crate) struct TlsConnector {
|
||||||
inner: Connector,
|
config: Arc<ClientConfig>,
|
||||||
domain: Arc<String>,
|
domain: Arc<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
enum Connector {
|
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
Openssl(SslConnector),
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
Rustls(Arc<ClientConfig>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TlsConnector {
|
impl TlsConnector {
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "tls")]
|
||||||
pub(crate) fn new_with_openssl_cert(
|
|
||||||
cert: Option<Certificate>,
|
|
||||||
identity: Option<Identity>,
|
|
||||||
domain: String,
|
|
||||||
) -> Result<Self, crate::Error> {
|
|
||||||
let mut config = SslConnector::builder(SslMethod::tls())?;
|
|
||||||
config.set_alpn_protos(ALPN_H2_WIRE)?;
|
|
||||||
|
|
||||||
#[cfg(feature = "openssl-roots")]
|
|
||||||
{
|
|
||||||
openssl_probe::init_ssl_cert_env_vars();
|
|
||||||
match config.cert_store_mut().set_default_paths() {
|
|
||||||
Ok(()) => (),
|
|
||||||
Err(e) => return Err(Box::new(TlsError::TrustAnchorsConfigurationError(e))),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(cert) = cert {
|
|
||||||
let ca = X509::from_pem(&cert.pem[..])?;
|
|
||||||
config.cert_store_mut().add_cert(ca)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(identity) = identity {
|
|
||||||
let key = PKey::private_key_from_pem(&identity.key[..])?;
|
|
||||||
let cert = X509::from_pem(&identity.cert.pem[..])?;
|
|
||||||
config.set_certificate(&cert)?;
|
|
||||||
config.set_private_key(&key)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
inner: Connector::Openssl(config.build()),
|
|
||||||
domain: Arc::new(domain),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
pub(crate) fn new_with_openssl_raw(
|
|
||||||
ssl_connector: openssl1::ssl::SslConnector,
|
|
||||||
domain: String,
|
|
||||||
) -> Result<Self, crate::Error> {
|
|
||||||
Ok(Self {
|
|
||||||
inner: Connector::Openssl(ssl_connector),
|
|
||||||
domain: Arc::new(domain),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
pub(crate) fn new_with_rustls_cert(
|
pub(crate) fn new_with_rustls_cert(
|
||||||
ca_cert: Option<Certificate>,
|
ca_cert: Option<Certificate>,
|
||||||
identity: Option<Identity>,
|
identity: Option<Identity>,
|
||||||
@@ -121,7 +53,7 @@ impl TlsConnector {
|
|||||||
config.set_single_client_cert(client_cert, client_key);
|
config.set_single_client_cert(client_cert, client_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rustls-roots")]
|
#[cfg(feature = "tls-roots")]
|
||||||
{
|
{
|
||||||
config.root_store = rustls_native_certs::load_native_certs()?;
|
config.root_store = rustls_native_certs::load_native_certs()?;
|
||||||
}
|
}
|
||||||
@@ -132,58 +64,38 @@ impl TlsConnector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
inner: Connector::Rustls(Arc::new(config)),
|
config: Arc::new(config),
|
||||||
domain: Arc::new(domain),
|
domain: Arc::new(domain),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "tls")]
|
||||||
pub(crate) fn new_with_rustls_raw(
|
pub(crate) fn new_with_rustls_raw(
|
||||||
config: tokio_rustls::rustls::ClientConfig,
|
config: tokio_rustls::rustls::ClientConfig,
|
||||||
domain: String,
|
domain: String,
|
||||||
) -> Result<Self, crate::Error> {
|
) -> Result<Self, crate::Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
inner: Connector::Rustls(Arc::new(config)),
|
config: Arc::new(config),
|
||||||
domain: Arc::new(domain),
|
domain: Arc::new(domain),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn connect(&self, io: TcpStream) -> Result<BoxedIo, crate::Error> {
|
pub(crate) async fn connect(&self, io: TcpStream) -> Result<BoxedIo, crate::Error> {
|
||||||
let tls_io = match &self.inner {
|
let tls_io = {
|
||||||
#[cfg(feature = "openssl")]
|
let dns = DNSNameRef::try_from_ascii_str(self.domain.as_str())?.to_owned();
|
||||||
Connector::Openssl(connector) => {
|
|
||||||
let config = connector.configure()?;
|
|
||||||
let tls = tokio_openssl::connect(config, &self.domain, io).await?;
|
|
||||||
|
|
||||||
match tls.ssl().selected_alpn_protocol() {
|
let io = RustlsConnector::from(self.config.clone())
|
||||||
Some(b) if b == b"h2" => tracing::trace!("HTTP/2 succesfully negotiated."),
|
.connect(dns.as_ref(), io)
|
||||||
_ => return Err(TlsError::H2NotNegotiated.into()),
|
.await?;
|
||||||
};
|
|
||||||
|
|
||||||
BoxedIo::new(tls)
|
let (_, session) = io.get_ref();
|
||||||
}
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
Connector::Rustls(config) => {
|
|
||||||
let dns = DNSNameRef::try_from_ascii_str(self.domain.as_str())
|
|
||||||
.unwrap()
|
|
||||||
.to_owned();
|
|
||||||
|
|
||||||
let io = RustlsConnector::from(config.clone())
|
match session.get_alpn_protocol() {
|
||||||
.connect(dns.as_ref(), io)
|
Some(b) if b == b"h2" => (),
|
||||||
.await?;
|
_ => return Err(TlsError::H2NotNegotiated.into()),
|
||||||
|
};
|
||||||
|
|
||||||
let (_, session) = io.get_ref();
|
BoxedIo::new(io)
|
||||||
|
|
||||||
match session.get_alpn_protocol() {
|
|
||||||
Some(b) if b == b"h2" => (),
|
|
||||||
_ => return Err(TlsError::H2NotNegotiated.into()),
|
|
||||||
};
|
|
||||||
|
|
||||||
BoxedIo::new(io)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unreachable_patterns)]
|
|
||||||
_ => unreachable!("Reached a tls config point with neither feature enabled!"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(tls_io)
|
Ok(tls_io)
|
||||||
@@ -192,79 +104,17 @@ impl TlsConnector {
|
|||||||
|
|
||||||
impl fmt::Debug for TlsConnector {
|
impl fmt::Debug for TlsConnector {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("TlsConnector")
|
f.debug_struct("TlsConnector").finish()
|
||||||
.field(
|
|
||||||
"inner",
|
|
||||||
match &self.inner {
|
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
Connector::Openssl(_) => &"Openssl",
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
Connector::Rustls(_) => &"Rustls",
|
|
||||||
|
|
||||||
#[allow(unreachable_patterns)]
|
|
||||||
_ => &"None",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct TlsAcceptor {
|
pub(crate) struct TlsAcceptor {
|
||||||
inner: Acceptor,
|
inner: Arc<ServerConfig>,
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
enum Acceptor {
|
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
Openssl(SslAcceptor),
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
Rustls(Arc<ServerConfig>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TlsAcceptor {
|
impl TlsAcceptor {
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "tls")]
|
||||||
pub(crate) fn new_with_openssl_identity(
|
|
||||||
identity: Identity,
|
|
||||||
client_ca_root: Option<Certificate>,
|
|
||||||
) -> Result<Self, crate::Error> {
|
|
||||||
let key = PKey::private_key_from_pem(&identity.key[..])?;
|
|
||||||
let cert = X509::from_pem(&identity.cert.pem[..])?;
|
|
||||||
|
|
||||||
let mut config = SslAcceptor::mozilla_modern(SslMethod::tls())?;
|
|
||||||
|
|
||||||
config.set_private_key(&key)?;
|
|
||||||
config.set_certificate(&cert)?;
|
|
||||||
config.set_alpn_protos(ALPN_H2_WIRE)?;
|
|
||||||
config.set_alpn_select_callback(|_ssl, alpn| {
|
|
||||||
select_next_proto(ALPN_H2_WIRE, alpn).ok_or(AlpnError::NOACK)
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(cert) = client_ca_root {
|
|
||||||
let ca_cert = X509::from_pem(&cert.pem[..])?;
|
|
||||||
let mut store = X509StoreBuilder::new()?;
|
|
||||||
store.add_cert(ca_cert.clone())?;
|
|
||||||
|
|
||||||
config.add_client_ca(&ca_cert)?;
|
|
||||||
config.set_verify_cert_store(store.build())?;
|
|
||||||
config.set_verify(SslVerifyMode::PEER | SslVerifyMode::FAIL_IF_NO_PEER_CERT);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
inner: Acceptor::Openssl(config.build()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
pub(crate) fn new_with_openssl_raw(
|
|
||||||
acceptor: openssl1::ssl::SslAcceptor,
|
|
||||||
) -> Result<Self, crate::Error> {
|
|
||||||
Ok(Self {
|
|
||||||
inner: Acceptor::Openssl(acceptor),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
pub(crate) fn new_with_rustls_identity(
|
pub(crate) fn new_with_rustls_identity(
|
||||||
identity: Identity,
|
identity: Identity,
|
||||||
client_ca_root: Option<Certificate>,
|
client_ca_root: Option<Certificate>,
|
||||||
@@ -291,36 +141,24 @@ impl TlsAcceptor {
|
|||||||
config.set_protocols(&[Vec::from(&ALPN_H2[..])]);
|
config.set_protocols(&[Vec::from(&ALPN_H2[..])]);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
inner: Acceptor::Rustls(Arc::new(config)),
|
inner: Arc::new(config),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "tls")]
|
||||||
pub(crate) fn new_with_rustls_raw(
|
pub(crate) fn new_with_rustls_raw(
|
||||||
config: tokio_rustls::rustls::ServerConfig,
|
config: tokio_rustls::rustls::ServerConfig,
|
||||||
) -> Result<Self, crate::Error> {
|
) -> Result<Self, crate::Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
inner: Acceptor::Rustls(Arc::new(config)),
|
inner: Arc::new(config),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn connect(&self, io: TcpStream) -> Result<BoxedIo, crate::Error> {
|
pub(crate) async fn connect(&self, io: TcpStream) -> Result<BoxedIo, crate::Error> {
|
||||||
let io = match &self.inner {
|
let io = {
|
||||||
#[cfg(feature = "openssl")]
|
let acceptor = RustlsAcceptor::from(self.inner.clone());
|
||||||
Acceptor::Openssl(acceptor) => {
|
let tls = acceptor.accept(io).await?;
|
||||||
let tls = tokio_openssl::accept(&acceptor, io).await?;
|
BoxedIo::new(tls)
|
||||||
BoxedIo::new(tls)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
Acceptor::Rustls(config) => {
|
|
||||||
let acceptor = RustlsAcceptor::from(config.clone());
|
|
||||||
let tls = acceptor.accept(io).await?;
|
|
||||||
BoxedIo::new(tls)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unreachable_patterns)]
|
|
||||||
_ => unreachable!("Reached a tls config point with neither feature enabled!"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(io)
|
Ok(io)
|
||||||
@@ -329,19 +167,7 @@ impl TlsAcceptor {
|
|||||||
|
|
||||||
impl fmt::Debug for TlsAcceptor {
|
impl fmt::Debug for TlsAcceptor {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("TlsAcceptor")
|
f.debug_struct("TlsAcceptor").finish()
|
||||||
.field(
|
|
||||||
"inner",
|
|
||||||
match &self.inner {
|
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
Acceptor::Openssl(_) => &"Openssl",
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
Acceptor::Rustls(_) => &"Rustls",
|
|
||||||
#[allow(unreachable_patterns)]
|
|
||||||
_ => &"None",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,24 +175,18 @@ impl fmt::Display for TlsError {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
TlsError::H2NotNegotiated => write!(f, "HTTP/2 was not negotiated."),
|
TlsError::H2NotNegotiated => write!(f, "HTTP/2 was not negotiated."),
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
TlsError::CertificateParseError => write!(f, "Error parsing TLS certificate."),
|
TlsError::CertificateParseError => write!(f, "Error parsing TLS certificate."),
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
TlsError::PrivateKeyParseError => write!(
|
TlsError::PrivateKeyParseError => write!(
|
||||||
f,
|
f,
|
||||||
"Error parsing TLS private key - no RSA or PKCS8-encoded keys found."
|
"Error parsing TLS private key - no RSA or PKCS8-encoded keys found."
|
||||||
),
|
),
|
||||||
#[cfg(feature = "openssl-roots")]
|
|
||||||
TlsError::TrustAnchorsConfigurationError(stack) => {
|
|
||||||
f.write_fmt(format_args!("Error adding trust anchors - {}", stack))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for TlsError {}
|
impl std::error::Error for TlsError {}
|
||||||
|
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "tls")]
|
||||||
mod rustls_keys {
|
mod rustls_keys {
|
||||||
use tokio_rustls::rustls::{internal::pemfile, Certificate, PrivateKey};
|
use tokio_rustls::rustls::{internal::pemfile, Certificate, PrivateKey};
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,3 @@
|
|||||||
/// Selects a library to provide TLS.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub(crate) enum TlsProvider {
|
|
||||||
/// Use OpenSSL for TLS.
|
|
||||||
#[cfg(feature = "openssl")]
|
|
||||||
OpenSsl,
|
|
||||||
/// Use OpenSSL for TLS.
|
|
||||||
#[cfg(feature = "rustls")]
|
|
||||||
Rustls,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a X509 certificate.
|
/// Represents a X509 certificate.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Certificate {
|
pub struct Certificate {
|
||||||
|
|||||||
Reference in New Issue
Block a user