linux support for DNS over TLS

This commit is contained in:
Benjamin Fry 2017-02-09 00:35:44 -08:00
parent 9ae4f3eef2
commit d409317e88
12 changed files with 208 additions and 86 deletions

View File

@ -12,6 +12,7 @@ and reliable implementation. It was attempted to make the move seamless,
but two new types were introduced, `SyncClient` and `SecureSyncClient`, which
are both synchronous implementations of the old Client function interfaces.
Please read those docs on those new types and the Client trait.
- When EDNS option is present, return only the digest understood matching RRSETs
### Removed
- *Important* The original Server implementation was removed entirely. Please
@ -20,9 +21,10 @@ but this is necessary to make sure that the software remains at a high quality
and there is no easy way to migrate the original Server to use ServerFuture.
### Added
- support for ECDSAP256SHA256, ECDSAP384SHA384 and ED25519 (client and server)
- Initial support for ECDSAP256SHA256, ECDSAP384SHA384 and ED25519 (client and server)
- additional config options for keys to named, see `tests/named_test_configs/example.toml`
- When EDNS option is present, return only the digest understood matching RRSETs
- Added DNS over TLS support, RFC 7858, #38
- Added native-tls with support for macOS and Linux (DNS over TLS)
## 0.9.3
### Changed

36
Cargo.lock generated
View File

