Merge pull request #217 from dnaka91/root-certs-feature-flags

Enable root cert providers through feature flags
pull/221/head
Daniel Abramov 3 years ago committed by GitHub
commit 5462b3b986
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      CHANGELOG.md
  2. 11
      Cargo.toml
  3. 24
      src/client.rs
  4. 4
      src/error.rs
  5. 4
      src/stream.rs
  6. 11
      tests/connection_reset.rs

@ -1,3 +1,14 @@
# 0.15.0 (unreleased)
- Allow selecting the method of loading root certificates if `rustls` is used as TLS implementation.
- Two new feature flags `rustls-tls-native-roots` and `rustls-tls-webpki-roots` have been added
that activate the respective method to load certificates.
- The `rustls-tls` flag was removed to raise awareness of this change. Otherwise, compilation
would have continue to work and potential errors (due to different or missing certificates)
only occurred at runtime.
- The new feature flags are additive. If both are enabled, both methods will be used to add
certificates to the TLS configuration.
# 0.14.0 # 0.14.0
- Use `rustls-native-certs` instead of `webpki-root` when `rustls-tls` feature is enabled. - Use `rustls-native-certs` instead of `webpki-root` when `rustls-tls` feature is enabled.

@ -19,7 +19,8 @@ all-features = true
default = [] default = []
native-tls = ["native-tls-crate"] native-tls = ["native-tls-crate"]
native-tls-vendored = ["native-tls", "native-tls-crate/vendored"] native-tls-vendored = ["native-tls", "native-tls-crate/vendored"]
rustls-tls = ["rustls", "webpki", "rustls-native-certs"] rustls-tls-native-roots = ["rustls", "webpki", "rustls-native-certs"]
rustls-tls-webpki-roots = ["rustls", "webpki", "webpki-roots"]
[dependencies] [dependencies]
base64 = "0.13.0" base64 = "0.13.0"
@ -43,13 +44,17 @@ version = "0.2.3"
optional = true optional = true
version = "0.19.0" version = "0.19.0"
[dependencies.rustls-native-certs]
optional = true
version = "0.5.0"
[dependencies.webpki] [dependencies.webpki]
optional = true optional = true
version = "0.21" version = "0.21"
[dependencies.rustls-native-certs] [dependencies.webpki-roots]
optional = true optional = true
version = "0.5.0" version = "0.21"
[dev-dependencies] [dev-dependencies]
criterion = "0.3.4" criterion = "0.3.4"

