105 lines
4.6 KiB
Rust
105 lines
4.6 KiB
Rust
use super::*;
|
|
use http_body_util::{BodyExt, Full};
|
|
use hyper_util::rt::{TokioExecutor, TokioIo};
|
|
|
|
pub(super) const ROOT: &[u8] = include_bytes!("../../../dever-tests/fixtures/tls/root.pem");
|
|
pub(super) const CERTIFICATE: &[u8] =
|
|
include_bytes!("../../../dever-tests/fixtures/tls/server.pem");
|
|
pub(super) const KEY: &[u8] = include_bytes!("../../../dever-tests/fixtures/tls/server-key.pem");
|
|
|
|
#[test]
|
|
fn tls_verifies_ca_hostname_alpn_and_keeps_bad_handshakes_isolated() {
|
|
runtime()
|
|
.run(async |scope| {
|
|
for http2 in [false, true] {
|
|
let listener = net::listen("127.0.0.1", 0, scope).await.unwrap();
|
|
let port = listener.port().unwrap();
|
|
let incoming = listener.clone();
|
|
let server = scope
|
|
.spawn(move |child| async move {
|
|
let tls = dever_runtime::tls::server(CERTIFICATE, KEY).unwrap();
|
|
let limits = Limits {
|
|
http2: http2.then(http::Http2Limits::default),
|
|
timeout_ms: 1000,
|
|
..Limits::default()
|
|
};
|
|
http::serve_tls::<_, _, false>(&incoming, &limits, &child, &tls, route)
|
|
.await
|
|
})
|
|
.unwrap();
|
|
let custom = dever_runtime::tls::client(ROOT).unwrap();
|
|
for (tls, host, protocol) in [
|
|
(dever_runtime::tls::system(), "localhost", http2),
|
|
(custom.clone(), "wrong.test", http2),
|
|
(custom.clone(), "localhost", !http2),
|
|
] {
|
|
let stream = tokio::net::TcpStream::connect(("127.0.0.1", port as u16))
|
|
.await
|
|
.unwrap();
|
|
assert!(tls.connect(host, stream, protocol).await.is_err());
|
|
}
|
|
let stream = tokio::net::TcpStream::connect(("127.0.0.1", port as u16))
|
|
.await
|
|
.unwrap();
|
|
let stream = custom.connect("localhost", stream, http2).await.unwrap();
|
|
let message = hyper::Request::builder()
|
|
.method("POST")
|
|
.uri(if http2 {
|
|
"https://localhost/echo"
|
|
} else {
|
|
"/echo"
|
|
})
|
|
.header("Host", "localhost")
|
|
.body(Full::new(bytes::Bytes::from_static(b"verified TLS")))
|
|
.unwrap();
|
|
let response = if http2 {
|
|
let (mut sender, connection) =
|
|
hyper::client::conn::http2::Builder::new(TokioExecutor::new())
|
|
.handshake(TokioIo::new(stream))
|
|
.await
|
|
.unwrap();
|
|
let driver = scope.spawn_leaf(move || connection).unwrap();
|
|
let response = sender.send_request(message).await.unwrap();
|
|
let body = response.into_body().collect().await.unwrap().to_bytes();
|
|
drop(sender);
|
|
driver.stop().await.unwrap();
|
|
body
|
|
} else {
|
|
let (mut sender, connection) =
|
|
hyper::client::conn::http1::handshake(TokioIo::new(stream))
|
|
.await
|
|
.unwrap();
|
|
let driver = scope.spawn_leaf(move || connection).unwrap();
|
|
let response = sender.send_request(message).await.unwrap();
|
|
let body = response.into_body().collect().await.unwrap().to_bytes();
|
|
drop(sender);
|
|
driver.stop().await.unwrap();
|
|
body
|
|
};
|
|
assert_eq!(response, b"verified TLS"[..]);
|
|
listener.close().unwrap();
|
|
server.wait().await.unwrap().unwrap();
|
|
}
|
|
})
|
|
.unwrap();
|
|
}
|
|
|
|
#[test]
|
|
fn tls_configuration_rejects_invalid_inputs_without_exposing_them() {
|
|
assert!(
|
|
dever_runtime::tls::client(b"private-input")
|
|
.unwrap_err()
|
|
.contains("empty")
|
|
);
|
|
let error = dever_runtime::tls::server(CERTIFICATE, b"private-key-input").unwrap_err();
|
|
assert!(!error.contains("private-key-input"));
|
|
assert!(dever_runtime::tls::server(ROOT, KEY).is_err());
|
|
let mut keys = KEY.to_vec();
|
|
keys.extend_from_slice(KEY);
|
|
assert!(
|
|
dever_runtime::tls::server(CERTIFICATE, &keys)
|
|
.unwrap_err()
|
|
.contains("one private key")
|
|
);
|
|
}
|