@ -6,7 +6,7 @@ dependencies = [
"chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
"docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -44,7 +44,7 @@ name = "backtrace"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -55,10 +55,10 @@ dependencies = [
[[package]]
name = "backtrace-sys"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -147,7 +147,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures"
version = "0.1.9"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -155,7 +155,7 @@ dependencies = [
[[package]]
name = "gcc"
version = "0.3.42"
version = "0.3.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -196,7 +196,7 @@ name = "libsqlite3-sys"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -312,25 +312,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "openssl"
version = "0.9.6"
source = "git+https://github.com/sfackler/rust-openssl.git#e62847dae76241e33294fb499fb95a77e88fa85a"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.6",
"openssl-sys 0.9.6 (git+https://github.com/sfackler/rust-openssl.git)",
]
[[package]]
name = "openssl"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
replace = "openssl 0.9.6"
replace = "openssl 0.9.6 (git+https://github.com/sfackler/rust-openssl.git)"
[[package]]
name = "openssl-sys"
version = "0.9.6"
source = "git+https://github.com/sfackler/rust-openssl.git#e62847dae76241e33294fb499fb95a77e88fa85a"
dependencies = [
"gcc 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -503,7 +505,7 @@ name = "tokio-core"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -515,7 +517,7 @@ name = "tokio-tls"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -536,7 +538,7 @@ dependencies = [
"chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
"data-encoding 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -593,7 +595,7 @@ dependencies = [
"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a"
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
"checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f"
"checksum backtrace-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3602e8d8c43336088a8505fa55cae2b3884a9be29440863a11528a42f46f6bb7"
"checksum backtrace-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a81b49c3aa114aa4d951a12d9e32e27809405c369efef2a75aac70efb1176fae"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
"checksum chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9213f7cd7c27e95c2b57c49f0e69b1ea65b27138da84a170133fd21b07659c00"
@ -605,8 +607,8 @@ dependencies = [
"checksum docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)" = "4a7ef30445607f6fc8720f0a0a2c7442284b629cf0d049286860fae23e71c4d9"
"checksum error-chain 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faa976b4fd2e4c2b2f3f486874b19e61944d3de3de8b61c9fcf835d583871bcc"
"checksum foreign-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d303bf9c8e20c02242ffe4217add748a5b2424cf5955bc399545540fc751c21"
"checksum futures 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "7463cac13a9c96d3fb5a0d2a653c5cbd6e79997ba153cf407117659aa97afe9b"
"checksum gcc 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "291055c78f59ca3d84c99026c9501c469413d386bb46be1e1cf1d285cd1db3b0"
"checksum futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c1913eb7083840b1bbcbf9631b7fda55eaf35fe7ead13cca034e8946f9e2bc41"
"checksum gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "c07c758b972368e703a562686adb39125707cc1ef3399da8c019fc6c2498a75d"
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6abe0ee2e758cd6bc8a2cd56726359007748fbf4128da998b65d0b70f881e19b"
@ -625,7 +627,9 @@ dependencies = [
"checksum num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "fb24d9bfb3f222010df27995441ded1e954f8f69cd35021f6bef02ca9552fb92"
"checksum num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "287a1c9969a847055e1122ec0ea7a5c5d6f72aad97934e131c83d5c08ab4e45c"
"checksum num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "a16a42856a256b39c6d3484f097f6713e14feacd9bfb02290917904fae46c81c"
"checksum openssl 0.9.6 (git+https://github.com/sfackler/rust-openssl.git)" = "<none>"
"checksum openssl 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0c00da69323449142e00a5410f0e022b39e8bbb7dc569cee8fc6af279279483c"
"checksum openssl-sys 0.9.6 (git+https://github.com/sfackler/rust-openssl.git)" = "<none>"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
"checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753"

View File

@ -2,5 +2,7 @@
members = ["client", "server"]
[replace]
"openssl:0.9.6" = { path = "../rust-openssl/openssl" }
"openssl-sys:0.9.6" = { path = "../rust-openssl/openssl-sys" }
"openssl:0.9.6" = { git = "https://github.com/sfackler/rust-openssl.git" }
#openssl:0.9.6" = { path = "../rust-openssl/openssl", git = "https://github.com/sfackler/rust-openssl.git" }
"openssl-sys:0.9.6" = { git = "https://github.com/sfackler/rust-openssl.git" }
#"openssl-sys:0.9.6" = { path = "../rust-openssl/openssl-sys", git = "https://github.com/sfackler/rust-openssl.git" }

View File

@ -56,8 +56,10 @@ openssl = { version = "^0.9.6", optional = true }
rand = "^0.3"
ring = { version = "^0.6", optional = true }
rustc-serialize = "^0.3.18"
security-framework = "^0.1.10"
time = "^0.1"
tokio-core = "^0.1"
tokio-tls = "^0.1"
untrusted = "^0.3"
[target.'cfg(target_os = "macos")'.dependencies]
security-framework = "^0.1.10"

View File

@ -38,6 +38,7 @@ extern crate native_tls;
extern crate rand;
#[cfg(feature = "ring")] extern crate ring;
extern crate rustc_serialize;
#[cfg(target_os = "macos")]
extern crate security_framework;
extern crate time;
#[macro_use] extern crate tokio_core;

View File

@ -20,6 +20,6 @@ mod tls_client_connection;
mod tls_client_stream;
mod tls_stream;
pub use self::tls_client_connection::TlsClientConnection;
pub use self::tls_client_stream::TlsClientStream;
pub use self::tls_stream::TlsStream;
pub use self::tls_client_connection::{TlsClientConnection, TlsClientConnectionBuilder};
pub use self::tls_client_stream::{TlsClientStream, TlsClientStreamBuilder};
pub use self::tls_stream::{TlsStream, TlsStreamBuilder};

View File

@ -19,13 +19,16 @@ use std::io;
use futures::Future;
use native_tls::Pkcs12;
#[cfg(target_os = "linux")]
use openssl::x509::X509 as OpensslX509;
#[cfg(target_os = "macos")]
use security_framework::certificate::SecCertificate;
use tokio_core::net::TcpStream;
use tokio_core::reactor::Core;
use ::error::*;
use ::client::{ClientConnection, ClientStreamHandle};
use ::tls::TlsClientStream;
use ::tls::{TlsClientStream, TlsClientStreamBuilder};
/// TCP based DNS client
pub struct TlsClientConnection {
@ -35,22 +38,8 @@ pub struct TlsClientConnection {
}
impl TlsClientConnection {
/// Creates a new client connection.
///
/// *Note* this has side affects of establishing the connection to the specified DNS server and
/// starting the event_loop. Expect this to change in the future.
///
/// # Arguments
///
/// * `name_server` - address of the name server to use for queries
pub fn new(name_server: SocketAddr,
subject_name: String,
certs: Vec<SecCertificate>,
pkcs12: Option<Pkcs12>) -> ClientResult<Self> {
let io_loop = try!(Core::new());
let (tls_client_stream, handle) = TlsClientStream::new_tls(name_server, subject_name, io_loop.handle(), certs, pkcs12);
Ok(TlsClientConnection{ io_loop: io_loop, tls_client_stream: tls_client_stream, client_stream_handle: handle })
pub fn builder() -> TlsClientConnectionBuilder {
TlsClientConnectionBuilder(TlsClientStream::builder())
}
}
@ -61,3 +50,37 @@ impl ClientConnection for TlsClientConnection {
(self.io_loop, self.tls_client_stream, self.client_stream_handle)
}
}
pub struct TlsClientConnectionBuilder(TlsClientStreamBuilder);
impl TlsClientConnectionBuilder {
#[cfg(target_os = "macos")]
pub fn add_ca(&mut self, ca: SecCertificate) {
self.0.add_ca(ca);
}
#[cfg(target_os = "linux")]
pub fn add_ca(&mut self, ca: OpensslX509) {
self.0.add_ca(ca);
}
/// Client side identity for client auth in TLS (aka mutual TLS auth)
pub fn identity(&mut self, pkcs12: Pkcs12) {
self.0.identity(pkcs12);
}
/// Creates a new client connection.
///
/// *Note* this has side affects of establishing the connection to the specified DNS server and
/// starting the event_loop. Expect this to change in the future.
///
/// # Arguments
///
/// * `name_server` - address of the name server to use for queries
pub fn build(self, name_server: SocketAddr, subject_name: String) -> ClientResult<TlsClientConnection> {
let io_loop = try!(Core::new());
let (tls_client_stream, handle) = self.0.build(name_server, subject_name, io_loop.handle());
Ok(TlsClientConnection{ io_loop: io_loop, tls_client_stream: tls_client_stream, client_stream_handle: handle })
}
}

View File

@ -10,6 +10,9 @@ use std::io;
use futures::{Async, Future, Poll, Stream};
use native_tls::Pkcs12;
#[cfg(target_os = "linux")]
use openssl::x509::X509 as OpensslX509;
#[cfg(target_os = "macos")]
use security_framework::certificate::SecCertificate;
use tokio_core::io::Io;
use tokio_core::net::TcpStream as TokioTcpStream;
@ -18,21 +21,38 @@ use tokio_tls::TlsStream as TokioTlsStream;
use ::BufClientStreamHandle;
use ::tcp::TcpClientStream;
use ::tls::TlsStream;
use ::tls::{TlsStream, TlsStreamBuilder};
use ::client::ClientStreamHandle;
pub type TlsClientStream = TcpClientStream<TokioTlsStream<TokioTcpStream>>;
impl TlsClientStream {
/// it is expected that the resolver wrapper will be responsible for creating and managing
/// new TcpClients such that each new client would have a random port (reduce chance of cache
/// poisoning)
pub fn new_tls(name_server: SocketAddr,
subject_name: String,
loop_handle: Handle,
certs: Vec<SecCertificate>,
pkcs12: Option<Pkcs12>) -> (Box<Future<Item=TlsClientStream, Error=io::Error>>, Box<ClientStreamHandle>) {
let (stream_future, sender) = TlsStream::new_tls(name_server, subject_name, loop_handle, certs, pkcs12);
pub fn builder() -> TlsClientStreamBuilder {
TlsClientStreamBuilder(TlsStream::builder())
}
}
pub struct TlsClientStreamBuilder(TlsStreamBuilder);
impl TlsClientStreamBuilder {
#[cfg(target_os = "macos")]
pub fn add_ca(&mut self, ca: SecCertificate) {
self.0.add_ca(ca);
}
#[cfg(target_os = "linux")]
pub fn add_ca(&mut self, ca: OpensslX509) {
self.0.add_ca(ca);
}
/// Client side identity for client auth in TLS (aka mutual TLS auth)
pub fn identity(&mut self, pkcs12: Pkcs12) {
self.0.identity(pkcs12);
}
pub fn build(self, name_server: SocketAddr, subject_name: String, loop_handle: Handle)
-> (Box<Future<Item=TlsClientStream, Error=io::Error>>, Box<ClientStreamHandle>) {
let (stream_future, sender) = self.0.build(name_server, subject_name, loop_handle);
let new_future: Box<Future<Item=TlsClientStream, Error=io::Error>> =
Box::new(stream_future.map(move |tls_stream| {

View File

@ -13,8 +13,13 @@ use futures::sync::mpsc::unbounded;
use native_tls;
use native_tls::TlsConnector;
use native_tls::Pkcs12;
#[cfg(target_os = "macos")]
use native_tls::backend::security_framework::TlsConnectorBuilderExt;
#[cfg(target_os = "linux")]
use native_tls::backend::openssl::TlsConnectorBuilderExt;
use native_tls::Protocol::Tlsv12;
#[cfg(target_os = "linux")]
use openssl::x509::X509 as OpensslX509;
#[cfg(target_os = "macos")]
use security_framework::certificate::SecCertificate;
use tokio_core::net::TcpStream as TokioTcpStream;
@ -27,6 +32,69 @@ use ::tcp::TcpStream;
pub type TlsStream = TcpStream<TokioTlsStream<TokioTcpStream>>;
impl TlsStream {
pub fn builder() -> TlsStreamBuilder {
TlsStreamBuilder { ca_chain: vec![], identity: None }
}
#[cfg(target_os = "linux")]
fn build(certs: Vec<OpensslX509>, pkcs12: Option<Pkcs12>) -> io::Result<TlsConnector> {
let mut builder = try!(TlsConnector::builder().map_err(|e| io::Error::new(io::ErrorKind::ConnectionRefused, format!("tls error: {}", e))));
try!(builder.supported_protocols(&[Tlsv12]).map_err(|e| io::Error::new(io::ErrorKind::ConnectionRefused, format!("tls error: {}", e))));
for cert in certs {
try!(builder.builder_mut().builder_mut().cert_store_mut().add_cert(cert).map_err(|e| io::Error::new(io::ErrorKind::ConnectionRefused, format!("tls error: {}", e))));
}
if let Some(pkcs12) = pkcs12 { try!(builder.identity(pkcs12).map_err(|e| io::Error::new(io::ErrorKind::ConnectionRefused, format!("tls error: {}", e)))); }
builder.build().map_err(|e| io::Error::new(io::ErrorKind::ConnectionRefused, format!("tls error: {}", e)))
}
#[cfg(target_os = "macos")]
fn build(certs: Vec<SecCertificate>, pkcs12: Option<Pkcs12>) -> io::Result<TlsConnector> {
let mut builder = try!(TlsConnector::builder().map_err(|e| io::Error::new(io::ErrorKind::ConnectionRefused, format!("tls error: {}", e))));
try!(builder.supported_protocols(&[Tlsv12]).map_err(|e| io::Error::new(io::ErrorKind::ConnectionRefused, format!("tls error: {}", e))));
builder.anchor_certificates(&certs);
if let Some(pkcs12) = pkcs12 { try!(builder.identity(pkcs12).map_err(|e| io::Error::new(io::ErrorKind::ConnectionRefused, format!("tls error: {}", e)))); }
builder.build().map_err(|e| io::Error::new(io::ErrorKind::ConnectionRefused, format!("tls error: {}", e)))
}
/// Initializes a TcpStream with an existing tokio_core::net::TcpStream.
///
/// This is intended for use with a TcpListener and Incoming.
pub fn from_tls_stream(stream: TokioTlsStream<TokioTcpStream>, peer_addr: SocketAddr) -> (Self, BufStreamHandle) {
let (message_sender, outbound_messages) = unbounded();
let stream = TcpStream::from_stream_with_receiver(stream, peer_addr, outbound_messages);
(stream, message_sender)
}
}
pub struct TlsStreamBuilder {
#[cfg(target_os = "macos")]
ca_chain: Vec<SecCertificate>,
#[cfg(target_os = "linux")]
ca_chain: Vec<OpensslX509>,
identity: Option<Pkcs12>,
}
impl TlsStreamBuilder {
#[cfg(target_os = "macos")]
pub fn add_ca(&mut self, ca: SecCertificate) {
self.ca_chain.push(ca);
}
#[cfg(target_os = "linux")]
pub fn add_ca(&mut self, ca: OpensslX509) {
self.ca_chain.push(ca);
}
/// Client side identity for client auth in TLS (aka mutual TLS auth)
pub fn identity(&mut self, pkcs12: Pkcs12) {
self.identity = Some(pkcs12);
}
/// Creates a new TlsStream to the specified name_server
///
/// [RFC 7858](https://tools.ietf.org/html/rfc7858), DNS over TLS, May 2016
@ -53,16 +121,15 @@ impl TlsStream {
/// * `name_server` - IP and Port for the remote DNS resolver
/// * `subject_name` - The Subject Public Key Info (SPKI) name as associated to a certificate
/// * `loop_handle` - The reactor Core handle
/// * `certs` - list of trusted certificates authorities
/// * `certs` - list of trusted certificate authorities
/// * `pkcs12` - optional client identity for client auth (i.e. for mutual TLS authentication)
/// TODO: make a builder for the certifiates...
pub fn new_tls(name_server: SocketAddr,
subject_name: String,
loop_handle: Handle,
certs: Vec<SecCertificate>,
pkcs12: Option<Pkcs12>) -> (Box<Future<Item=TlsStream, Error=io::Error>>, BufStreamHandle) {
pub fn build(self,
name_server: SocketAddr,
subject_name: String,
loop_handle: Handle) -> (Box<Future<Item=TlsStream, Error=io::Error>>, BufStreamHandle) {
let (message_sender, outbound_messages) = unbounded();
let tls_connector = match Self::build(certs, pkcs12) {
let tls_connector = match TlsStream::build(self.ca_chain, self.identity) {
Ok(c) => c,
Err(e) => return (Box::new(future::err(e).into_future().map_err(|e| io::Error::new(io::ErrorKind::ConnectionRefused, format!("tls error: {}", e)))),
message_sender)
@ -84,26 +151,6 @@ impl TlsStream {
(stream, message_sender)
}
#[deprecated = "is this used?"]
fn build(certs: Vec<SecCertificate>, pkcs12: Option<Pkcs12>) -> native_tls::Result<TlsConnector> {
let mut builder = try!(TlsConnector::builder());
try!(builder.supported_protocols(&[Tlsv12]));
builder.anchor_certificates(&certs);
if let Some(pkcs12) = pkcs12 { try!(builder.identity(pkcs12)); }
builder.build()
}
/// Initializes a TcpStream with an existing tokio_core::net::TcpStream.
///
/// This is intended for use with a TcpListener and Incoming.
pub fn from_tls_stream(stream: TokioTlsStream<TokioTcpStream>, peer_addr: SocketAddr) -> (Self, BufStreamHandle) {
let (message_sender, outbound_messages) = unbounded();
let stream = TcpStream::from_stream_with_receiver(stream, peer_addr, outbound_messages);
(stream, message_sender)
}
}
#[cfg(test)] use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
@ -221,8 +268,16 @@ fn tls_client_stream_test(server_addr: IpAddr) {
// the tests should run within 5 seconds... right?
// TODO: add timeout here, so that test never hangs...
// let timeout = Timeout::new(Duration::from_secs(5), &io_loop.handle());
#[cfg(target_os = "macos")]
let trust_chain = SecCertificate::from_der(&cert_der).unwrap();
let (stream, sender) = TlsStream::new_tls(server_addr, subject_name.to_string(), io_loop.handle(), vec![trust_chain], None);
#[cfg(target_os = "linux")]
let trust_chain = OpensslX509::from_der(&cert_der).unwrap();
let mut builder = TlsStream::builder();
builder.add_ca(trust_chain);
let (stream, sender) = builder.build(server_addr, subject_name.to_string(), io_loop.handle());
let mut stream = io_loop.run(stream).ok().expect("run failed to get stream");

View File

@ -3,6 +3,6 @@
trust_dns_dir=$(dirname $0)/..
pushd ${trust_dns_dir}
docker run -a STDERR -a STDOUT --rm -v ${PWD}:/src fnichol/rust:1.12.0 bash scripts/run_tests.sh "$@" | tee target/linux_output.txt
docker run -a STDERR -a STDOUT --rm -v ${PWD}:/src fnichol/rust:nightly bash scripts/run_tests.sh "$@" | tee target/linux_output.txt
popd

View File

@ -60,9 +60,11 @@ openssl = "^0.9.6"
rand = "^0.3"
rustc-serialize = "^0.3.18"
rusqlite = { version = "^0.8.0", features = ["bundled"] }
security-framework = "^0.1.10"
time = "^0.1"
tokio-core = "^0.1"
tokio-tls = "^0.1"
toml = "^0.1"
trust-dns = { version = "^0.9", path = "../client" }
[target.'cfg(target_os = "macos")'.dependencies]
security-framework = "^0.1.10"

View File

@ -2,6 +2,7 @@ extern crate chrono;
extern crate futures;
extern crate native_tls;
extern crate openssl;
#[cfg(target_os = "macos")]
extern crate security_framework;
extern crate trust_dns;
extern crate trust_dns_server;
@ -14,7 +15,9 @@ use std::time::Duration;
use futures::Stream;
use openssl::*;
use openssl::x509::extension::*;
#[cfg(target_os = "linux")]
use openssl::x509::X509 as OpensslX509;
#[cfg(target_os = "macos")]
use security_framework::certificate::SecCertificate;
use trust_dns::client::*;
@ -98,8 +101,7 @@ fn test_server_www_tls() {
let pkcs12 = native_tls::Pkcs12::from_der(&pkcs12_der, "mypassword").expect("Pkcs12::from_der");
thread::Builder::new().name("test_server:tls:server".to_string()).spawn(move || server_thread_tls(tcp_listener, pkcs12)).unwrap();
let trust_chain = vec![SecCertificate::from_der(&cert_der).unwrap()];
let client_thread = thread::Builder::new().name("test_server:tcp:client".to_string()).spawn(move || client_thread_www(lazy_tls_client(ipaddr, subject_name.to_string(), trust_chain))).unwrap();
let client_thread = thread::Builder::new().name("test_server:tcp:client".to_string()).spawn(move || client_thread_www(lazy_tls_client(ipaddr, subject_name.to_string(), cert_der))).unwrap();
let client_result = client_thread.join();
// let server_result = server_thread.join();
@ -116,8 +118,17 @@ fn lazy_tcp_client(ipaddr: SocketAddr) -> TcpClientConnection {
TcpClientConnection::new(ipaddr).unwrap()
}
fn lazy_tls_client(ipaddr: SocketAddr, subject_name: String, trust_chain: Vec<SecCertificate>) -> TlsClientConnection {
TlsClientConnection::new(ipaddr, subject_name, trust_chain, None).unwrap()
fn lazy_tls_client(ipaddr: SocketAddr, subject_name: String, cert_der: Vec<u8>) -> TlsClientConnection {
let mut builder = TlsClientConnection::builder();
#[cfg(target_os = "macos")]
let trust_chain = SecCertificate::from_der(&cert_der).unwrap();
#[cfg(target_os = "linux")]
let trust_chain = OpensslX509::from_der(&cert_der).unwrap();
builder.add_ca(trust_chain);
builder.build(ipaddr, subject_name).unwrap()
}
fn client_thread_www<C: ClientConnection>(conn: C)