use std::sync::Arc; use rustls::ClientHello; use rustls::NoClientAuth; use rustls::ServerConfig; use rustls::ResolvesServerCert; use rustls::sign; use rustls::sign::CertifiedKey; use rustls::internal::pemfile; use actix_web::App; use actix_web::HttpServer; use actix_web::get; use actix_web::Responder; const CERT_CHAIN: &str = include_str!("cert_chain.pem"); const PRIVATE_KEY: &str = include_str!("private_key.pem"); struct ResolvesServerCertImpl; impl ResolvesServerCert for ResolvesServerCertImpl { fn resolve(&self, client_hello: ClientHello) -> Option { println!("Request server name: {:?}", client_hello.server_name()); let mut cert_chain_bytes = CERT_CHAIN.as_bytes(); let mut private_key_bytes = PRIVATE_KEY.as_bytes(); let cert_chain = pemfile::certs(&mut cert_chain_bytes).unwrap(); let mut keys = pemfile::pkcs8_private_keys(&mut private_key_bytes).unwrap(); let signing_key = sign::any_supported_type(&keys.remove(0)).unwrap(); Some(CertifiedKey::new(cert_chain, Arc::new(signing_key))) } } #[get("/")] async fn index() -> impl Responder { format!("Hello world!") } #[actix_web::main] async fn main() -> std::io::Result<()> { let mut config = ServerConfig::new(NoClientAuth::new()); config.cert_resolver = Arc::new(ResolvesServerCertImpl); let listen = "127.0.0.1:8443"; println!("Listen at: {}", listen); HttpServer::new(|| App::new().service(index)) .bind_rustls(listen, config)? .run() .await }