aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/ssl/tests/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/src/ssl/tests/mod.rs')
-rw-r--r--openssl/src/ssl/tests/mod.rs690
1 files changed, 396 insertions, 294 deletions
diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs
index 3bbbed03..a84f6b25 100644
--- a/openssl/src/ssl/tests/mod.rs
+++ b/openssl/src/ssl/tests/mod.rs
@@ -1,5 +1,6 @@
#![allow(unused_imports)]
+use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::io::{self, BufReader};
@@ -11,31 +12,26 @@ use std::process::{Command, Child, Stdio, ChildStdin};
use std::thread;
use std::time::Duration;
-use net2::TcpStreamExt;
+use tempdir::TempDir;
-use crypto::hash::Type::SHA256;
+use hash::MessageDigest;
use ssl;
use ssl::SSL_VERIFY_PEER;
-use ssl::SslMethod::Sslv23;
use ssl::{SslMethod, HandshakeError};
-use ssl::error::Error;
-use ssl::{SslContext, SslStream};
-use x509::X509StoreContext;
-use x509::X509FileType;
-use x509::X509;
-use crypto::pkey::PKey;
-
-#[cfg(feature="dtlsv1")]
+use ssl::{SslContext, SslStream, Ssl, ShutdownResult, SslConnectorBuilder, SslAcceptorBuilder,
+ Error};
+use x509::{X509StoreContext, X509, X509_FILETYPE_PEM};
+#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
+use x509::verify::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS;
+use pkey::PKey;
+
use std::net::UdpSocket;
-#[cfg(feature="dtlsv1")]
-use ssl::SslMethod::Dtlsv1;
-#[cfg(feature="sslv2")]
-use ssl::SslMethod::Sslv2;
-#[cfg(feature="dtlsv1")]
-use net2::UdpSocketExt;
mod select;
+static CERT: &'static [u8] = include_bytes!("../../../test/cert.pem");
+static KEY: &'static [u8] = include_bytes!("../../../test/key.pem");
+
fn next_addr() -> SocketAddr {
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
static PORT: AtomicUsize = ATOMIC_USIZE_INIT;
@@ -46,32 +42,42 @@ fn next_addr() -> SocketAddr {
struct Server {
p: Child,
+ _temp: TempDir,
}
impl Server {
fn spawn(args: &[&str], input: Option<Box<FnMut(ChildStdin) + Send>>) -> (Server, SocketAddr) {
+ let td = TempDir::new("openssl").unwrap();
+ let cert = td.path().join("cert.pem");
+ let key = td.path().join("key.pem");
+ File::create(&cert).unwrap().write_all(CERT).unwrap();
+ File::create(&key).unwrap().write_all(KEY).unwrap();
+
let addr = next_addr();
let mut child = Command::new("openssl")
- .arg("s_server")
- .arg("-accept")
- .arg(addr.port().to_string())
- .args(args)
- .arg("-cert")
- .arg("cert.pem")
- .arg("-key")
- .arg("key.pem")
- .arg("-no_dhe")
- .current_dir("test")
- .stdout(Stdio::null())
- .stderr(Stdio::null())
- .stdin(Stdio::piped())
- .spawn()
- .unwrap();
+ .arg("s_server")
+ .arg("-accept")
+ .arg(addr.port().to_string())
+ .args(args)
+ .arg("-cert")
+ .arg(&cert)
+ .arg("-key")
+ .arg(&key)
+ .arg("-no_dhe")
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .stdin(Stdio::piped())
+ .spawn()
+ .unwrap();
let stdin = child.stdin.take().unwrap();
if let Some(mut input) = input {
thread::spawn(move || input(stdin));
}
- (Server { p: child }, addr)
+ (Server {
+ p: child,
+ _temp: td,
+ },
+ addr)
}
fn new_tcp(args: &[&str]) -> (Server, TcpStream) {
@@ -92,7 +98,6 @@ impl Server {
Server::new_tcp(&["-www"])
}
- #[cfg(any(feature = "alpn", feature = "npn"))]
fn new_alpn() -> (Server, TcpStream) {
Server::new_tcp(&["-www",
"-nextprotoneg",
@@ -101,7 +106,6 @@ impl Server {
"http/1.1,spdy/3.1"])
}
- #[cfg(feature = "dtlsv1")]
fn new_dtlsv1<I>(input: I) -> (Server, UdpConnected)
where I: IntoIterator<Item = &'static str>,
I::IntoIter: Send + 'static
@@ -109,17 +113,17 @@ impl Server {
let mut input = input.into_iter();
let (s, addr) = Server::spawn(&["-dtls1"],
Some(Box::new(move |mut io| {
- for s in input.by_ref() {
- if io.write_all(s.as_bytes()).is_err() {
- break;
- }
- }
- })));
+ for s in input.by_ref() {
+ if io.write_all(s.as_bytes()).is_err() {
+ break;
+ }
+ }
+ })));
// Need to wait for the UDP socket to get bound in our child process,
// but don't currently have a great way to do that so just wait for a
// bit.
thread::sleep(Duration::from_millis(100));
- let socket = UdpSocket::bind(next_addr()).unwrap();
+ let socket = UdpSocket::bind("127.0.0.1:0").unwrap();
socket.connect(&addr).unwrap();
(s, UdpConnected(socket))
}
@@ -132,51 +136,18 @@ impl Drop for Server {
}
}
-#[cfg(feature = "dtlsv1")]
#[derive(Debug)]
struct UdpConnected(UdpSocket);
-#[cfg(feature = "dtlsv1")]
impl Read for UdpConnected {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- self.0.recv_from(buf).map(|(s, _)| s)
+ self.0.recv(buf)
}
}
-#[cfg(feature = "dtlsv1")]
impl Write for UdpConnected {
- #[cfg(unix)]
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- use std::os::unix::prelude::*;
- use libc;
- let n = unsafe {
- libc::send(self.0.as_raw_fd(),
- buf.as_ptr() as *const _,
- buf.len() as libc::size_t,
- 0)
- };
- if n < 0 {
- Err(io::Error::last_os_error())
- } else {
- Ok(n as usize)
- }
- }
-
- #[cfg(windows)]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- use std::os::windows::prelude::*;
- use libc;
- let n = unsafe {
- libc::send(self.0.as_raw_socket(),
- buf.as_ptr() as *const _,
- buf.len() as libc::c_int,
- 0)
- };
- if n < 0 {
- Err(io::Error::last_os_error())
- } else {
- Ok(n as usize)
- }
+ self.0.send(buf)
}
fn flush(&mut self) -> io::Result<()> {
@@ -197,147 +168,139 @@ macro_rules! run_test(
use ssl::SslMethod;
use ssl::{SslContext, Ssl, SslStream};
use ssl::SSL_VERIFY_PEER;
- use crypto::hash::Type::{SHA1, SHA256};
+ use hash::MessageDigest;
use x509::X509StoreContext;
use serialize::hex::FromHex;
+ use types::OpenSslTypeRef;
use super::Server;
#[test]
fn sslv23() {
let (_s, stream) = Server::new();
- $blk(SslMethod::Sslv23, stream);
+ $blk(SslMethod::tls(), stream);
}
#[test]
- #[cfg(feature="dtlsv1")]
+ #[cfg_attr(any(windows, target_arch = "arm"), ignore)] // FIXME(#467)
fn dtlsv1() {
let (_s, stream) = Server::new_dtlsv1(Some("hello"));
- $blk(SslMethod::Dtlsv1, stream);
+ $blk(SslMethod::dtls(), stream);
}
}
);
);
run_test!(new_ctx, |method, _| {
- SslContext::new(method).unwrap();
-});
-
-run_test!(new_sslstream, |method, stream| {
- SslStream::connect(&SslContext::new(method).unwrap(), stream).unwrap();
-});
-
-run_test!(get_ssl_method, |method, _| {
- let ssl = Ssl::new(&SslContext::new(method).unwrap()).unwrap();
- assert_eq!(ssl.ssl_method(), method);
+ SslContext::builder(method).unwrap();
});
run_test!(verify_untrusted, |method, stream| {
- let mut ctx = SslContext::new(method).unwrap();
+ let mut ctx = SslContext::builder(method).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- match SslStream::connect(&ctx, stream) {
+ match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(_) => panic!("expected failure"),
Err(err) => println!("error {:?}", err),
}
});
run_test!(verify_trusted, |method, stream| {
- let mut ctx = SslContext::new(method).unwrap();
+ let mut ctx = SslContext::builder(method).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
+ match ctx.set_ca_file(&Path::new("test/root-ca.pem")) {
Ok(_) => {}
Err(err) => panic!("Unexpected error {:?}", err),
}
- match SslStream::connect(&ctx, stream) {
+ match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(_) => (),
Err(err) => panic!("Expected success, got {:?}", err),
}
});
run_test!(verify_untrusted_callback_override_ok, |method, stream| {
- let mut ctx = SslContext::new(method).unwrap();
+ let mut ctx = SslContext::builder(method).unwrap();
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, _| true);
- match SslStream::connect(&ctx, stream) {
+ match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(_) => (),
Err(err) => panic!("Expected success, got {:?}", err),
}
});
run_test!(verify_untrusted_callback_override_bad, |method, stream| {
- let mut ctx = SslContext::new(method).unwrap();
+ let mut ctx = SslContext::builder(method).unwrap();
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, _| false);
- assert!(SslStream::connect(&ctx, stream).is_err());
+ assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_err());
});
run_test!(verify_trusted_callback_override_ok, |method, stream| {
- let mut ctx = SslContext::new(method).unwrap();
+ let mut ctx = SslContext::builder(method).unwrap();
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, _| true);
- match ctx.set_CA_file(&Path::new("test/cert.pem")) {
+ match ctx.set_ca_file(&Path::new("test/cert.pem")) {
Ok(_) => {}
Err(err) => panic!("Unexpected error {:?}", err),
}
- match SslStream::connect(&ctx, stream) {
+ match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(_) => (),
Err(err) => panic!("Expected success, got {:?}", err),
}
});
run_test!(verify_trusted_callback_override_bad, |method, stream| {
- let mut ctx = SslContext::new(method).unwrap();
+ let mut ctx = SslContext::builder(method).unwrap();
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, _| false);
- match ctx.set_CA_file(&Path::new("test/cert.pem")) {
+ match ctx.set_ca_file(&Path::new("test/cert.pem")) {
Ok(_) => {}
Err(err) => panic!("Unexpected error {:?}", err),
}
- assert!(SslStream::connect(&ctx, stream).is_err());
+ assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_err());
});
run_test!(verify_callback_load_certs, |method, stream| {
- let mut ctx = SslContext::new(method).unwrap();
+ let mut ctx = SslContext::builder(method).unwrap();
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, x509_ctx| {
assert!(x509_ctx.current_cert().is_some());
true
});
- assert!(SslStream::connect(&ctx, stream).is_ok());
+ assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_ok());
});
run_test!(verify_trusted_get_error_ok, |method, stream| {
- let mut ctx = SslContext::new(method).unwrap();
+ let mut ctx = SslContext::builder(method).unwrap();
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, x509_ctx| {
assert!(x509_ctx.error().is_none());
true
});
- match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
+ match ctx.set_ca_file(&Path::new("test/root-ca.pem")) {
Ok(_) => {}
Err(err) => panic!("Unexpected error {:?}", err),
}
- assert!(SslStream::connect(&ctx, stream).is_ok());
+ assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_ok());
});
run_test!(verify_trusted_get_error_err, |method, stream| {
- let mut ctx = SslContext::new(method).unwrap();
+ let mut ctx = SslContext::builder(method).unwrap();
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, x509_ctx| {
assert!(x509_ctx.error().is_some());
false
});
- assert!(SslStream::connect(&ctx, stream).is_err());
+ assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_err());
});
run_test!(verify_callback_data, |method, stream| {
- let mut ctx = SslContext::new(method).unwrap();
+ let mut ctx = SslContext::builder(method).unwrap();
- // Node id was generated as SHA256 hash of certificate "test/cert.pem"
- // in DER format.
- // Command: openssl x509 -in test/cert.pem -outform DER | openssl dgst -sha256
- // Please update if "test/cert.pem" will ever change
+// Node id was generated as SHA256 hash of certificate "test/cert.pem"
+// in DER format.
+// Command: openssl x509 -in test/cert.pem -outform DER | openssl dgst -sha256
+// Please update if "test/cert.pem" will ever change
let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
let node_id = node_hash_str.from_hex().unwrap();
ctx.set_verify_callback(SSL_VERIFY_PEER, move |_preverify_ok, x509_ctx| {
@@ -345,14 +308,14 @@ run_test!(verify_callback_data, |method, stream| {
match cert {
None => false,
Some(cert) => {
- let fingerprint = cert.fingerprint(SHA1).unwrap();
+ let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
fingerprint == node_id
}
}
});
ctx.set_verify_depth(1);
- match SslStream::connect(&ctx, stream) {
+ match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(_) => (),
Err(err) => panic!("Expected success, got {:?}", err),
}
@@ -360,12 +323,11 @@ run_test!(verify_callback_data, |method, stream| {
run_test!(ssl_verify_callback, |method, stream| {
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
- use ssl::IntoSsl;
static CHECKED: AtomicUsize = ATOMIC_USIZE_INIT;
- let ctx = SslContext::new(method).unwrap();
- let mut ssl = ctx.into_ssl().unwrap();
+ let ctx = SslContext::builder(method).unwrap();
+ let mut ssl = Ssl::new(&ctx.build()).unwrap();
let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
let node_id = node_hash_str.from_hex().unwrap();
@@ -374,13 +336,13 @@ run_test!(ssl_verify_callback, |method, stream| {
match x509.current_cert() {
None => false,
Some(cert) => {
- let fingerprint = cert.fingerprint(SHA1).unwrap();
+ let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
fingerprint == node_id
}
}
});
- match SslStream::connect(ssl, stream) {
+ match ssl.connect(stream) {
Ok(_) => (),
Err(err) => panic!("Expected success, got {:?}", err),
}
@@ -391,24 +353,24 @@ run_test!(ssl_verify_callback, |method, stream| {
// Make sure every write call translates to a write call to the underlying socket.
#[test]
fn test_write_hits_stream() {
- let listener = TcpListener::bind(next_addr()).unwrap();
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().unwrap();
let guard = thread::spawn(move || {
- let ctx = SslContext::new(Sslv23).unwrap();
+ let ctx = SslContext::builder(SslMethod::tls()).unwrap();
let stream = TcpStream::connect(addr).unwrap();
- let mut stream = SslStream::connect(&ctx, stream).unwrap();
+ let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap();
stream.write_all(b"hello").unwrap();
stream
});
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM).unwrap();
- ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM).unwrap();
+ ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM).unwrap();
+ ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM).unwrap();
let stream = listener.accept().unwrap().0;
- let mut stream = SslStream::accept(&ctx, stream).unwrap();
+ let mut stream = Ssl::new(&ctx.build()).unwrap().accept(stream).unwrap();
let mut buf = [0; 5];
assert_eq!(5, stream.read(&mut buf).unwrap());
@@ -423,7 +385,7 @@ fn test_set_certificate_and_private_key() {
let cert = include_bytes!("../../../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_private_key(&key).unwrap();
ctx.set_certificate(&cert).unwrap();
@@ -431,18 +393,18 @@ fn test_set_certificate_and_private_key() {
}
run_test!(get_ctx_options, |method, _| {
- let ctx = SslContext::new(method).unwrap();
+ let ctx = SslContext::builder(method).unwrap();
ctx.options();
});
run_test!(set_ctx_options, |method, _| {
- let mut ctx = SslContext::new(method).unwrap();
+ let mut ctx = SslContext::builder(method).unwrap();
let opts = ctx.set_options(ssl::SSL_OP_NO_TICKET);
assert!(opts.contains(ssl::SSL_OP_NO_TICKET));
});
run_test!(clear_ctx_options, |method, _| {
- let mut ctx = SslContext::new(method).unwrap();
+ let mut ctx = SslContext::builder(method).unwrap();
ctx.set_options(ssl::SSL_OP_ALL);
let opts = ctx.clear_options(ssl::SSL_OP_ALL);
assert!(!opts.contains(ssl::SSL_OP_ALL));
@@ -451,17 +413,8 @@ run_test!(clear_ctx_options, |method, _| {
#[test]
fn test_write() {
let (_s, stream) = Server::new();
- let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), stream).unwrap();
- stream.write_all("hello".as_bytes()).unwrap();
- stream.flush().unwrap();
- stream.write_all(" there".as_bytes()).unwrap();
- stream.flush().unwrap();
-}
-
-#[test]
-fn test_write_direct() {
- let (_s, stream) = Server::new();
- let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), stream).unwrap();
+ let ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap();
stream.write_all("hello".as_bytes()).unwrap();
stream.flush().unwrap();
stream.write_all(" there".as_bytes()).unwrap();
@@ -469,20 +422,21 @@ fn test_write_direct() {
}
run_test!(get_peer_certificate, |method, stream| {
- let stream = SslStream::connect(&SslContext::new(method).unwrap(), stream).unwrap();
+ let ctx = SslContext::builder(method).unwrap();
+ let stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap();
let cert = stream.ssl().peer_certificate().unwrap();
- let fingerprint = cert.fingerprint(SHA1).unwrap();
+ let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
let node_id = node_hash_str.from_hex().unwrap();
assert_eq!(node_id, fingerprint)
});
#[test]
-#[cfg(feature = "dtlsv1")]
+#[cfg_attr(any(windows, target_arch = "arm"), ignore)] // FIXME(#467)
fn test_write_dtlsv1() {
let (_s, stream) = Server::new_dtlsv1(iter::repeat("y\n"));
-
- let mut stream = SslStream::connect(&SslContext::new(Dtlsv1).unwrap(), stream).unwrap();
+ let ctx = SslContext::builder(SslMethod::dtls()).unwrap();
+ let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap();
stream.write_all(b"hello").unwrap();
stream.flush().unwrap();
stream.write_all(b" there").unwrap();
@@ -492,16 +446,8 @@ fn test_write_dtlsv1() {
#[test]
fn test_read() {
let (_s, tcp) = Server::new();
- let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
- stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
- stream.flush().unwrap();
- io::copy(&mut stream, &mut io::sink()).ok().expect("read error");
-}
-
-#[test]
-fn test_read_direct() {
- let (_s, tcp) = Server::new();
- let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
+ let ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ let mut stream = Ssl::new(&ctx.build()).unwrap().connect(tcp).unwrap();
stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
stream.flush().unwrap();
io::copy(&mut stream, &mut io::sink()).ok().expect("read error");
@@ -510,7 +456,8 @@ fn test_read_direct() {
#[test]
fn test_pending() {
let (_s, tcp) = Server::new();
- let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
+ let ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ let mut stream = Ssl::new(&ctx.build()).unwrap().connect(tcp).unwrap();
stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
stream.flush().unwrap();
@@ -533,7 +480,8 @@ fn test_pending() {
#[test]
fn test_state() {
let (_s, tcp) = Server::new();
- let stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
+ let ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ let stream = Ssl::new(&ctx.build()).unwrap().connect(tcp).unwrap();
assert_eq!(stream.ssl().state_string(), "SSLOK ");
assert_eq!(stream.ssl().state_string_long(),
"SSL negotiation finished successfully");
@@ -542,17 +490,17 @@ fn test_state() {
/// Tests that connecting with the client using ALPN, but the server not does not
/// break the existing connection behavior.
#[test]
-#[cfg(feature = "alpn")]
+#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
fn test_connect_with_unilateral_alpn() {
let (_s, stream) = Server::new();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
- match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
+ ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap();
+ match ctx.set_ca_file(&Path::new("test/root-ca.pem")) {
Ok(_) => {}
Err(err) => panic!("Unexpected error {:?}", err),
}
- let stream = match SslStream::connect(&ctx, stream) {
+ let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(stream) => stream,
Err(err) => panic!("Expected success, got {:?}", err),
};
@@ -564,17 +512,16 @@ fn test_connect_with_unilateral_alpn() {
/// Tests that connecting with the client using NPN, but the server not does not
/// break the existing connection behavior.
#[test]
-#[cfg(feature = "npn")]
fn test_connect_with_unilateral_npn() {
let (_s, stream) = Server::new();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]);
- match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
+ ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap();
+ match ctx.set_ca_file(&Path::new("test/root-ca.pem")) {
Ok(_) => {}
Err(err) => panic!("Unexpected error {:?}", err),
}
- let stream = match SslStream::connect(&ctx, stream) {
+ let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(stream) => stream,
Err(err) => panic!("Expected success, got {:?}", err),
};
@@ -586,17 +533,17 @@ fn test_connect_with_unilateral_npn() {
/// Tests that when both the client as well as the server use ALPN and their
/// lists of supported protocols have an overlap, the correct protocol is chosen.
#[test]
-#[cfg(feature = "alpn")]
+#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
fn test_connect_with_alpn_successful_multiple_matching() {
let (_s, stream) = Server::new_alpn();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]);
- match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
+ ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]).unwrap();
+ match ctx.set_ca_file(&Path::new("test/root-ca.pem")) {
Ok(_) => {}
Err(err) => panic!("Unexpected error {:?}", err),
}
- let stream = match SslStream::connect(&ctx, stream) {
+ let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(stream) => stream,
Err(err) => panic!("Expected success, got {:?}", err),
};
@@ -608,17 +555,17 @@ fn test_connect_with_alpn_successful_multiple_matching() {
/// Tests that when both the client as well as the server use NPN and their
/// lists of supported protocols have an overlap, the correct protocol is chosen.
#[test]
-#[cfg(feature = "npn")]
+#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
fn test_connect_with_npn_successful_multiple_matching() {
let (_s, stream) = Server::new_alpn();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_npn_protocols(&[b"spdy/3.1", b"http/1.1"]);
- match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
+ ctx.set_npn_protocols(&[b"spdy/3.1", b"http/1.1"]).unwrap();
+ match ctx.set_ca_file(&Path::new("test/root-ca.pem")) {
Ok(_) => {}
Err(err) => panic!("Unexpected error {:?}", err),
}
- let stream = match SslStream::connect(&ctx, stream) {
+ let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(stream) => stream,
Err(err) => panic!("Expected success, got {:?}", err),
};
@@ -631,17 +578,17 @@ fn test_connect_with_npn_successful_multiple_matching() {
/// lists of supported protocols have an overlap -- with only ONE protocol
/// being valid for both.
#[test]
-#[cfg(feature = "alpn")]
+#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
fn test_connect_with_alpn_successful_single_match() {
let (_s, stream) = Server::new_alpn();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_alpn_protocols(&[b"spdy/3.1"]);
- match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
+ ctx.set_alpn_protocols(&[b"spdy/3.1"]).unwrap();
+ match ctx.set_ca_file(&Path::new("test/root-ca.pem")) {
Ok(_) => {}
Err(err) => panic!("Unexpected error {:?}", err),
}
- let stream = match SslStream::connect(&ctx, stream) {
+ let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(stream) => stream,
Err(err) => panic!("Expected success, got {:?}", err),
};
@@ -655,17 +602,17 @@ fn test_connect_with_alpn_successful_single_match() {
/// lists of supported protocols have an overlap -- with only ONE protocol
/// being valid for both.
#[test]
-#[cfg(feature = "npn")]
+#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
fn test_connect_with_npn_successful_single_match() {
let (_s, stream) = Server::new_alpn();
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_npn_protocols(&[b"spdy/3.1"]);
- match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
+ ctx.set_npn_protocols(&[b"spdy/3.1"]).unwrap();
+ match ctx.set_ca_file(&Path::new("test/root-ca.pem")) {
Ok(_) => {}
Err(err) => panic!("Unexpected error {:?}", err),
}
- let stream = match SslStream::connect(&ctx, stream) {
+ let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(stream) => stream,
Err(err) => panic!("Expected success, got {:?}", err),
};
@@ -677,37 +624,36 @@ fn test_connect_with_npn_successful_single_match() {
/// Tests that when the `SslStream` is created as a server stream, the protocols
/// are correctly advertised to the client.
#[test]
-#[cfg(feature = "npn")]
fn test_npn_server_advertise_multiple() {
- let listener = TcpListener::bind(next_addr()).unwrap();
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let localhost = listener.local_addr().unwrap();
// We create a different context instance for the server...
let listener_ctx = {
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]);
- assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
+ ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap();
+ assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.is_ok());
- ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM)
- .unwrap();
- ctx
+ ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
+ .unwrap();
+ ctx.build()
};
// Have the listener wait on the connection in a different thread.
thread::spawn(move || {
let (stream, _) = listener.accept().unwrap();
- let _ = SslStream::accept(&listener_ctx, stream).unwrap();
+ Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap();
});
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_npn_protocols(&[b"spdy/3.1"]);
- match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
+ ctx.set_npn_protocols(&[b"spdy/3.1"]).unwrap();
+ match ctx.set_ca_file(&Path::new("test/root-ca.pem")) {
Ok(_) => {}
Err(err) => panic!("Unexpected error {:?}", err),
}
// Now connect to the socket and make sure the protocol negotiation works...
let stream = TcpStream::connect(localhost).unwrap();
- let stream = match SslStream::connect(&ctx, stream) {
+ let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(stream) => stream,
Err(err) => panic!("Expected success, got {:?}", err),
};
@@ -718,37 +664,37 @@ fn test_npn_server_advertise_multiple() {
/// Tests that when the `SslStream` is created as a server stream, the protocols
/// are correctly advertised to the client.
#[test]
-#[cfg(feature = "alpn")]
+#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
fn test_alpn_server_advertise_multiple() {
- let listener = TcpListener::bind(next_addr()).unwrap();
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let localhost = listener.local_addr().unwrap();
// We create a different context instance for the server...
let listener_ctx = {
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
- assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
+ ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap();
+ assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.is_ok());
- ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM)
- .unwrap();
- ctx
+ ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
+ .unwrap();
+ ctx.build()
};
// Have the listener wait on the connection in a different thread.
thread::spawn(move || {
let (stream, _) = listener.accept().unwrap();
- let _ = SslStream::accept(&listener_ctx, stream).unwrap();
+ Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap();
});
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_alpn_protocols(&[b"spdy/3.1"]);
- match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
+ ctx.set_alpn_protocols(&[b"spdy/3.1"]).unwrap();
+ match ctx.set_ca_file(&Path::new("test/root-ca.pem")) {
Ok(_) => {}
Err(err) => panic!("Unexpected error {:?}", err),
}
// Now connect to the socket and make sure the protocol negotiation works...
let stream = TcpStream::connect(localhost).unwrap();
- let stream = match SslStream::connect(&ctx, stream) {
+ let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) {
Ok(stream) => stream,
Err(err) => panic!("Expected success, got {:?}", err),
};
@@ -759,87 +705,82 @@ fn test_alpn_server_advertise_multiple() {
/// Test that Servers supporting ALPN don't report a protocol when none of their protocols match
/// the client's reported protocol.
#[test]
-#[cfg(feature = "alpn")]
+#[cfg(all(feature = "v102", ossl102))]
fn test_alpn_server_select_none() {
- let listener = TcpListener::bind(next_addr()).unwrap();
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let localhost = listener.local_addr().unwrap();
// We create a different context instance for the server...
let listener_ctx = {
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
- assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
+ ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap();
+ assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
.is_ok());
- ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM)
- .unwrap();
- ctx
+ ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
+ .unwrap();
+ ctx.build()
};
// Have the listener wait on the connection in a different thread.
thread::spawn(move || {
let (stream, _) = listener.accept().unwrap();
- let _ = SslStream::accept(&listener_ctx, stream).unwrap();
+ Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap();
});
- let mut ctx = SslContext::new(Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
- ctx.set_alpn_protocols(&[b"http/2"]);
- match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
- Ok(_) => {}
- Err(err) => panic!("Unexpected error {:?}", err),
- }
+ ctx.set_alpn_protocols(&[b"http/2"]).unwrap();
+ ctx.set_ca_file(&Path::new("test/root-ca.pem")).unwrap();
// Now connect to the socket and make sure the protocol negotiation works...
let stream = TcpStream::connect(localhost).unwrap();
- let stream = match SslStream::connect(&ctx, stream) {
- Ok(stream) => stream,
- Err(err) => panic!("Expected success, got {:?}", err),
- };
+ let stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap();
// Since the protocols from the server and client don't overlap at all, no protocol is selected
assert_eq!(None, stream.ssl().selected_alpn_protocol());
}
+// In 1.1.0, ALPN negotiation failure is a fatal error
+#[test]
+#[cfg(all(feature = "v110", ossl110))]
+fn test_alpn_server_select_none() {
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
+ let localhost = listener.local_addr().unwrap();
+ // We create a different context instance for the server...
+ let listener_ctx = {
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ ctx.set_verify(SSL_VERIFY_PEER);
+ ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap();
+ assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM)
+ .is_ok());
+ ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM)
+ .unwrap();
+ ctx.build()
+ };
+ // Have the listener wait on the connection in a different thread.
+ thread::spawn(move || {
+ let (stream, _) = listener.accept().unwrap();
+ assert!(Ssl::new(&listener_ctx).unwrap().accept(stream).is_err());
+ });
-#[cfg(feature="dtlsv1")]
-#[cfg(test)]
-mod dtlsv1 {
- use serialize::hex::FromHex;
- use std::net::TcpStream;
- use std::thread;
-
- use crypto::hash::Type::SHA256;
- use ssl::SslMethod;
- use ssl::SslMethod::Dtlsv1;
- use ssl::{SslContext, SslStream};
- use ssl::SSL_VERIFY_PEER;
- use x509::X509StoreContext;
-
- const PROTOCOL: SslMethod = Dtlsv1;
-
- #[test]
- fn test_new_ctx() {
- SslContext::new(PROTOCOL).unwrap();
- }
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ ctx.set_verify(SSL_VERIFY_PEER);
+ ctx.set_alpn_protocols(&[b"http/2"]).unwrap();
+ ctx.set_ca_file(&Path::new("test/root-ca.pem")).unwrap();
+ // Now connect to the socket and make sure the protocol negotiation works...
+ let stream = TcpStream::connect(localhost).unwrap();
+ assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_err());
}
#[test]
-#[cfg(feature = "dtlsv1")]
+#[cfg_attr(any(windows, target_arch = "arm"), ignore)] // FIXME(#467)
fn test_read_dtlsv1() {
let (_s, stream) = Server::new_dtlsv1(Some("hello"));
- let mut stream = SslStream::connect(&SslContext::new(Dtlsv1).unwrap(), stream).unwrap();
+ let ctx = SslContext::builder(SslMethod::dtls()).unwrap();
+ let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap();
let mut buf = [0u8; 100];
assert!(stream.read(&mut buf).is_ok());
}
-#[test]
-#[cfg(feature = "sslv2")]
-fn test_sslv2_connect_failure() {
- let (_s, tcp) = Server::new_tcp(&["-no_ssl2", "-www"]);
- SslStream::connect(&SslContext::new(Sslv2).unwrap(), tcp)
- .err()
- .unwrap();
-}
-
fn wait_io(stream: &TcpStream, read: bool, timeout_ms: u32) -> bool {
unsafe {
let mut set: select::fd_set = mem::zeroed();
@@ -859,8 +800,7 @@ fn wait_io(stream: &TcpStream, read: bool, timeout_ms: u32) -> bool {
}
}
-fn handshake(res: Result<SslStream<TcpStream>, HandshakeError<TcpStream>>)
- -> SslStream<TcpStream> {
+fn handshake(res: Result<SslStream<TcpStream>, HandshakeError<TcpStream>>) -> SslStream<TcpStream> {
match res {
Ok(s) => s,
Err(HandshakeError::Interrupted(s)) => {
@@ -875,8 +815,8 @@ fn handshake(res: Result<SslStream<TcpStream>, HandshakeError<TcpStream>>)
fn test_write_nonblocking() {
let (_s, stream) = Server::new();
stream.set_nonblocking(true).unwrap();
- let cx = SslContext::new(Sslv23).unwrap();
- let mut stream = handshake(SslStream::connect(&cx, stream));
+ let cx = SslContext::builder(SslMethod::tls()).unwrap().build();
+ let mut stream = handshake(Ssl::new(&cx).unwrap().connect(stream));
let mut iterations = 0;
loop {
@@ -909,12 +849,12 @@ fn test_write_nonblocking() {
}
#[test]
-#[cfg_attr(windows, ignore)] // FIXME flickers on appveyor
+#[cfg_attr(any(windows, target_arch = "arm"), ignore)] // FIXME(#467)
fn test_read_nonblocking() {
let (_s, stream) = Server::new();
stream.set_nonblocking(true).unwrap();
- let cx = SslContext::new(Sslv23).unwrap();
- let mut stream = handshake(SslStream::connect(&cx, stream));
+ let cx = SslContext::builder(SslMethod::tls()).unwrap().build();
+ let mut stream = handshake(Ssl::new(&cx).unwrap().connect(stream));
let mut iterations = 0;
loop {
@@ -965,7 +905,6 @@ fn test_read_nonblocking() {
#[test]
#[should_panic(expected = "blammo")]
-#[cfg(feature = "nightly")]
fn write_panic() {
struct ExplodingStream(TcpStream);
@@ -988,13 +927,12 @@ fn write_panic() {
let (_s, stream) = Server::new();
let stream = ExplodingStream(stream);
- let ctx = SslContext::new(SslMethod::Sslv23).unwrap();
- let _ = SslStream::connect(&ctx, stream);
+ let ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ let _ = Ssl::new(&ctx.build()).unwrap().connect(stream);
}
#[test]
#[should_panic(expected = "blammo")]
-#[cfg(feature = "nightly")]
fn read_panic() {
struct ExplodingStream(TcpStream);
@@ -1017,13 +955,12 @@ fn read_panic() {
let (_s, stream) = Server::new();
let stream = ExplodingStream(stream);
- let ctx = SslContext::new(SslMethod::Sslv23).unwrap();
- let _ = SslStream::connect(&ctx, stream);
+ let ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ let _ = Ssl::new(&ctx.build()).unwrap().connect(stream);
}
#[test]
#[should_panic(expected = "blammo")]
-#[cfg(feature = "nightly")]
fn flush_panic() {
struct ExplodingStream(TcpStream);
@@ -1046,32 +983,31 @@ fn flush_panic() {
let (_s, stream) = Server::new();
let stream = ExplodingStream(stream);
- let ctx = SslContext::new(SslMethod::Sslv23).unwrap();
- let mut stream = SslStream::connect(&ctx, stream).unwrap();
+ let ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).ok().unwrap();
let _ = stream.flush();
}
#[test]
fn refcount_ssl_context() {
let mut ssl = {
- let ctx = SslContext::new(SslMethod::Sslv23).unwrap();
- ssl::Ssl::new(&ctx).unwrap()
+ let ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ ssl::Ssl::new(&ctx.build()).unwrap()
};
{
- let new_ctx_a = SslContext::new(SslMethod::Sslv23).unwrap();
+ let new_ctx_a = SslContext::builder(SslMethod::tls()).unwrap().build();
let _new_ctx_b = ssl.set_ssl_context(&new_ctx_a);
}
}
#[test]
-#[cfg_attr(windows, ignore)] // don't have a trusted CA list easily available :(
fn default_verify_paths() {
- let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_default_verify_paths().unwrap();
ctx.set_verify(SSL_VERIFY_PEER);
let s = TcpStream::connect("google.com:443").unwrap();
- let mut socket = SslStream::connect(&ctx, s).unwrap();
+ let mut socket = Ssl::new(&ctx.build()).unwrap().connect(s).unwrap();
socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
let mut result = vec![];
@@ -1086,6 +1022,172 @@ fn default_verify_paths() {
fn add_extra_chain_cert() {
let cert = include_bytes!("../../../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
- let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap();
- ctx.add_extra_chain_cert(&cert).unwrap();
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ ctx.add_extra_chain_cert(cert).unwrap();
+}
+
+#[test]
+#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
+fn verify_valid_hostname() {
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ ctx.set_default_verify_paths().unwrap();
+ ctx.set_verify(SSL_VERIFY_PEER);
+
+ let mut ssl = Ssl::new(&ctx.build()).unwrap();
+ ssl.param_mut().set_hostflags(X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+ ssl.param_mut().set_host("google.com").unwrap();
+
+ let s = TcpStream::connect("google.com:443").unwrap();
+ let mut socket = ssl.connect(s).unwrap();
+
+ socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
+ let mut result = vec![];
+ socket.read_to_end(&mut result).unwrap();
+
+ println!("{}", String::from_utf8_lossy(&result));
+ assert!(result.starts_with(b"HTTP/1.0"));
+ assert!(result.ends_with(b"</HTML>\r\n") || result.ends_with(b"</html>"));
+}
+
+#[test]
+#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
+fn verify_invalid_hostname() {
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ ctx.set_default_verify_paths().unwrap();
+ ctx.set_verify(SSL_VERIFY_PEER);
+
+ let mut ssl = Ssl::new(&ctx.build()).unwrap();
+ ssl.param_mut().set_hostflags(X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+ ssl.param_mut().set_host("foobar.com").unwrap();
+
+ let s = TcpStream::connect("google.com:443").unwrap();
+ assert!(ssl.connect(s).is_err());
+}
+
+#[test]
+fn connector_valid_hostname() {
+ let connector = SslConnectorBuilder::new(SslMethod::tls()).unwrap().build();
+
+ let s = TcpStream::connect("google.com:443").unwrap();
+ let mut socket = connector.connect("google.com", s).unwrap();
+
+ socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
+ let mut result = vec![];
+ socket.read_to_end(&mut result).unwrap();
+
+ println!("{}", String::from_utf8_lossy(&result));
+ assert!(result.starts_with(b"HTTP/1.0"));
+ assert!(result.ends_with(b"</HTML>\r\n") || result.ends_with(b"</html>"));
+}
+
+#[test]
+fn connector_invalid_hostname() {
+ let connector = SslConnectorBuilder::new(SslMethod::tls()).unwrap().build();
+
+ let s = TcpStream::connect("google.com:443").unwrap();
+ assert!(connector.connect("foobar.com", s).is_err());
+}
+
+#[test]
+fn connector_client_server_mozilla_intermediate() {
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
+ let port = listener.local_addr().unwrap().port();
+
+ let t = thread::spawn(move || {
+ let key = PKey::private_key_from_pem(KEY).unwrap();
+ let cert = X509::from_pem(CERT).unwrap();
+ let connector =
+ SslAcceptorBuilder::mozilla_intermediate(SslMethod::tls(), &key, &cert, None::<X509>)
+ .unwrap()
+ .build();
+ let stream = listener.accept().unwrap().0;
+ let mut stream = connector.accept(stream).unwrap();
+
+ stream.write_all(b"hello").unwrap();
+ });
+
+ let mut connector = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
+ connector.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
+ let connector = connector.build();
+
+ let stream = TcpStream::connect(("127.0.0.1", port)).unwrap();
+ let mut stream = connector.connect("foobar.com", stream).unwrap();
+
+ let mut buf = [0; 5];
+ stream.read_exact(&mut buf).unwrap();
+ assert_eq!(b"hello", &buf);
+
+ t.join().unwrap();
+}
+
+#[test]
+fn connector_client_server_mozilla_modern() {
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
+ let port = listener.local_addr().unwrap().port();
+
+ let t = thread::spawn(move || {
+ let key = PKey::private_key_from_pem(KEY).unwrap();
+ let cert = X509::from_pem(CERT).unwrap();
+ let connector =
+ SslAcceptorBuilder::mozilla_modern(SslMethod::tls(), &key, &cert, None::<X509>)
+ .unwrap()
+ .build();
+ let stream = listener.accept().unwrap().0;
+ let mut stream = connector.accept(stream).unwrap();
+
+ stream.write_all(b"hello").unwrap();
+ });
+
+ let mut connector = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
+ connector.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
+ let connector = connector.build();
+
+ let stream = TcpStream::connect(("127.0.0.1", port)).unwrap();
+ let mut stream = connector.connect("foobar.com", stream).unwrap();
+
+ let mut buf = [0; 5];
+ stream.read_exact(&mut buf).unwrap();
+ assert_eq!(b"hello", &buf);
+
+ t.join().unwrap();
+}
+
+#[test]
+fn shutdown() {
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
+ let port = listener.local_addr().unwrap().port();
+
+ thread::spawn(move || {
+ let stream = listener.accept().unwrap().0;
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM).unwrap();
+ ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM).unwrap();
+ let ssl = Ssl::new(&ctx.build()).unwrap();
+ let mut stream = ssl.accept(stream).unwrap();
+
+ stream.write_all(b"hello").unwrap();
+ let mut buf = [0; 1];
+ assert_eq!(stream.read(&mut buf).unwrap(), 0);
+ assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Received);
+ });
+
+ let stream = TcpStream::connect(("127.0.0.1", port)).unwrap();
+ let ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ let ssl = Ssl::new(&ctx.build()).unwrap();
+ let mut stream = ssl.connect(stream).unwrap();
+
+ let mut buf = [0; 5];
+ stream.read_exact(&mut buf).unwrap();
+ assert_eq!(b"hello", &buf);
+
+ assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Sent);
+ assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Received);
+}
+
+fn _check_kinds() {
+ fn is_send<T: Send>() {}
+ fn is_sync<T: Sync>() {}
+
+ is_send::<SslStream<TcpStream>>();
+ is_sync::<SslStream<TcpStream>>();
}