Update to rustls 0.20

This commit is contained in:
Dirkjan Ochtman 2021-10-25 16:16:21 +02:00 committed by Benjamin Fry
parent fa59fe50ab
commit 57d0c8c0fb
20 changed files with 232 additions and 189 deletions

60
Cargo.lock generated
View File

@ -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]]

View File

@ -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"

View File

@ -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);

View File

@ -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>>(

View File

@ -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"] }

View File

@ -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()
}
}

View File

@ -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"

View File

@ -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
}
}

View File

@ -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;

View File

@ -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

View File

@ -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)
}

View File

@ -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,

View File

@ -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 }

View File

@ -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));

View File

@ -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)

View File

@ -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" }

View File

@ -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" }

View File

@ -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));

View File

@ -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))
}

View File

@ -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"] }