Update to rustls 0.20
This commit is contained in:
parent
fa59fe50ab
commit
57d0c8c0fb
60
Cargo.lock
generated
60
Cargo.lock
generated
@ -1225,15 +1225,23 @@ checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49"
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.19.1"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
|
||||
checksum = "9b5ac6078ca424dc1d3ae2328526a76787fecc7f8011f520e3276730e711fc95"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"log",
|
||||
"ring",
|
||||
"sct",
|
||||
"webpki",
|
||||
"webpki 0.22.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9"
|
||||
dependencies = [
|
||||
"base64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1254,9 +1262,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.6.1"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
|
||||
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
@ -1531,13 +1539,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.22.0"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
|
||||
checksum = "d49194a46b06a69f2498a34a595ab4a9c1babd2642ffa3dbccf6c6778d1426f2"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"tokio",
|
||||
"webpki",
|
||||
"webpki 0.22.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1600,7 +1608,7 @@ dependencies = [
|
||||
"trust-dns-proto",
|
||||
"trust-dns-resolver",
|
||||
"trust-dns-server",
|
||||
"webpki-roots",
|
||||
"webpki-roots 0.22.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1624,7 +1632,7 @@ dependencies = [
|
||||
"time",
|
||||
"tokio",
|
||||
"trust-dns-proto",
|
||||
"webpki",
|
||||
"webpki 0.22.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1666,7 +1674,7 @@ dependencies = [
|
||||
"trust-dns-proto",
|
||||
"trust-dns-resolver",
|
||||
"trust-dns-server",
|
||||
"webpki-roots",
|
||||
"webpki-roots 0.21.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1710,6 +1718,7 @@ dependencies = [
|
||||
"rand",
|
||||
"ring",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"socket2 0.4.1",
|
||||
@ -1721,8 +1730,8 @@ dependencies = [
|
||||
"tokio-rustls",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"webpki",
|
||||
"webpki-roots",
|
||||
"webpki 0.22.0",
|
||||
"webpki-roots 0.22.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1748,7 +1757,7 @@ dependencies = [
|
||||
"tokio-openssl",
|
||||
"tokio-rustls",
|
||||
"trust-dns-proto",
|
||||
"webpki-roots",
|
||||
"webpki-roots 0.22.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1985,13 +1994,32 @@ dependencies = [
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
|
||||
dependencies = [
|
||||
"webpki",
|
||||
"webpki 0.21.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c475786c6f47219345717a043a37ec04cb4bc185e28853adcc4fa0a947eba630"
|
||||
dependencies = [
|
||||
"webpki 0.22.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -74,7 +74,7 @@ path = "src/named.rs"
|
||||
clap = "2.33"
|
||||
futures = { version = "0.3.5", default-features = false, features = ["std"] }
|
||||
log = "0.4"
|
||||
rustls = { version = "0.19", optional = true }
|
||||
rustls = { version = "0.20", optional = true }
|
||||
time = "0.3"
|
||||
tokio = { version = "1.0", features = ["time"] }
|
||||
trust-dns-client = { version = "0.21.0-alpha.4", path = "../crates/client" }
|
||||
@ -87,4 +87,4 @@ native-tls = "0.2"
|
||||
regex = "1.3.4"
|
||||
trust-dns-proto = { version = "0.21.0-alpha.4", path = "../crates/proto", features = ["testing", "dns-over-native-tls"] }
|
||||
trust-dns-resolver = { version = "0.21.0-alpha.4", path = "../crates/resolver" }
|
||||
webpki-roots = "0.21"
|
||||
webpki-roots = "0.22.1"
|
||||
|
@ -19,7 +19,7 @@ use std::io::*;
|
||||
use std::net::*;
|
||||
use std::sync::Arc;
|
||||
|
||||
use rustls::{Certificate, ClientConfig, ProtocolVersion, RootCertStore};
|
||||
use rustls::{Certificate, ClientConfig, OwnedTrustAnchor, RootCertStore};
|
||||
use tokio::net::TcpStream as TokioTcpStream;
|
||||
use tokio::runtime::Runtime;
|
||||
use trust_dns_client::client::*;
|
||||
@ -56,16 +56,26 @@ fn test_example_https_toml_startup() {
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
|
||||
// using the mozilla default root store
|
||||
let mut root_store = RootCertStore::empty();
|
||||
root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
|
||||
let versions = vec![ProtocolVersion::TLSv1_2];
|
||||
root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
|
||||
OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||
ta.subject,
|
||||
ta.spki,
|
||||
ta.name_constraints,
|
||||
)
|
||||
}));
|
||||
|
||||
let cert = to_trust_anchor(&cert_der);
|
||||
root_store.add(&cert).unwrap();
|
||||
|
||||
let mut client_config = ClientConfig::new();
|
||||
client_config.root_store = root_store;
|
||||
client_config.versions = versions;
|
||||
let mut client_config = ClientConfig::builder()
|
||||
.with_safe_default_cipher_suites()
|
||||
.with_safe_default_kx_groups()
|
||||
.with_protocol_versions(&[&rustls::version::TLS12])
|
||||
.unwrap()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
client_config.alpn_protocols.push(ALPN_H2.to_vec());
|
||||
|
||||
let client_config = Arc::new(client_config);
|
||||
|
@ -21,6 +21,7 @@ use std::sync::Arc;
|
||||
|
||||
use rustls::Certificate;
|
||||
use rustls::ClientConfig;
|
||||
use rustls::RootCertStore;
|
||||
use tokio::net::TcpStream as TokioTcpStream;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
@ -55,8 +56,14 @@ fn test_example_tls_toml_startup() {
|
||||
.unwrap();
|
||||
|
||||
let cert = to_trust_anchor(&cert_der);
|
||||
let mut config = ClientConfig::new();
|
||||
config.root_store.add(&cert).expect("bad certificate");
|
||||
let mut root_store = RootCertStore::empty();
|
||||
root_store.add(&cert).expect("bad certificate");
|
||||
|
||||
let config = ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
|
||||
let config = Arc::new(config);
|
||||
|
||||
let (stream, sender) = tls_client_connect::<AsyncIoTokioAsStd<TokioTcpStream>>(
|
||||
|
@ -77,13 +77,13 @@ openssl = { version = "0.10", features = ["v102", "v110"], optional = true }
|
||||
radix_trie = "0.2.0"
|
||||
rand = "0.8"
|
||||
ring = { version = "0.16", optional = true, features = ["std"]}
|
||||
rustls = { version = "0.19", optional = true }
|
||||
rustls = { version = "0.20.0", optional = true }
|
||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
thiserror = "1.0.20"
|
||||
time = "0.3"
|
||||
tokio = { version = "1.0", features = ["rt"] }
|
||||
trust-dns-proto = { version = "0.21.0-alpha.4", path = "../proto"}
|
||||
webpki = { version = "0.21", optional = true }
|
||||
webpki = { version = "0.22.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
futures = { version = "0.3.5", default-features = false, features = ["std", "executor"] }
|
||||
|
@ -11,7 +11,7 @@ use std::marker::PhantomData;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use rustls::{Certificate, ClientConfig};
|
||||
use rustls::ClientConfig;
|
||||
use trust_dns_proto::https::{HttpsClientConnect, HttpsClientStream, HttpsClientStreamBuilder};
|
||||
use trust_dns_proto::tcp::Connect;
|
||||
|
||||
@ -24,22 +24,33 @@ use crate::client::{ClientConnection, Signer};
|
||||
pub struct HttpsClientConnection<T> {
|
||||
name_server: SocketAddr,
|
||||
dns_name: String,
|
||||
client_config: ClientConfig,
|
||||
client_config: Arc<ClientConfig>,
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> HttpsClientConnection<T> {
|
||||
/// Creates a new client connection.
|
||||
///
|
||||
/// *Note* this has side affects of binding the socket to 0.0.0.0 and starting the listening
|
||||
/// event_loop. Expect this to change in the future.
|
||||
/// *Note* this has side affects of starting the listening event_loop. Expect this to change in
|
||||
/// the future.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name_server` - address of the name server to use for queries
|
||||
/// * `name_server` - IP and Port for the remote DNS resolver
|
||||
/// * `dns_name` - The DNS name, Subject Public Key Info (SPKI) name, as associated to a certificate
|
||||
/// * `client_config` - The TLS config
|
||||
#[allow(clippy::new_ret_no_self)]
|
||||
pub fn new() -> HttpsClientConnectionBuilder {
|
||||
HttpsClientConnectionBuilder::new()
|
||||
pub fn new(
|
||||
name_server: SocketAddr,
|
||||
dns_name: String,
|
||||
client_config: Arc<ClientConfig>,
|
||||
) -> Self {
|
||||
Self {
|
||||
name_server,
|
||||
dns_name,
|
||||
client_config,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,57 +68,7 @@ where
|
||||
) -> Self::SenderFuture {
|
||||
// TODO: maybe signer needs to be applied in https...
|
||||
let https_builder =
|
||||
HttpsClientStreamBuilder::with_client_config(Arc::new(self.client_config.clone()));
|
||||
HttpsClientStreamBuilder::with_client_config(Arc::clone(&self.client_config));
|
||||
https_builder.build(self.name_server, self.dns_name.clone())
|
||||
}
|
||||
}
|
||||
|
||||
/// A helper to construct an HTTPS connection
|
||||
pub struct HttpsClientConnectionBuilder {
|
||||
client_config: ClientConfig,
|
||||
}
|
||||
|
||||
impl HttpsClientConnectionBuilder {
|
||||
/// Return a new builder for DNS-over-HTTPS
|
||||
pub fn new() -> HttpsClientConnectionBuilder {
|
||||
HttpsClientConnectionBuilder {
|
||||
client_config: ClientConfig::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs a new TlsStreamBuilder with the associated ClientConfig
|
||||
pub fn with_client_config(client_config: ClientConfig) -> Self {
|
||||
HttpsClientConnectionBuilder { client_config }
|
||||
}
|
||||
|
||||
/// Add a custom trusted peer certificate or certificate authority.
|
||||
///
|
||||
/// If this is the 'client' then the 'server' must have it associated as it's `identity`, or have had the `identity` signed by this certificate.
|
||||
pub fn add_ca(&mut self, ca: Certificate) {
|
||||
self.client_config
|
||||
.root_store
|
||||
.add(&ca)
|
||||
.expect("bad certificate!");
|
||||
}
|
||||
|
||||
/// Creates a new HttpsStream to the specified name_server
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name_server` - IP and Port for the remote DNS resolver
|
||||
/// * `dns_name` - The DNS name, Subject Public Key Info (SPKI) name, as associated to a certificate
|
||||
pub fn build<T>(self, name_server: SocketAddr, dns_name: String) -> HttpsClientConnection<T> {
|
||||
HttpsClientConnection {
|
||||
name_server,
|
||||
dns_name,
|
||||
client_config: self.client_config,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HttpsClientConnectionBuilder {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ maintenance = { status = "actively-developed" }
|
||||
|
||||
[features]
|
||||
dns-over-tls = []
|
||||
dns-over-rustls = ["dns-over-tls", "rustls", "tokio-rustls", "webpki"]
|
||||
dns-over-rustls = ["dns-over-tls", "rustls", "rustls-pemfile", "tokio-rustls", "webpki"]
|
||||
dns-over-native-tls = ["dns-over-tls", "native-tls", "tokio-native-tls"]
|
||||
dns-over-openssl = ["dns-over-tls", "openssl", "tokio-openssl"]
|
||||
|
||||
@ -88,7 +88,8 @@ native-tls = { version = "0.2", optional = true }
|
||||
openssl = { version = "0.10", features = ["v102", "v110"], optional = true }
|
||||
rand = "0.8"
|
||||
ring = { version = "0.16", optional = true, features = ["std"] }
|
||||
rustls = { version = "0.19", optional = true }
|
||||
rustls = { version = "0.20.0", optional = true }
|
||||
rustls-pemfile = { version = "0.2.1", optional = true }
|
||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
smallvec = "1.6"
|
||||
socket2 = { version = "0.4.0", optional = true }
|
||||
@ -97,11 +98,11 @@ tinyvec = { version = "1.1.1", features = ["alloc"] }
|
||||
tokio = { version = "1.0", features = ["io-util"], optional = true }
|
||||
tokio-native-tls = { version = "0.3.0", optional = true }
|
||||
tokio-openssl = { version = "0.6.0", optional = true }
|
||||
tokio-rustls = { version = "0.22", optional = true, features = ["early-data"] }
|
||||
tokio-rustls = { version = "0.23.0", optional = true, features = ["early-data"] }
|
||||
url = "2.1.0"
|
||||
wasm-bindgen-crate = { version = "0.2.58", optional = true, package = "wasm-bindgen" }
|
||||
webpki = { version = "0.21", optional = true }
|
||||
webpki-roots = { version = "0.21", optional = true }
|
||||
webpki = { version = "0.22.0", optional = true }
|
||||
webpki-roots = { version = "0.22.1", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.9"
|
||||
|
@ -5,6 +5,7 @@
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::{self, Display};
|
||||
use std::future::Future;
|
||||
use std::io;
|
||||
@ -26,7 +27,6 @@ use rustls::ClientConfig;
|
||||
use tokio_rustls::{
|
||||
client::TlsStream as TokioTlsClientStream, Connect as TokioTlsConnect, TlsConnector,
|
||||
};
|
||||
use webpki::DNSNameRef;
|
||||
|
||||
use crate::error::ProtoError;
|
||||
use crate::iocompat::AsyncIoStdAsTokio;
|
||||
@ -285,16 +285,6 @@ pub struct HttpsClientStreamBuilder {
|
||||
}
|
||||
|
||||
impl HttpsClientStreamBuilder {
|
||||
/// Return a new builder for DNS-over-HTTPS
|
||||
pub fn new() -> HttpsClientStreamBuilder {
|
||||
let mut client_config = ClientConfig::new();
|
||||
client_config.alpn_protocols.push(ALPN_H2.to_vec());
|
||||
|
||||
HttpsClientStreamBuilder {
|
||||
client_config: Arc::new(client_config),
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs a new TlsStreamBuilder with the associated ClientConfig
|
||||
pub fn with_client_config(client_config: Arc<ClientConfig>) -> Self {
|
||||
HttpsClientStreamBuilder { client_config }
|
||||
@ -329,12 +319,6 @@ impl HttpsClientStreamBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HttpsClientStreamBuilder {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// A future that resolves to an HttpsClientStream
|
||||
pub struct HttpsClientConnect<S>(HttpsClientConnectState<S>)
|
||||
where
|
||||
@ -430,10 +414,9 @@ where
|
||||
let tls = tls
|
||||
.take()
|
||||
.expect("programming error, tls should not be None here");
|
||||
let dns_name = tls.dns_name;
|
||||
let name_server_name = Arc::clone(&dns_name);
|
||||
let name_server_name = Arc::clone(&tls.dns_name);
|
||||
|
||||
match DNSNameRef::try_from_ascii_str(&dns_name) {
|
||||
match tls.dns_name.as_ref().try_into() {
|
||||
Ok(dns_name) => {
|
||||
let tls = TlsConnector::from(tls.client_config);
|
||||
let tls = tls.connect(dns_name, AsyncIoStdAsTokio(tcp));
|
||||
@ -444,7 +427,7 @@ where
|
||||
}
|
||||
}
|
||||
Err(_) => HttpsClientConnectState::Errored(Some(ProtoError::from(
|
||||
format!("bad dns_name: {}", dns_name),
|
||||
format!("bad dns_name: {}", &tls.dns_name),
|
||||
))),
|
||||
}
|
||||
}
|
||||
@ -520,10 +503,9 @@ mod tests {
|
||||
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
|
||||
use std::str::FromStr;
|
||||
|
||||
use rustls::{ClientConfig, KeyLogFile, ProtocolVersion, RootCertStore};
|
||||
use rustls::KeyLogFile;
|
||||
use tokio::net::TcpStream as TokioTcpStream;
|
||||
use tokio::runtime::Runtime;
|
||||
use webpki_roots;
|
||||
|
||||
use crate::iocompat::AsyncIoTokioAsStd;
|
||||
use crate::op::{Message, Query, ResponseCode};
|
||||
@ -543,15 +525,7 @@ mod tests {
|
||||
|
||||
let request = DnsRequest::new(request, Default::default());
|
||||
|
||||
// using the mozilla default root store
|
||||
let mut root_store = RootCertStore::empty();
|
||||
root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
|
||||
let versions = vec![ProtocolVersion::TLSv1_2];
|
||||
|
||||
let mut client_config = ClientConfig::new();
|
||||
client_config.root_store = root_store;
|
||||
client_config.versions = versions;
|
||||
client_config.alpn_protocols.push(ALPN_H2.to_vec());
|
||||
let mut client_config = client_config_tls12_webpki_roots();
|
||||
client_config.key_log = Arc::new(KeyLogFile::new());
|
||||
|
||||
let https_builder = HttpsClientStreamBuilder::with_client_config(Arc::new(client_config));
|
||||
@ -619,16 +593,7 @@ mod tests {
|
||||
|
||||
let request = DnsRequest::new(request, Default::default());
|
||||
|
||||
// using the mozilla default root store
|
||||
let mut root_store = RootCertStore::empty();
|
||||
root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
|
||||
let versions = vec![ProtocolVersion::TLSv1_2];
|
||||
|
||||
let mut client_config = ClientConfig::new();
|
||||
client_config.root_store = root_store;
|
||||
client_config.versions = versions;
|
||||
client_config.alpn_protocols.push(ALPN_H2.to_vec());
|
||||
|
||||
let client_config = client_config_tls12_webpki_roots();
|
||||
let https_builder = HttpsClientStreamBuilder::with_client_config(Arc::new(client_config));
|
||||
let connect = https_builder.build::<AsyncIoTokioAsStd<TokioTcpStream>>(
|
||||
cloudflare,
|
||||
@ -678,4 +643,27 @@ mod tests {
|
||||
&Ipv6Addr::new(0x2606, 0x2800, 0x0220, 0x0001, 0x0248, 0x1893, 0x25c8, 0x1946)
|
||||
);
|
||||
}
|
||||
|
||||
fn client_config_tls12_webpki_roots() -> ClientConfig {
|
||||
use rustls::{OwnedTrustAnchor, RootCertStore};
|
||||
let mut root_store = RootCertStore::empty();
|
||||
root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
|
||||
OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||
ta.subject,
|
||||
ta.spki,
|
||||
ta.name_constraints,
|
||||
)
|
||||
}));
|
||||
|
||||
let mut client_config = ClientConfig::builder()
|
||||
.with_safe_default_cipher_suites()
|
||||
.with_safe_default_kx_groups()
|
||||
.with_protocol_versions(&[&rustls::version::TLS12])
|
||||
.unwrap()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
|
||||
client_config.alpn_protocols = vec![ALPN_H2.to_vec()];
|
||||
client_config
|
||||
}
|
||||
}
|
||||
|
@ -15,4 +15,4 @@ pub use self::tls_client_stream::{tls_client_connect, TlsClientStream};
|
||||
pub use self::tls_stream::{tls_connect, tls_from_stream, TlsStream};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
pub(crate) mod tests;
|
||||
|
@ -24,7 +24,6 @@ use openssl::x509::store::X509StoreBuilder;
|
||||
use openssl::x509::*;
|
||||
|
||||
use futures_util::stream::StreamExt;
|
||||
use rustls::Certificate;
|
||||
use rustls::ClientConfig;
|
||||
use tokio::net::TcpStream as TokioTcpStream;
|
||||
use tokio::runtime::Runtime;
|
||||
@ -201,13 +200,13 @@ fn tls_client_stream_test(server_addr: IpAddr, mtls: bool) {
|
||||
// TODO: add timeout here, so that test never hangs...
|
||||
// let timeout = Timeout::new(Duration::from_secs(5));
|
||||
|
||||
let trust_chain = Certificate(root_cert_der);
|
||||
|
||||
let mut config = ClientConfig::new();
|
||||
config
|
||||
.root_store
|
||||
.add(&trust_chain)
|
||||
.expect("bad certificate!");
|
||||
let mut roots = rustls::RootCertStore::empty();
|
||||
let (_, ignored) = roots.add_parsable_certificates(&[root_cert_der]);
|
||||
assert_eq!(ignored, 0, "bad certificate!");
|
||||
let mut config = ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates(roots)
|
||||
.with_no_client_auth();
|
||||
|
||||
// barrier.wait();
|
||||
// fix MTLS
|
||||
|
@ -12,8 +12,8 @@ use std::io::{BufReader, Read};
|
||||
use std::path::Path;
|
||||
|
||||
use log::warn;
|
||||
use rustls::internal::pemfile::{certs, pkcs8_private_keys};
|
||||
use rustls::{self, Certificate, PrivateKey, ServerConfig};
|
||||
use rustls_pemfile::{certs, pkcs8_private_keys};
|
||||
|
||||
use crate::error::{ProtoError, ProtoResult};
|
||||
|
||||
@ -25,20 +25,29 @@ pub fn read_cert(cert_path: &Path) -> ProtoResult<Vec<Certificate>> {
|
||||
.map_err(|e| format!("error opening cert file: {:?}: {}", cert_path, e))?;
|
||||
|
||||
let mut reader = BufReader::new(&mut cert_file);
|
||||
certs(&mut reader).map_err(|()| {
|
||||
ProtoError::from(format!(
|
||||
match certs(&mut reader) {
|
||||
Ok(certs) => Ok(certs.into_iter().map(Certificate).collect()),
|
||||
Err(_) => Err(ProtoError::from(format!(
|
||||
"failed to read certs from: {}",
|
||||
cert_path.display()
|
||||
))
|
||||
})
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads a private key from a pkcs8 formatted, and possibly encoded file
|
||||
pub fn read_key_from_pkcs8(path: &Path) -> ProtoResult<PrivateKey> {
|
||||
let mut file = BufReader::new(File::open(path)?);
|
||||
|
||||
let mut keys: Vec<PrivateKey> = pkcs8_private_keys(&mut file)
|
||||
.map_err(|()| ProtoError::from(format!("failed to read keys from: {}", path.display())))?;
|
||||
let mut keys = match pkcs8_private_keys(&mut file) {
|
||||
Ok(keys) => keys.into_iter().map(PrivateKey).collect::<Vec<_>>(),
|
||||
Err(_) => {
|
||||
return Err(ProtoError::from(format!(
|
||||
"failed to read keys from: {}",
|
||||
path.display()
|
||||
)))
|
||||
}
|
||||
};
|
||||
|
||||
match keys.len() {
|
||||
0 => return Err(format!("no keys available in: {}", path.display()).into()),
|
||||
1 => (),
|
||||
@ -65,23 +74,25 @@ pub fn read_key_from_pem(path: &Path) -> ProtoResult<PrivateKey> {
|
||||
let file = File::open(path)?;
|
||||
let mut file = BufReader::new(file);
|
||||
|
||||
let mut keys = rustls::internal::pemfile::rsa_private_keys(&mut file)
|
||||
let mut keys = rustls_pemfile::rsa_private_keys(&mut file)
|
||||
.map_err(|_| format!("Error reading RSA key from: {}", path.display()))?;
|
||||
let key = keys
|
||||
.pop()
|
||||
.ok_or_else(|| format!("No RSA keys in file: {}", path.display()))?;
|
||||
|
||||
Ok(key)
|
||||
Ok(PrivateKey(key))
|
||||
}
|
||||
|
||||
/// Construct the new Acceptor with the associated pkcs12 data
|
||||
pub fn new_acceptor(
|
||||
cert: Vec<Certificate>,
|
||||
key: PrivateKey,
|
||||
) -> Result<ServerConfig, rustls::TLSError> {
|
||||
let mut config = ServerConfig::new(rustls::NoClientAuth::new());
|
||||
config.set_protocols(&[b"h2".to_vec()]);
|
||||
config.set_single_cert(cert, key)?;
|
||||
) -> Result<ServerConfig, rustls::Error> {
|
||||
let mut config = ServerConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_no_client_auth()
|
||||
.with_single_cert(cert, key)?;
|
||||
|
||||
config.alpn_protocols = vec![b"h2".to_vec()];
|
||||
Ok(config)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
//! DNS over TLS I/O stream implementation for Rustls
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::future::Future;
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
@ -18,7 +19,6 @@ use rustls::ClientConfig;
|
||||
use tokio;
|
||||
use tokio::net::TcpStream as TokioTcpStream;
|
||||
use tokio_rustls::TlsConnector;
|
||||
use webpki::{DNSName, DNSNameRef};
|
||||
|
||||
use crate::iocompat::{AsyncIoStdAsTokio, AsyncIoTokioAsStd};
|
||||
use crate::tcp::Connect;
|
||||
@ -113,12 +113,13 @@ async fn connect_tls<S: Connect>(
|
||||
) -> io::Result<TcpStream<AsyncIoTokioAsStd<TokioTlsClientStream<S>>>> {
|
||||
let tcp = S::connect(name_server).await?;
|
||||
|
||||
let dns_name = DNSNameRef::try_from_ascii_str(&dns_name)
|
||||
.map(DNSName::from)
|
||||
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "bad dns_name"))?;
|
||||
let dns_name = match dns_name.as_str().try_into() {
|
||||
Ok(name) => name,
|
||||
Err(_) => return Err(io::Error::new(io::ErrorKind::InvalidInput, "bad dns_name")),
|
||||
};
|
||||
|
||||
let s = tls_connector
|
||||
.connect(dns_name.as_ref(), AsyncIoStdAsTokio(tcp))
|
||||
.connect(dns_name, AsyncIoStdAsTokio(tcp))
|
||||
.map_err(|e| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::ConnectionRefused,
|
||||
|
@ -74,16 +74,16 @@ log = "0.4"
|
||||
lru-cache = "0.1.2"
|
||||
parking_lot = "0.11"
|
||||
resolv-conf = { version = "0.7.0", optional = true, features = ["system"] }
|
||||
rustls = {version = "0.19", optional = true}
|
||||
rustls = { version = "0.20.0", optional = true }
|
||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
smallvec = "1.6"
|
||||
thiserror = "1.0.20"
|
||||
tokio = { version = "1.0", optional = true }
|
||||
tokio-native-tls = { version = "0.3", optional = true }
|
||||
tokio-openssl = { version = "0.6.0", optional = true }
|
||||
tokio-rustls = { version = "0.22", optional = true }
|
||||
tokio-rustls = { version = "0.23.0", optional = true }
|
||||
trust-dns-proto = { version = "0.21.0-alpha.4", path = "../proto", default-features = false }
|
||||
webpki-roots = { version = "0.21", optional = true }
|
||||
webpki-roots = { version = "0.22.1", optional = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
ipconfig = { version = "0.2.2", optional = true }
|
||||
|
@ -223,17 +223,26 @@ impl ResolverConfig {
|
||||
/// ```
|
||||
/// use std::sync::Arc;
|
||||
///
|
||||
/// use rustls::{ClientConfig, ProtocolVersion, RootCertStore};
|
||||
/// use rustls::{ClientConfig, ProtocolVersion, RootCertStore, OwnedTrustAnchor};
|
||||
/// use trust_dns_resolver::config::ResolverConfig;
|
||||
/// use webpki_roots;
|
||||
///
|
||||
/// let mut root_store = RootCertStore::empty();
|
||||
/// root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
|
||||
/// let versions = vec![ProtocolVersion::TLSv1_2];
|
||||
/// root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
|
||||
/// OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||
/// ta.subject,
|
||||
/// ta.spki,
|
||||
/// ta.name_constraints,
|
||||
/// )
|
||||
/// }));
|
||||
///
|
||||
/// let mut client_config = ClientConfig::new();
|
||||
/// client_config.root_store = root_store;
|
||||
/// client_config.versions = versions;
|
||||
/// let mut client_config = ClientConfig::builder()
|
||||
/// .with_safe_default_cipher_suites()
|
||||
/// .with_safe_default_kx_groups()
|
||||
/// .with_protocol_versions(&[&rustls::version::TLS12])
|
||||
/// .unwrap()
|
||||
/// .with_root_certificates(root_store)
|
||||
/// .with_no_client_auth();
|
||||
///
|
||||
/// let mut resolver_config = ResolverConfig::quad9_tls();
|
||||
/// resolver_config.set_tls_client_config(Arc::new(client_config));
|
||||
|
@ -13,7 +13,7 @@ use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
|
||||
use futures_util::future::Future;
|
||||
use rustls::{ClientConfig, ProtocolVersion, RootCertStore};
|
||||
use rustls::{ClientConfig, OwnedTrustAnchor, RootCertStore};
|
||||
|
||||
use proto::error::ProtoError;
|
||||
use proto::rustls::{tls_client_connect, TlsClientStream};
|
||||
@ -28,12 +28,22 @@ lazy_static! {
|
||||
// using the mozilla default root store
|
||||
pub(crate) static ref CLIENT_CONFIG: Arc<ClientConfig> = {
|
||||
let mut root_store = RootCertStore::empty();
|
||||
root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
|
||||
let versions = vec![ProtocolVersion::TLSv1_2];
|
||||
root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
|
||||
OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||
ta.subject,
|
||||
ta.spki,
|
||||
ta.name_constraints,
|
||||
)
|
||||
}));
|
||||
|
||||
let mut client_config = ClientConfig::builder()
|
||||
.with_safe_default_cipher_suites()
|
||||
.with_safe_default_kx_groups()
|
||||
.with_protocol_versions(&[&rustls::version::TLS12])
|
||||
.unwrap()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
|
||||
let mut client_config = ClientConfig::new();
|
||||
client_config.root_store = root_store;
|
||||
client_config.versions = versions;
|
||||
client_config.alpn_protocols.push(ALPN_H2.to_vec());
|
||||
|
||||
Arc::new(client_config)
|
||||
|
@ -85,13 +85,13 @@ http = { version = "0.2", optional = true }
|
||||
log = "0.4"
|
||||
openssl = { version = "0.10", features = ["v102", "v110"], optional = true }
|
||||
rusqlite = { version = "0.26.1", features = ["bundled", "time"], optional = true }
|
||||
rustls = { version = "0.19", optional = true }
|
||||
rustls = { version = "0.20", optional = true }
|
||||
serde = { version = "1.0.114", features = ["derive"] }
|
||||
thiserror = "1.0.20"
|
||||
time = "0.3"
|
||||
tokio = { version = "1.0", features = ["net"] }
|
||||
tokio-openssl = { version = "0.6.0", optional = true }
|
||||
tokio-rustls = { version = "0.22", optional = true }
|
||||
tokio-rustls = { version = "0.23.0", optional = true }
|
||||
toml = "0.5"
|
||||
trust-dns-client= { version = "0.21.0-alpha.4", path = "../client" }
|
||||
trust-dns-proto = { version = "0.21.0-alpha.4", path = "../proto" }
|
||||
|
@ -77,7 +77,7 @@ futures = "0.3.5"
|
||||
openssl = { version = "0.10", features = ["v102", "v110"] }
|
||||
rand = "0.8"
|
||||
rusqlite = { version = "0.26.0", features = ["bundled"] }
|
||||
rustls = "0.19"
|
||||
rustls = "0.20"
|
||||
time = "0.3"
|
||||
tokio = { version = "1.0", features = ["time", "rt"] }
|
||||
trust-dns-client= { version = "0.21.0-alpha.4", path = "../../crates/client" }
|
||||
|
@ -128,7 +128,7 @@ fn test_query_tcp_ipv6() {
|
||||
#[test]
|
||||
#[cfg(feature = "dns-over-https-rustls")]
|
||||
fn test_query_https() {
|
||||
use rustls::{ClientConfig, ProtocolVersion, RootCertStore};
|
||||
use rustls::{ClientConfig, OwnedTrustAnchor, RootCertStore};
|
||||
use trust_dns_proto::https::HttpsClientStreamBuilder;
|
||||
|
||||
const ALPN_H2: &[u8] = b"h2";
|
||||
@ -138,12 +138,21 @@ fn test_query_https() {
|
||||
|
||||
// using the mozilla default root store
|
||||
let mut root_store = RootCertStore::empty();
|
||||
root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
|
||||
let versions = vec![ProtocolVersion::TLSv1_2];
|
||||
root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
|
||||
OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||
ta.subject,
|
||||
ta.spki,
|
||||
ta.name_constraints,
|
||||
)
|
||||
}));
|
||||
|
||||
let mut client_config = ClientConfig::new();
|
||||
client_config.root_store = root_store;
|
||||
client_config.versions = versions;
|
||||
let mut client_config = ClientConfig::builder()
|
||||
.with_safe_default_cipher_suites()
|
||||
.with_safe_default_kx_groups()
|
||||
.with_protocol_versions(&[&rustls::version::TLS12])
|
||||
.unwrap()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
client_config.alpn_protocols.push(ALPN_H2.to_vec());
|
||||
|
||||
let https_builder = HttpsClientStreamBuilder::with_client_config(Arc::new(client_config));
|
||||
|
@ -23,6 +23,8 @@ use trust_dns_server::ServerFuture;
|
||||
|
||||
use trust_dns_integration::authority::create_example;
|
||||
|
||||
#[cfg(feature = "dns-over-rustls")]
|
||||
use rustls::RootCertStore;
|
||||
#[cfg(feature = "dns-over-rustls")]
|
||||
use trust_dns_integration::tls_client_connection::TlsClientConnection;
|
||||
|
||||
@ -266,11 +268,18 @@ fn lazy_tls_client(
|
||||
) -> TlsClientConnection<trust_dns_proto::iocompat::AsyncIoTokioAsStd<tokio::net::TcpStream>> {
|
||||
use rustls::ClientConfig;
|
||||
|
||||
let mut config = ClientConfig::new();
|
||||
let mut root_store = RootCertStore::empty();
|
||||
let der_certs = cert_chain.into_iter().map(|cert| cert.0).collect::<Vec<_>>();
|
||||
let (_, ignored) = root_store.add_parsable_certificates(&der_certs);
|
||||
assert_eq!(ignored, 0, "bad certificate!");
|
||||
|
||||
for cert in cert_chain {
|
||||
config.root_store.add(&cert).expect("bad certificate");
|
||||
}
|
||||
let config = ClientConfig::builder()
|
||||
.with_safe_default_cipher_suites()
|
||||
.with_safe_default_kx_groups()
|
||||
.with_protocol_versions(&[&rustls::version::TLS12])
|
||||
.unwrap()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
|
||||
TlsClientConnection::new(ipaddr, dns_name, Arc::new(config))
|
||||
}
|
||||
|
@ -65,4 +65,4 @@ trust-dns-resolver = { version = "0.21.0-alpha.4", features = ["dnssec-openssl"]
|
||||
log = "0.4"
|
||||
openssl = { version = "0.10", features = ["v102", "v110"] }
|
||||
structopt = "0.3"
|
||||
tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] }
|
||||
tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] }
|
||||
|
Loading…
Reference in New Issue
Block a user