@ -50,7 +50,10 @@ mod encryption {
} }
} }
#[cfg(all(feature = "rustls-tls", not(feature = "native-tls")))] #[cfg(all(
any(feature = "rustls-tls-native-roots", feature = "rustls-tls-webpki-roots"),
not(feature = "native-tls")
))]
mod encryption { mod encryption {
use rustls::ClientConfig; use rustls::ClientConfig;
pub use rustls::{ClientSession, StreamOwned}; pub use rustls::{ClientSession, StreamOwned};
@ -71,12 +74,21 @@ mod encryption {
Mode::Plain => Ok(StreamSwitcher::Plain(stream)), Mode::Plain => Ok(StreamSwitcher::Plain(stream)),
Mode::Tls => { Mode::Tls => {
let config = { let config = {
#[allow(unused_mut)]
let mut config = ClientConfig::new(); let mut config = ClientConfig::new();
config.root_store = #[cfg(feature = "rustls-tls-native-roots")]
rustls_native_certs::load_native_certs().map_err(|(_, err)| err)?; {
config.root_store =
rustls_native_certs::load_native_certs().map_err(|(_, err)| err)?;
}
#[cfg(feature = "rustls-tls-webpki-roots")]
{
config.root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
}
Arc::new(config) Arc::new(config)
}; };
let domain = DNSNameRef::try_from_ascii_str(domain).map_err(TlsError::Dns)?; let domain = DNSNameRef::try_from_ascii_str(domain).map_err(TlsError::Dns)?;
let client = ClientSession::new(&config, domain); let client = ClientSession::new(&config, domain);
let stream = StreamOwned::new(client, stream); let stream = StreamOwned::new(client, stream);
@ -87,7 +99,11 @@ mod encryption {
} }
} }
#[cfg(not(any(feature = "native-tls", feature = "rustls-tls")))] #[cfg(not(any(
feature = "native-tls",
feature = "rustls-tls-native-roots",
feature = "rustls-tls-webpki-roots"
)))]
mod encryption { mod encryption {
use std::net::TcpStream; use std::net::TcpStream;

@ -253,11 +253,11 @@ pub enum TlsError {
#[error("native-tls error: {0}")] #[error("native-tls error: {0}")]
Native(#[from] native_tls_crate::Error), Native(#[from] native_tls_crate::Error),
/// Rustls error. /// Rustls error.
#[cfg(feature = "rustls-tls")] #[cfg(any(feature = "rustls-tls-native-roots", feature = "rustls-tls-webpki-roots"))]
#[error("rustls error: {0}")] #[error("rustls error: {0}")]
Rustls(#[from] rustls::TLSError), Rustls(#[from] rustls::TLSError),
/// DNS name resolution error. /// DNS name resolution error.
#[cfg(feature = "rustls-tls")] #[cfg(any(feature = "rustls-tls-native-roots", feature = "rustls-tls-webpki-roots"))]
#[error("Invalid DNS name: {0}")] #[error("Invalid DNS name: {0}")]
Dns(#[from] webpki::InvalidDNSNameError), Dns(#[from] webpki::InvalidDNSNameError),
} }

@ -10,7 +10,7 @@ use std::net::TcpStream;
#[cfg(feature = "native-tls")] #[cfg(feature = "native-tls")]
use native_tls_crate::TlsStream; use native_tls_crate::TlsStream;
#[cfg(feature = "rustls-tls")] #[cfg(any(feature = "rustls-tls-native-roots", feature = "rustls-tls-webpki-roots"))]
use rustls::StreamOwned; use rustls::StreamOwned;
/// Stream mode, either plain TCP or TLS. /// Stream mode, either plain TCP or TLS.
@ -41,7 +41,7 @@ impl<S: Read + Write + NoDelay> NoDelay for TlsStream<S> {
} }
} }
#[cfg(feature = "rustls-tls")] #[cfg(any(feature = "rustls-tls-native-roots", feature = "rustls-tls-webpki-roots"))]
impl<S: rustls::Session, T: Read + Write + NoDelay> NoDelay for StreamOwned<S, T> { impl<S: rustls::Session, T: Read + Write + NoDelay> NoDelay for StreamOwned<S, T> {
fn set_nodelay(&mut self, nodelay: bool) -> IoResult<()> { fn set_nodelay(&mut self, nodelay: bool) -> IoResult<()> {
self.sock.set_nodelay(nodelay) self.sock.set_nodelay(nodelay)

@ -1,6 +1,10 @@
//! Verifies that the server returns a `ConnectionClosed` error when the connection //! Verifies that the server returns a `ConnectionClosed` error when the connection
//! is closed from the server's point of view and drop the underlying tcp socket. //! is closed from the server's point of view and drop the underlying tcp socket.
#![cfg(any(feature = "native-tls", feature = "rustls-tls"))] #![cfg(any(
feature = "native-tls",
feature = "rustls-tls-native-roots",
feature = "rustls-tls-webpki-roots"
))]
use std::{ use std::{
net::{TcpListener, TcpStream}, net::{TcpListener, TcpStream},
@ -15,7 +19,10 @@ use url::Url;
#[cfg(feature = "native-tls")] #[cfg(feature = "native-tls")]
type Sock = WebSocket<Stream<TcpStream, native_tls_crate::TlsStream<TcpStream>>>; type Sock = WebSocket<Stream<TcpStream, native_tls_crate::TlsStream<TcpStream>>>;
#[cfg(all(feature = "rustls-tls", not(feature = "native-tls")))] #[cfg(all(
any(feature = "rustls-tls-native-roots", feature = "rustls-tls-webpki-roots"),
not(feature = "native-tls")
))]
type Sock = WebSocket<Stream<TcpStream, rustls::StreamOwned<rustls::ClientSession, TcpStream>>>; type Sock = WebSocket<Stream<TcpStream, rustls::StreamOwned<rustls::ClientSession, TcpStream>>>;
fn do_test<CT, ST>(port: u16, client_task: CT, server_task: ST) fn do_test<CT, ST>(port: u16, client_task: CT, server_task: ST)

Loading…
Cancel
Save