linux support for DNS over TLS
This commit is contained in:
parent
9ae4f3eef2
commit
d409317e88
@ -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
36
Cargo.lock
generated
@ -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"
|
||||
|
@ -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" }
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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};
|
||||
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
@ -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| {
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user