mirror of
https://github.com/fafhrd91/actix-net
synced 2025-06-26 19:47:43 +02:00
add timeout for accepting tls connections (#393)
Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
130
actix-tls/tests/accept-openssl.rs
Normal file
130
actix-tls/tests/accept-openssl.rs
Normal file
@ -0,0 +1,130 @@
|
||||
//! Use Rustls connector to test OpenSSL acceptor.
|
||||
|
||||
#![cfg(all(
|
||||
feature = "accept",
|
||||
feature = "connect",
|
||||
feature = "rustls",
|
||||
feature = "openssl"
|
||||
))]
|
||||
|
||||
use std::{convert::TryFrom, io::Write, sync::Arc};
|
||||
|
||||
use actix_rt::net::TcpStream;
|
||||
use actix_server::TestServer;
|
||||
use actix_service::ServiceFactoryExt as _;
|
||||
use actix_tls::accept::openssl::{Acceptor, TlsStream};
|
||||
use actix_utils::future::ok;
|
||||
use tokio_rustls::rustls::{Certificate, ClientConfig, RootCertStore, ServerName};
|
||||
|
||||
fn new_cert_and_key() -> (String, String) {
|
||||
let cert = rcgen::generate_simple_self_signed(vec![
|
||||
"127.0.0.1".to_owned(),
|
||||
"localhost".to_owned(),
|
||||
])
|
||||
.unwrap();
|
||||
|
||||
let key = cert.serialize_private_key_pem();
|
||||
let cert = cert.serialize_pem().unwrap();
|
||||
|
||||
(cert, key)
|
||||
}
|
||||
|
||||
fn openssl_acceptor(cert: String, key: String) -> tls_openssl::ssl::SslAcceptor {
|
||||
use tls_openssl::{
|
||||
pkey::PKey,
|
||||
ssl::{SslAcceptor, SslMethod},
|
||||
x509::X509,
|
||||
};
|
||||
|
||||
let cert = X509::from_pem(cert.as_bytes()).unwrap();
|
||||
let key = PKey::private_key_from_pem(key.as_bytes()).unwrap();
|
||||
|
||||
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
|
||||
builder.set_certificate(&cert).unwrap();
|
||||
builder.set_private_key(&key).unwrap();
|
||||
builder.set_alpn_select_callback(|_, _protocols| Ok(b"http/1.1"));
|
||||
builder.set_alpn_protos(b"\x08http/1.1").unwrap();
|
||||
builder.build()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod danger {
|
||||
use std::time::SystemTime;
|
||||
|
||||
use super::*;
|
||||
|
||||
use tokio_rustls::rustls::{
|
||||
self,
|
||||
client::{ServerCertVerified, ServerCertVerifier},
|
||||
};
|
||||
|
||||
pub struct NoCertificateVerification;
|
||||
|
||||
impl ServerCertVerifier for NoCertificateVerification {
|
||||
fn verify_server_cert(
|
||||
&self,
|
||||
_end_entity: &Certificate,
|
||||
_intermediates: &[Certificate],
|
||||
_server_name: &ServerName,
|
||||
_scts: &mut dyn Iterator<Item = &[u8]>,
|
||||
_ocsp_response: &[u8],
|
||||
_now: SystemTime,
|
||||
) -> Result<ServerCertVerified, rustls::Error> {
|
||||
Ok(ServerCertVerified::assertion())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn rustls_connector(_cert: String, _key: String) -> ClientConfig {
|
||||
let mut config = ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates(RootCertStore::empty())
|
||||
.with_no_client_auth();
|
||||
|
||||
config
|
||||
.dangerous()
|
||||
.set_certificate_verifier(Arc::new(danger::NoCertificateVerification));
|
||||
|
||||
config.alpn_protocols = vec![b"http/1.1".to_vec()];
|
||||
config
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn accepts_connections() {
|
||||
let (cert, key) = new_cert_and_key();
|
||||
|
||||
let srv = TestServer::with({
|
||||
let cert = cert.clone();
|
||||
let key = key.clone();
|
||||
|
||||
move || {
|
||||
let openssl_acceptor = openssl_acceptor(cert.clone(), key.clone());
|
||||
let tls_acceptor = Acceptor::new(openssl_acceptor);
|
||||
|
||||
tls_acceptor
|
||||
.map_err(|err| println!("OpenSSL error: {:?}", err))
|
||||
.and_then(move |_stream: TlsStream<TcpStream>| ok(()))
|
||||
}
|
||||
});
|
||||
|
||||
let mut sock = srv
|
||||
.connect()
|
||||
.expect("cannot connect to test server")
|
||||
.into_std()
|
||||
.unwrap();
|
||||
sock.set_nonblocking(false).unwrap();
|
||||
|
||||
let config = rustls_connector(cert, key);
|
||||
let config = Arc::new(config);
|
||||
|
||||
let mut conn = tokio_rustls::rustls::ClientConnection::new(
|
||||
config,
|
||||
ServerName::try_from("localhost").unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut stream = tokio_rustls::rustls::Stream::new(&mut conn, &mut sock);
|
||||
|
||||
stream.flush().expect("TLS handshake failed");
|
||||
}
|
104
actix-tls/tests/accept-rustls.rs
Normal file
104
actix-tls/tests/accept-rustls.rs
Normal file
@ -0,0 +1,104 @@
|
||||
//! Use OpenSSL connector to test Rustls acceptor.
|
||||
|
||||
#![cfg(all(
|
||||
feature = "accept",
|
||||
feature = "connect",
|
||||
feature = "rustls",
|
||||
feature = "openssl"
|
||||
))]
|
||||
|
||||
use std::io::{BufReader, Write};
|
||||
|
||||
use actix_rt::net::TcpStream;
|
||||
use actix_server::TestServer;
|
||||
use actix_service::ServiceFactoryExt as _;
|
||||
use actix_tls::accept::rustls::{Acceptor, TlsStream};
|
||||
use actix_tls::connect::tls::openssl::SslConnector;
|
||||
use actix_utils::future::ok;
|
||||
use rustls_pemfile::{certs, pkcs8_private_keys};
|
||||
use tls_openssl::ssl::SslVerifyMode;
|
||||
use tokio_rustls::rustls::{self, Certificate, PrivateKey, ServerConfig};
|
||||
|
||||
fn new_cert_and_key() -> (String, String) {
|
||||
let cert = rcgen::generate_simple_self_signed(vec![
|
||||
"127.0.0.1".to_owned(),
|
||||
"localhost".to_owned(),
|
||||
])
|
||||
.unwrap();
|
||||
|
||||
let key = cert.serialize_private_key_pem();
|
||||
let cert = cert.serialize_pem().unwrap();
|
||||
|
||||
(cert, key)
|
||||
}
|
||||
|
||||
fn rustls_server_config(cert: String, key: String) -> rustls::ServerConfig {
|
||||
// Load TLS key and cert files
|
||||
|
||||
let cert = &mut BufReader::new(cert.as_bytes());
|
||||
let key = &mut BufReader::new(key.as_bytes());
|
||||
|
||||
let cert_chain = certs(cert).unwrap().into_iter().map(Certificate).collect();
|
||||
let mut keys = pkcs8_private_keys(key).unwrap();
|
||||
|
||||
let mut config = ServerConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_no_client_auth()
|
||||
.with_single_cert(cert_chain, PrivateKey(keys.remove(0)))
|
||||
.unwrap();
|
||||
|
||||
config.alpn_protocols = vec![b"http/1.1".to_vec()];
|
||||
|
||||
config
|
||||
}
|
||||
|
||||
fn openssl_connector(cert: String, key: String) -> SslConnector {
|
||||
use actix_tls::connect::tls::openssl::{SslConnector as OpensslConnector, SslMethod};
|
||||
use tls_openssl::{pkey::PKey, x509::X509};
|
||||
|
||||
let cert = X509::from_pem(cert.as_bytes()).unwrap();
|
||||
let key = PKey::private_key_from_pem(key.as_bytes()).unwrap();
|
||||
|
||||
let mut ssl = OpensslConnector::builder(SslMethod::tls()).unwrap();
|
||||
ssl.set_verify(SslVerifyMode::NONE);
|
||||
ssl.set_certificate(&cert).unwrap();
|
||||
ssl.set_private_key(&key).unwrap();
|
||||
ssl.set_alpn_protos(b"\x08http/1.1").unwrap();
|
||||
|
||||
ssl.build()
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn accepts_connections() {
|
||||
let (cert, key) = new_cert_and_key();
|
||||
|
||||
let srv = TestServer::with({
|
||||
let cert = cert.clone();
|
||||
let key = key.clone();
|
||||
|
||||
move || {
|
||||
let tls_acceptor = Acceptor::new(rustls_server_config(cert.clone(), key.clone()));
|
||||
|
||||
tls_acceptor
|
||||
.map_err(|err| println!("Rustls error: {:?}", err))
|
||||
.and_then(move |_stream: TlsStream<TcpStream>| ok(()))
|
||||
}
|
||||
});
|
||||
|
||||
let sock = srv
|
||||
.connect()
|
||||
.expect("cannot connect to test server")
|
||||
.into_std()
|
||||
.unwrap();
|
||||
sock.set_nonblocking(false).unwrap();
|
||||
|
||||
let connector = openssl_connector(cert, key);
|
||||
|
||||
let mut stream = connector
|
||||
.connect("localhost", sock)
|
||||
.expect("TLS handshake failed");
|
||||
|
||||
stream.do_handshake().expect("TLS handshake failed");
|
||||
|
||||
stream.flush().expect("TLS handshake failed");
|
||||
}
|
Reference in New Issue
Block a user