From 9c9431be3068d471d8f90e4383027731920cfdbe Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 31 May 2023 09:01:53 +0200 Subject: [PATCH] Remove tokio-native-tls --- Cargo.toml | 1 - tokio-native-tls/CHANGELOG.md | 11 - tokio-native-tls/Cargo.toml | 41 -- tokio-native-tls/LICENSE | 25 -- tokio-native-tls/README.md | 18 - .../examples/download-rust-lang.rs | 39 -- tokio-native-tls/examples/echo.rs | 52 --- tokio-native-tls/examples/identity.p12 | Bin 3386 -> 0 bytes tokio-native-tls/src/lib.rs | 384 ------------------ tokio-native-tls/tests/bad.rs | 122 ------ tokio-native-tls/tests/cert.der | Bin 799 -> 0 bytes tokio-native-tls/tests/google.rs | 99 ----- tokio-native-tls/tests/identity.p12 | Bin 3386 -> 0 bytes tokio-native-tls/tests/root-ca.der | Bin 865 -> 0 bytes tokio-native-tls/tests/smoke.rs | 172 -------- 15 files changed, 964 deletions(-) delete mode 100644 tokio-native-tls/CHANGELOG.md delete mode 100644 tokio-native-tls/Cargo.toml delete mode 100644 tokio-native-tls/LICENSE delete mode 100644 tokio-native-tls/README.md delete mode 100644 tokio-native-tls/examples/download-rust-lang.rs delete mode 100644 tokio-native-tls/examples/echo.rs delete mode 100644 tokio-native-tls/examples/identity.p12 delete mode 100644 tokio-native-tls/src/lib.rs delete mode 100644 tokio-native-tls/tests/bad.rs delete mode 100644 tokio-native-tls/tests/cert.der delete mode 100644 tokio-native-tls/tests/google.rs delete mode 100644 tokio-native-tls/tests/identity.p12 delete mode 100644 tokio-native-tls/tests/root-ca.der delete mode 100644 tokio-native-tls/tests/smoke.rs diff --git a/Cargo.toml b/Cargo.toml index ebea3ab..7e7344c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,5 @@ [workspace] members = [ - "tokio-native-tls", "tokio-rustls", "tokio-rustls/examples/client", "tokio-rustls/examples/server" diff --git a/tokio-native-tls/CHANGELOG.md b/tokio-native-tls/CHANGELOG.md deleted file mode 100644 index 1994302..0000000 --- a/tokio-native-tls/CHANGELOG.md +++ /dev/null @@ -1,11 +0,0 @@ -# 0.3.0 (December 23, 2020) - -- Upgrade to `tokio 1.0`. - -# 0.2.0 (October 16, 2020) - -- Upgrade to `tokio 0.3`. - -# 0.1.0 (January 9th, 2019) - -- Initial release from `tokio-tls 0.3` diff --git a/tokio-native-tls/Cargo.toml b/tokio-native-tls/Cargo.toml deleted file mode 100644 index 9b47807..0000000 --- a/tokio-native-tls/Cargo.toml +++ /dev/null @@ -1,41 +0,0 @@ -[package] -name = "tokio-native-tls" -# When releasing to crates.io: -# - Remove path dependencies -# - Update html_root_url. -# - Update doc url -# - Cargo.toml -# - README.md -# - Update CHANGELOG.md. -# - Create "v0.1.x" git tag. -version = "0.3.1" -edition = "2018" -authors = ["Tokio Contributors "] -license = "MIT" -repository = "https://github.com/tokio-rs/tls" -homepage = "https://tokio.rs" -documentation = "https://docs.rs/tokio-native-tls" -description = """ -An implementation of TLS/SSL streams for Tokio using native-tls giving an implementation of TLS -for nonblocking I/O streams. -""" -categories = ["asynchronous", "network-programming"] - -[dependencies] -native-tls = "0.2" -tokio = "1.0" - -[features] -vendored = ["native-tls/vendored"] - -[dev-dependencies] -tokio = { version = "1.0", features = ["macros", "rt", "rt-multi-thread", "io-util", "net"] } -cfg-if = "1.0" -env_logger = { version = "0.10", default-features = false } -futures = { version = "0.3.0", features = ["async-await"] } - -tempfile = "3.1" -lazy_static = "1.4.0" - -[package.metadata.docs.rs] -all-features = true diff --git a/tokio-native-tls/LICENSE b/tokio-native-tls/LICENSE deleted file mode 100644 index cdb28b4..0000000 --- a/tokio-native-tls/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2019 Tokio Contributors - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/tokio-native-tls/README.md b/tokio-native-tls/README.md deleted file mode 100644 index 7b7aea3..0000000 --- a/tokio-native-tls/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# tokio-native-tls -[![github actions](https://github.com/tokio-rs/tls/workflows/CI/badge.svg)](https://github.com/tokio-rs/tls/actions) -[![crates](https://img.shields.io/crates/v/tokio-native-tls.svg)](https://crates.io/crates/tokio-native-tls) -[![license](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/tokio-rs/tls/blob/master/tokio-native-tls/LICENSE) -[![docs.rs](https://docs.rs/tokio-native-tls/badge.svg)](https://docs.rs/tokio-native-tls/) - -An implementation of TLS/SSL streams for Tokio built on top of the -[`native-tls`](https://crates.io/crates/native-tls) crate. - -## License - -This project is licensed under the [MIT license](./LICENSE). - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in Tokio by you, shall be licensed as MIT, without any additional -terms or conditions. diff --git a/tokio-native-tls/examples/download-rust-lang.rs b/tokio-native-tls/examples/download-rust-lang.rs deleted file mode 100644 index 6f864c3..0000000 --- a/tokio-native-tls/examples/download-rust-lang.rs +++ /dev/null @@ -1,39 +0,0 @@ -// #![warn(rust_2018_idioms)] - -use native_tls::TlsConnector; -use std::error::Error; -use std::net::ToSocketAddrs; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use tokio::net::TcpStream; - -#[tokio::main] -async fn main() -> Result<(), Box> { - let addr = "www.rust-lang.org:443" - .to_socket_addrs()? - .next() - .ok_or("failed to resolve www.rust-lang.org")?; - - let socket = TcpStream::connect(&addr).await?; - let cx = TlsConnector::builder().build()?; - let cx = tokio_native_tls::TlsConnector::from(cx); - - let mut socket = cx.connect("www.rust-lang.org", socket).await?; - - socket - .write_all( - "\ - GET / HTTP/1.0\r\n\ - Host: www.rust-lang.org\r\n\ - \r\n\ - " - .as_bytes(), - ) - .await?; - - let mut data = Vec::new(); - socket.read_to_end(&mut data).await?; - - // println!("data: {:?}", &data); - println!("{}", String::from_utf8_lossy(&data[..])); - Ok(()) -} diff --git a/tokio-native-tls/examples/echo.rs b/tokio-native-tls/examples/echo.rs deleted file mode 100644 index 74c0564..0000000 --- a/tokio-native-tls/examples/echo.rs +++ /dev/null @@ -1,52 +0,0 @@ -#![warn(rust_2018_idioms)] - -// A tiny async TLS echo server with Tokio -use native_tls::Identity; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use tokio::net::TcpListener; - -/** -an example to setup a tls server. -how to test: -wget https://127.0.0.1:12345 --no-check-certificate -*/ -#[tokio::main] -async fn main() -> Result<(), Box> { - // Bind the server's socket - let addr = "127.0.0.1:12345".to_string(); - let tcp: TcpListener = TcpListener::bind(&addr).await?; - - // Create the TLS acceptor. - let der = include_bytes!("identity.p12"); - let cert = Identity::from_pkcs12(der, "mypass")?; - let tls_acceptor = - tokio_native_tls::TlsAcceptor::from(native_tls::TlsAcceptor::builder(cert).build()?); - loop { - // Asynchronously wait for an inbound socket. - let (socket, remote_addr) = tcp.accept().await?; - let tls_acceptor = tls_acceptor.clone(); - println!("accept connection from {}", remote_addr); - tokio::spawn(async move { - // Accept the TLS connection. - let mut tls_stream = tls_acceptor.accept(socket).await.expect("accept error"); - // In a loop, read data from the socket and write the data back. - - let mut buf = [0; 1024]; - let n = tls_stream - .read(&mut buf) - .await - .expect("failed to read data from socket"); - - if n == 0 { - return; - } - println!("read={}", unsafe { - String::from_utf8_unchecked(buf[0..n].into()) - }); - tls_stream - .write_all(&buf[0..n]) - .await - .expect("failed to write data to socket"); - }); - } -} diff --git a/tokio-native-tls/examples/identity.p12 b/tokio-native-tls/examples/identity.p12 deleted file mode 100644 index d16abb8c70627bd959667495e578fb6f010a7f1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3386 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 CKSRy{ diff --git a/tokio-native-tls/src/lib.rs b/tokio-native-tls/src/lib.rs deleted file mode 100644 index 8ce19c0..0000000 --- a/tokio-native-tls/src/lib.rs +++ /dev/null @@ -1,384 +0,0 @@ -#![doc(html_root_url = "https://docs.rs/tokio-native-tls/0.3.0")] -#![warn( - missing_debug_implementations, - missing_docs, - rust_2018_idioms, - unreachable_pub -)] -#![deny(rustdoc::broken_intra_doc_links)] -#![doc(test( - no_crate_inject, - attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) -))] - -//! Async TLS streams -//! -//! This library is an implementation of TLS streams using the most appropriate -//! system library by default for negotiating the connection. That is, on -//! Windows this library uses SChannel, on OSX it uses SecureTransport, and on -//! other platforms it uses OpenSSL. -//! -//! Each TLS stream implements the `Read` and `Write` traits to interact and -//! interoperate with the rest of the futures I/O ecosystem. Client connections -//! initiated from this crate verify hostnames automatically and by default. -//! -//! This crate primarily exports this ability through two newtypes, -//! `TlsConnector` and `TlsAcceptor`. These newtypes augment the -//! functionality provided by the `native-tls` crate, on which this crate is -//! built. Configuration of TLS parameters is still primarily done through the -//! `native-tls` crate. - -use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; - -use crate::native_tls::{Error, HandshakeError, MidHandshakeTlsStream}; -use std::fmt; -use std::future::Future; -use std::io::{self, Read, Write}; -use std::marker::Unpin; -#[cfg(unix)] -use std::os::unix::io::{AsRawFd, RawFd}; -#[cfg(windows)] -use std::os::windows::io::{AsRawSocket, RawSocket}; -use std::pin::Pin; -use std::ptr::null_mut; -use std::task::{Context, Poll}; - -/// An intermediate wrapper for the inner stream `S`. -#[derive(Debug)] -pub struct AllowStd { - inner: S, - context: *mut (), -} - -impl AllowStd { - /// Returns a shared reference to the inner stream. - pub fn get_ref(&self) -> &S { - &self.inner - } - - /// Returns a mutable reference to the inner stream. - pub fn get_mut(&mut self) -> &mut S { - &mut self.inner - } -} - -/// A wrapper around an underlying raw stream which implements the TLS or SSL -/// protocol. -/// -/// A `TlsStream` represents a handshake that has been completed successfully -/// and both the server and the client are ready for receiving and sending -/// data. Bytes read from a `TlsStream` are decrypted from `S` and bytes written -/// to a `TlsStream` are encrypted when passing through to `S`. -#[derive(Debug)] -pub struct TlsStream(native_tls::TlsStream>); - -/// A wrapper around a `native_tls::TlsConnector`, providing an async `connect` -/// method. -#[derive(Clone)] -pub struct TlsConnector(native_tls::TlsConnector); - -/// A wrapper around a `native_tls::TlsAcceptor`, providing an async `accept` -/// method. -#[derive(Clone)] -pub struct TlsAcceptor(native_tls::TlsAcceptor); - -struct MidHandshake(Option>>); - -enum StartedHandshake { - Done(TlsStream), - Mid(MidHandshakeTlsStream>), -} - -struct StartedHandshakeFuture(Option>); -struct StartedHandshakeFutureInner { - f: F, - stream: S, -} - -struct Guard<'a, S>(&'a mut TlsStream) -where - AllowStd: Read + Write; - -impl Drop for Guard<'_, S> -where - AllowStd: Read + Write, -{ - fn drop(&mut self) { - (self.0).0.get_mut().context = null_mut(); - } -} - -// *mut () context is neither Send nor Sync -unsafe impl Send for AllowStd {} -unsafe impl Sync for AllowStd {} - -impl AllowStd -where - S: Unpin, -{ - fn with_context(&mut self, f: F) -> io::Result - where - F: FnOnce(&mut Context<'_>, Pin<&mut S>) -> Poll>, - { - unsafe { - assert!(!self.context.is_null()); - let waker = &mut *(self.context as *mut _); - match f(waker, Pin::new(&mut self.inner)) { - Poll::Ready(r) => r, - Poll::Pending => Err(io::Error::from(io::ErrorKind::WouldBlock)), - } - } - } -} - -impl Read for AllowStd -where - S: AsyncRead + Unpin, -{ - fn read(&mut self, buf: &mut [u8]) -> io::Result { - let mut buf = ReadBuf::new(buf); - self.with_context(|ctx, stream| stream.poll_read(ctx, &mut buf))?; - Ok(buf.filled().len()) - } -} - -impl Write for AllowStd -where - S: AsyncWrite + Unpin, -{ - fn write(&mut self, buf: &[u8]) -> io::Result { - self.with_context(|ctx, stream| stream.poll_write(ctx, buf)) - } - - fn flush(&mut self) -> io::Result<()> { - self.with_context(|ctx, stream| stream.poll_flush(ctx)) - } -} - -impl TlsStream { - fn with_context(&mut self, ctx: &mut Context<'_>, f: F) -> Poll> - where - F: FnOnce(&mut native_tls::TlsStream>) -> io::Result, - AllowStd: Read + Write, - { - self.0.get_mut().context = ctx as *mut _ as *mut (); - let g = Guard(self); - match f(&mut (g.0).0) { - Ok(v) => Poll::Ready(Ok(v)), - Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Poll::Pending, - Err(e) => Poll::Ready(Err(e)), - } - } - - /// Returns a shared reference to the inner stream. - pub fn get_ref(&self) -> &native_tls::TlsStream> { - &self.0 - } - - /// Returns a mutable reference to the inner stream. - pub fn get_mut(&mut self) -> &mut native_tls::TlsStream> { - &mut self.0 - } -} - -impl AsyncRead for TlsStream -where - S: AsyncRead + AsyncWrite + Unpin, -{ - fn poll_read( - mut self: Pin<&mut Self>, - ctx: &mut Context<'_>, - buf: &mut ReadBuf<'_>, - ) -> Poll> { - self.with_context(ctx, |s| { - let n = s.read(buf.initialize_unfilled())?; - buf.advance(n); - Ok(()) - }) - } -} - -impl AsyncWrite for TlsStream -where - S: AsyncRead + AsyncWrite + Unpin, -{ - fn poll_write( - mut self: Pin<&mut Self>, - ctx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - self.with_context(ctx, |s| s.write(buf)) - } - - fn poll_flush(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll> { - self.with_context(ctx, |s| s.flush()) - } - - fn poll_shutdown(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll> { - self.with_context(ctx, |s| s.shutdown()) - } -} - -#[cfg(unix)] -impl AsRawFd for TlsStream -where - S: AsRawFd, -{ - fn as_raw_fd(&self) -> RawFd { - self.get_ref().get_ref().get_ref().as_raw_fd() - } -} - -#[cfg(windows)] -impl AsRawSocket for TlsStream -where - S: AsRawSocket, -{ - fn as_raw_socket(&self) -> RawSocket { - self.get_ref().get_ref().get_ref().as_raw_socket() - } -} - -async fn handshake(f: F, stream: S) -> Result, Error> -where - F: FnOnce( - AllowStd, - ) -> Result>, HandshakeError>> - + Unpin, - S: AsyncRead + AsyncWrite + Unpin, -{ - let start = StartedHandshakeFuture(Some(StartedHandshakeFutureInner { f, stream })); - - match start.await { - Err(e) => Err(e), - Ok(StartedHandshake::Done(s)) => Ok(s), - Ok(StartedHandshake::Mid(s)) => MidHandshake(Some(s)).await, - } -} - -impl Future for StartedHandshakeFuture -where - F: FnOnce( - AllowStd, - ) -> Result>, HandshakeError>> - + Unpin, - S: Unpin, - AllowStd: Read + Write, -{ - type Output = Result, Error>; - - fn poll( - mut self: Pin<&mut Self>, - ctx: &mut Context<'_>, - ) -> Poll, Error>> { - let inner = self.0.take().expect("future polled after completion"); - let stream = AllowStd { - inner: inner.stream, - context: ctx as *mut _ as *mut (), - }; - - match (inner.f)(stream) { - Ok(mut s) => { - s.get_mut().context = null_mut(); - Poll::Ready(Ok(StartedHandshake::Done(TlsStream(s)))) - } - Err(HandshakeError::WouldBlock(mut s)) => { - s.get_mut().context = null_mut(); - Poll::Ready(Ok(StartedHandshake::Mid(s))) - } - Err(HandshakeError::Failure(e)) => Poll::Ready(Err(e)), - } - } -} - -impl TlsConnector { - /// Connects the provided stream with this connector, assuming the provided - /// domain. - /// - /// This function will internally call `TlsConnector::connect` to connect - /// the stream and returns a future representing the resolution of the - /// connection operation. The returned future will resolve to either - /// `TlsStream` or `Error` depending if it's successful or not. - /// - /// This is typically used for clients who have already established, for - /// example, a TCP connection to a remote server. That stream is then - /// provided here to perform the client half of a connection to a - /// TLS-powered server. - pub async fn connect(&self, domain: &str, stream: S) -> Result, Error> - where - S: AsyncRead + AsyncWrite + Unpin, - { - handshake(move |s| self.0.connect(domain, s), stream).await - } -} - -impl fmt::Debug for TlsConnector { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("TlsConnector").finish() - } -} - -impl From for TlsConnector { - fn from(inner: native_tls::TlsConnector) -> TlsConnector { - TlsConnector(inner) - } -} - -impl TlsAcceptor { - /// Accepts a new client connection with the provided stream. - /// - /// This function will internally call `TlsAcceptor::accept` to connect - /// the stream and returns a future representing the resolution of the - /// connection operation. The returned future will resolve to either - /// `TlsStream` or `Error` depending if it's successful or not. - /// - /// This is typically used after a new socket has been accepted from a - /// `TcpListener`. That socket is then passed to this function to perform - /// the server half of accepting a client connection. - pub async fn accept(&self, stream: S) -> Result, Error> - where - S: AsyncRead + AsyncWrite + Unpin, - { - handshake(move |s| self.0.accept(s), stream).await - } -} - -impl fmt::Debug for TlsAcceptor { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("TlsAcceptor").finish() - } -} - -impl From for TlsAcceptor { - fn from(inner: native_tls::TlsAcceptor) -> TlsAcceptor { - TlsAcceptor(inner) - } -} - -impl Future for MidHandshake { - type Output = Result, Error>; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let mut_self = self.get_mut(); - let mut s = mut_self.0.take().expect("future polled after completion"); - - s.get_mut().context = cx as *mut _ as *mut (); - match s.handshake() { - Ok(mut s) => { - s.get_mut().context = null_mut(); - Poll::Ready(Ok(TlsStream(s))) - } - Err(HandshakeError::WouldBlock(mut s)) => { - s.get_mut().context = null_mut(); - mut_self.0 = Some(s); - Poll::Pending - } - Err(HandshakeError::Failure(e)) => Poll::Ready(Err(e)), - } - } -} - -/// re-export native_tls -pub mod native_tls { - pub use native_tls::*; -} diff --git a/tokio-native-tls/tests/bad.rs b/tokio-native-tls/tests/bad.rs deleted file mode 100644 index 862d998..0000000 --- a/tokio-native-tls/tests/bad.rs +++ /dev/null @@ -1,122 +0,0 @@ -#![warn(rust_2018_idioms)] - -use cfg_if::cfg_if; -use native_tls::TlsConnector; -use std::io::{self, Error}; -use std::net::ToSocketAddrs; -use tokio::net::TcpStream; - -macro_rules! t { - ($e:expr) => { - match $e { - Ok(e) => e, - Err(e) => panic!("{} failed with {:?}", stringify!($e), e), - } - }; -} - -cfg_if! { - if #[cfg(feature = "force-rustls")] { - fn verify_failed(err: &Error, s: &str) { - let err = err.to_string(); - assert!(err.contains(s), "bad error: {}", err); - } - - fn assert_expired_error(err: &Error) { - verify_failed(err, "CertExpired"); - } - - fn assert_wrong_host(err: &Error) { - verify_failed(err, "CertNotValidForName"); - } - - fn assert_self_signed(err: &Error) { - verify_failed(err, "UnknownIssuer"); - } - - fn assert_untrusted_root(err: &Error) { - verify_failed(err, "UnknownIssuer"); - } - } else if #[cfg(any(feature = "force-openssl", - all(not(target_os = "macos"), - not(target_os = "windows"), - not(target_os = "ios"))))] { - fn verify_failed(err: &Error) { - assert!(format!("{}", err).contains("certificate verify failed")) - } - - use verify_failed as assert_expired_error; - use verify_failed as assert_wrong_host; - use verify_failed as assert_self_signed; - use verify_failed as assert_untrusted_root; - } else if #[cfg(any(target_os = "macos", target_os = "ios"))] { - - fn assert_invalid_cert_chain(err: &Error) { - assert!(format!("{}", err).contains("was not trusted.")) - } - - use crate::assert_invalid_cert_chain as assert_expired_error; - use crate::assert_invalid_cert_chain as assert_wrong_host; - use crate::assert_invalid_cert_chain as assert_self_signed; - use crate::assert_invalid_cert_chain as assert_untrusted_root; - } else { - fn assert_expired_error(err: &Error) { - let s = err.to_string(); - assert!(s.contains("system clock"), "error = {:?}", s); - } - - fn assert_wrong_host(err: &Error) { - let s = err.to_string(); - assert!(s.contains("CN name"), "error = {:?}", s); - } - - fn assert_self_signed(err: &Error) { - let s = err.to_string(); - assert!(s.contains("root certificate which is not trusted"), "error = {:?}", s); - } - - use assert_self_signed as assert_untrusted_root; - } -} - -async fn get_host(host: &'static str) -> Error { - drop(env_logger::try_init()); - - let addr = format!("{}:443", host); - let addr = t!(addr.to_socket_addrs()).next().unwrap(); - - let socket = t!(TcpStream::connect(&addr).await); - let builder = TlsConnector::builder(); - let cx = t!(builder.build()); - let cx = tokio_native_tls::TlsConnector::from(cx); - let res = cx - .connect(host, socket) - .await - .map_err(|e| Error::new(io::ErrorKind::Other, e)); - - assert!(res.is_err()); - res.err().unwrap() -} - -#[tokio::test] -async fn expired() { - assert_expired_error(&get_host("expired.badssl.com").await) -} - -// TODO: the OSX builders on Travis apparently fail this tests spuriously? -// passes locally though? Seems... bad! -#[tokio::test] -#[cfg_attr(all(target_os = "macos", feature = "force-openssl"), ignore)] -async fn wrong_host() { - assert_wrong_host(&get_host("wrong.host.badssl.com").await) -} - -#[tokio::test] -async fn self_signed() { - assert_self_signed(&get_host("self-signed.badssl.com").await) -} - -#[tokio::test] -async fn untrusted_root() { - assert_untrusted_root(&get_host("untrusted-root.badssl.com").await) -} diff --git a/tokio-native-tls/tests/cert.der b/tokio-native-tls/tests/cert.der deleted file mode 100644 index e1f964d6b79bd199b8487206aab0ff9b58af4fd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 799 zcmXqLVwN^&Vq#|EWN0t^zW3b>{iO!HY@Awc9&O)w85y}*84O$vxeYkkm_u3Egqa*e z4TTK^K^zVquHgLKRNdf`#FA7)MFV+|AQz8>XI@EaQC@0^LU?9MdS*$nLO@BSf=@|` zft)z6p_ze&p^2fnfq{W>lsK;uh-(Dp8bndW8kqB#dAQQ@^OF*b^pf*)4VoC0kbT9- z%D~*j$j<;2=VEGNWMo+JMYYFev-skG)_=+q+b>j@NqdU_*LA=ARQg_y*`H}US?oWV z-`oG*SZG)3(N9mddwH%rrIeDd@a3w>M86eJ?e|~hkSq#lSU7Fcg;^VCb(tmke|0+X z_0`NXtY=GhDm-}^AEm1Lb(iU+Qo2>+#bt$zQhOBJhr`8~AqNUewzYn&aj zx;G(CHnisTf{E*{OuD8%`Q~cY4Lp5mOBYT~zcrbMktejd(> zb0-+@y5-zs*kZkKb6#21LR;aE$#Q;2ulF!`2ZgQrx9gQioJ7^Ll!+TJiwGOvKF=R` z_SxMjcb435dH>8WKqN9|!M6)*t<7F&ahozRGcqtDhY&E{fg!}m;Ps7tM`tCsvpb8^ z`K5tpcWk?`!Gu>c;(PWyyKiefCn@v1y4IrF{^8Bq@V-33MT$XkQyAMHUrW_}=-2W> zKdtb?^fT_0^_aBo+VE`kQroZotK}fOXW^-3`yM^fHCehL?TGrPD?!W+O*_~vCtFVS z;Aqjj$LxPMV($43ca8Ve?fv_0#-iS&uFkNI#%mFxLS=g&8z*pP2I%-DJ-qDBm0_H6 zf0N_)UPG?VgOZxHA11#x+y1xILCN2vgRO#@_2TpSey5IcB9$j*-?4n zJ4dqPWNsa@neKn}ecLL>mok$DQv)U}RW{yJnNd^H+iW`Z%F& { - match $e { - Ok(e) => e, - Err(e) => panic!("{} failed with {:?}", stringify!($e), e), - } - }; -} - -cfg_if! { - if #[cfg(feature = "force-rustls")] { - fn assert_bad_hostname_error(err: &io::Error) { - let err = err.to_string(); - assert!(err.contains("CertNotValidForName"), "bad error: {}", err); - } - } else if #[cfg(any(feature = "force-openssl", - all(not(target_os = "macos"), - not(target_os = "windows"), - not(target_os = "ios"))))] { - fn assert_bad_hostname_error(err: &io::Error) { - let err = err.get_ref().unwrap(); - let err = err.downcast_ref::().unwrap(); - assert!(format!("{}", err).contains("certificate verify failed")); - } - } else if #[cfg(any(target_os = "macos", target_os = "ios"))] { - fn assert_bad_hostname_error(err: &io::Error) { - let err = err.get_ref().unwrap(); - let err = err.downcast_ref::().unwrap(); - assert!(format!("{}", err).contains("was not trusted.")); - } - } else { - fn assert_bad_hostname_error(err: &io::Error) { - let err = err.get_ref().unwrap(); - let err = err.downcast_ref::().unwrap(); - assert!(format!("{}", err).contains("CN name")); - } - } -} - -#[tokio::test] -async fn fetch_google() { - drop(env_logger::try_init()); - - // First up, resolve google.com - let addr = t!("google.com:443".to_socket_addrs()).next().unwrap(); - - let socket = TcpStream::connect(&addr).await.unwrap(); - - // Send off the request by first negotiating an SSL handshake, then writing - // of our request, then flushing, then finally read off the response. - let builder = TlsConnector::builder(); - let connector = t!(builder.build()); - let connector = tokio_native_tls::TlsConnector::from(connector); - let mut socket = t!(connector.connect("google.com", socket).await); - t!(socket.write_all(b"GET / HTTP/1.0\r\n\r\n").await); - let mut data = Vec::new(); - t!(socket.read_to_end(&mut data).await); - - // any response code is fine - assert!(data.starts_with(b"HTTP/1.0 ")); - - let data = String::from_utf8_lossy(&data); - let data = data.trim_end(); - assert!(data.ends_with("") || data.ends_with("")); -} - -fn native2io(e: native_tls::Error) -> io::Error { - io::Error::new(io::ErrorKind::Other, e) -} - -// see comment in bad.rs for ignore reason -#[cfg_attr(all(target_os = "macos", feature = "force-openssl"), ignore)] -#[tokio::test] -async fn wrong_hostname_error() { - drop(env_logger::try_init()); - - let addr = t!("google.com:443".to_socket_addrs()).next().unwrap(); - - let socket = t!(TcpStream::connect(&addr).await); - let builder = TlsConnector::builder(); - let connector = t!(builder.build()); - let connector = tokio_native_tls::TlsConnector::from(connector); - let res = connector - .connect("rust-lang.org", socket) - .await - .map_err(native2io); - - assert!(res.is_err()); - assert_bad_hostname_error(&res.err().unwrap()); -} diff --git a/tokio-native-tls/tests/identity.p12 b/tokio-native-tls/tests/identity.p12 deleted file mode 100644 index d16abb8c70627bd959667495e578fb6f010a7f1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3386 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 CKSRy{ diff --git a/tokio-native-tls/tests/root-ca.der b/tokio-native-tls/tests/root-ca.der deleted file mode 100644 index a9335c6fc2c81c3802c3d9ce20b0a83b124328a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 865 zcmXqLVvaRvVsc%;%*4pV#L4hTpHDUV`thj-ylk9WZ60mkc^MhGSs4sm4Y>_C*_cCF z*o2uJLk)!u1VJ1Q9qfVU#$p5r}I94=}PaFgG#sGZ-{6axpbA zGBT_Uye3vxrn|Fr`uw<~w`b0~8kDYZW4Xau{wLdX-T7XAaf}kJzq01V@waVhv!iz$ zTvpTjh^g!gN63#Ix=+|#1g2K0OR!uDS8MeNsq0(+wAiKp_l4NE3gMlPL@QdKCWpMA z&ZOU8oO}4r^SmZY2wonMv_e*dnN*PZxl z${CvXmX@9>anO4GZ0^CPI~(37ewVpC)WBZoOK(E!7oks&l};#1b{l$O8;Hdek0>8u>x zOGKuduVOfQ;lrys{_U*0xNYWU@XuNMqU*)>4?-sv)w*A(zW&eu$w9B_9!Zz=(-XgK zvviF=n%(P|Z@2sT)3bZH9-X-Oi?Oj^TvAi;X0ycE9J8K}T6Zn#HO@I@-TclFxjiRo zn$g96_wIk+-4zAyDxY1TrrMGn>QTG**|xWvo95U0ZhSXAmid`SU)!m2BMas$n?4_! z5__We(bsJW8C$a^N!7+A3%&TUM|pB?!#BD0y@vzb)m(1|UEOy_V$D_a*-TXuN^f+k w3ZnlkKK1iYhiC4b*#}RYzgH=FKQ?X}&$CaRvswPtH6Lm5TzJJ;Y|UN?0B@CI7XSbN diff --git a/tokio-native-tls/tests/smoke.rs b/tokio-native-tls/tests/smoke.rs deleted file mode 100644 index 994fdde..0000000 --- a/tokio-native-tls/tests/smoke.rs +++ /dev/null @@ -1,172 +0,0 @@ -use futures::join; -use lazy_static::lazy_static; -use native_tls::{Certificate, Identity}; -use std::{fs, io::Error, path::PathBuf, process::Command}; -use tokio::{ - io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}, - net::{TcpListener, TcpStream}, -}; -use tokio_native_tls::{TlsAcceptor, TlsConnector}; - -lazy_static! { - static ref CERT_DIR: PathBuf = { - if cfg!(unix) { - let dir = tempfile::TempDir::new().unwrap(); - let path = dir.path().to_str().unwrap(); - - Command::new("sh") - .arg("-c") - .arg(format!("./scripts/generate-certificate.sh {}", path)) - .output() - .expect("failed to execute process"); - - dir.into_path() - } else { - PathBuf::from("tests") - } - }; -} - -#[tokio::test] -async fn client_to_server() { - let srv = TcpListener::bind("127.0.0.1:0").await.unwrap(); - let addr = srv.local_addr().unwrap(); - - let (server_tls, client_tls) = context(); - - // Create a future to accept one socket, connect the ssl stream, and then - // read all the data from it. - let server = async move { - let (socket, _) = srv.accept().await.unwrap(); - let mut socket = server_tls.accept(socket).await.unwrap(); - - // Verify access to all of the nested inner streams (e.g. so that peer - // certificates can be accessed). This is just a compile check. - let native_tls_stream: &native_tls::TlsStream<_> = socket.get_ref(); - let _peer_cert = native_tls_stream.peer_certificate().unwrap(); - let allow_std_stream: &tokio_native_tls::AllowStd<_> = native_tls_stream.get_ref(); - let _tokio_tcp_stream: &tokio::net::TcpStream = allow_std_stream.get_ref(); - - let mut data = Vec::new(); - socket.read_to_end(&mut data).await.unwrap(); - data - }; - - // Create a future to connect to our server, connect the ssl stream, and - // then write a bunch of data to it. - let client = async move { - let socket = TcpStream::connect(&addr).await.unwrap(); - let socket = client_tls.connect("foobar.com", socket).await.unwrap(); - copy_data(socket).await - }; - - // Finally, run everything! - let (data, _) = join!(server, client); - // assert_eq!(amt, AMT); - assert!(data == vec![9; AMT]); -} - -#[tokio::test] -async fn server_to_client() { - // Create a server listening on a port, then figure out what that port is - let srv = TcpListener::bind("127.0.0.1:0").await.unwrap(); - let addr = srv.local_addr().unwrap(); - - let (server_tls, client_tls) = context(); - - let server = async move { - let (socket, _) = srv.accept().await.unwrap(); - let socket = server_tls.accept(socket).await.unwrap(); - copy_data(socket).await - }; - - let client = async move { - let socket = TcpStream::connect(&addr).await.unwrap(); - let mut socket = client_tls.connect("foobar.com", socket).await.unwrap(); - let mut data = Vec::new(); - socket.read_to_end(&mut data).await.unwrap(); - data - }; - - // Finally, run everything! - let (_, data) = join!(server, client); - assert!(data == vec![9; AMT]); -} - -#[tokio::test] -async fn one_byte_at_a_time() { - const AMT: usize = 1024; - - let srv = TcpListener::bind("127.0.0.1:0").await.unwrap(); - let addr = srv.local_addr().unwrap(); - - let (server_tls, client_tls) = context(); - - let server = async move { - let (socket, _) = srv.accept().await.unwrap(); - let mut socket = server_tls.accept(socket).await.unwrap(); - let mut amt = 0; - for b in std::iter::repeat(9).take(AMT) { - let data = [b as u8]; - socket.write_all(&data).await.unwrap(); - amt += 1; - } - amt - }; - - let client = async move { - let socket = TcpStream::connect(&addr).await.unwrap(); - let mut socket = client_tls.connect("foobar.com", socket).await.unwrap(); - let mut data = Vec::new(); - loop { - let mut buf = [0; 1]; - match socket.read_exact(&mut buf).await { - Ok(_) => data.extend_from_slice(&buf), - Err(ref err) if err.kind() == std::io::ErrorKind::UnexpectedEof => break, - Err(err) => panic!("{}", err), - } - } - data - }; - - let (amt, data) = join!(server, client); - assert_eq!(amt, AMT); - assert!(data == vec![9; AMT as usize]); -} - -fn context() -> (TlsAcceptor, TlsConnector) { - let pkcs12 = fs::read(CERT_DIR.join("identity.p12")).unwrap(); - let der = fs::read(CERT_DIR.join("root-ca.der")).unwrap(); - - let identity = Identity::from_pkcs12(&pkcs12, "mypass").unwrap(); - let acceptor = native_tls::TlsAcceptor::builder(identity).build().unwrap(); - - let cert = Certificate::from_der(&der).unwrap(); - let connector = native_tls::TlsConnector::builder() - .add_root_certificate(cert) - .build() - .unwrap(); - - (acceptor.into(), connector.into()) -} - -const AMT: usize = 128 * 1024; - -async fn copy_data(mut w: W) -> Result { - let mut data = vec![9; AMT as usize]; - let mut amt = 0; - while !data.is_empty() { - let written = w.write(&data).await?; - if written <= data.len() { - amt += written; - data.resize(data.len() - written, 0); - } else { - w.write_all(&data).await?; - amt += data.len(); - break; - } - - println!("remaining: {}", data.len()); - } - Ok(amt) -}