Files
core/test/rust/runtime/http/tls.rs
T
2026-11-03 03:32:07 +00:00

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")
);
}