1 use std::{fmt, sync::Arc}; 2 3 use tokio::io::{AsyncRead, AsyncWrite}; 4 use tokio_rustls::{ 5 rustls::{server::WebPkiClientVerifier, RootCertStore, ServerConfig}, 6 server::TlsStream, 7 TlsAcceptor as RustlsAcceptor, 8 }; 9 10 use crate::transport::{ 11 service::tls::{convert_certificate_to_pki_types, convert_identity_to_pki_types, ALPN_H2}, 12 Certificate, Identity, 13 }; 14 15 #[derive(Clone)] 16 pub(crate) struct TlsAcceptor { 17 inner: Arc<ServerConfig>, 18 } 19 20 impl TlsAcceptor { new( identity: &Identity, client_ca_root: Option<&Certificate>, client_auth_optional: bool, ignore_client_order: bool, use_key_log: bool, ) -> Result<Self, crate::BoxError>21 pub(crate) fn new( 22 identity: &Identity, 23 client_ca_root: Option<&Certificate>, 24 client_auth_optional: bool, 25 ignore_client_order: bool, 26 use_key_log: bool, 27 ) -> Result<Self, crate::BoxError> { 28 let builder = ServerConfig::builder(); 29 30 let builder = match client_ca_root { 31 None => builder.with_no_client_auth(), 32 Some(cert) => { 33 let mut roots = RootCertStore::empty(); 34 roots.add_parsable_certificates(convert_certificate_to_pki_types(cert)?); 35 let verifier = if client_auth_optional { 36 WebPkiClientVerifier::builder(roots.into()).allow_unauthenticated() 37 } else { 38 WebPkiClientVerifier::builder(roots.into()) 39 } 40 .build()?; 41 builder.with_client_cert_verifier(verifier) 42 } 43 }; 44 45 let (cert, key) = convert_identity_to_pki_types(identity)?; 46 let mut config = builder.with_single_cert(cert, key)?; 47 config.ignore_client_order = ignore_client_order; 48 49 if use_key_log { 50 config.key_log = Arc::new(tokio_rustls::rustls::KeyLogFile::new()); 51 } 52 53 config.alpn_protocols.push(ALPN_H2.into()); 54 Ok(Self { 55 inner: Arc::new(config), 56 }) 57 } 58 accept<IO>(&self, io: IO) -> Result<TlsStream<IO>, crate::BoxError> where IO: AsyncRead + AsyncWrite + Unpin,59 pub(crate) async fn accept<IO>(&self, io: IO) -> Result<TlsStream<IO>, crate::BoxError> 60 where 61 IO: AsyncRead + AsyncWrite + Unpin, 62 { 63 let acceptor = RustlsAcceptor::from(self.inner.clone()); 64 acceptor.accept(io).await.map_err(Into::into) 65 } 66 } 67 68 impl fmt::Debug for TlsAcceptor { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 70 f.debug_struct("TlsAcceptor").finish() 71 } 72 } 73