tls_api_openssl/
acceptor.rs1use openssl::pkcs12::ParsedPkcs12_2;
2
3use tls_api::async_as_sync::AsyncIoAsSyncIo;
4use tls_api::spi_acceptor_common;
5use tls_api::AsyncSocket;
6use tls_api::AsyncSocketBox;
7use tls_api::ImplInfo;
8
9use crate::encode_alpn_protos;
10use crate::handshake::HandshakeFuture;
11use anyhow::Context;
12use std::future::Future;
13
14pub struct TlsAcceptorBuilder(pub openssl::ssl::SslAcceptorBuilder);
15
16pub struct TlsAcceptor(pub openssl::ssl::SslAcceptor);
17
18fn to_openssl_pkcs12(pkcs12: &[u8], passphrase: &str) -> anyhow::Result<ParsedPkcs12_2> {
19 let pkcs12 = openssl::pkcs12::Pkcs12::from_der(pkcs12)?;
20 pkcs12.parse2(passphrase).context("Parse passphrase")
21}
22
23impl tls_api::TlsAcceptorBuilder for TlsAcceptorBuilder {
24 type Acceptor = TlsAcceptor;
25
26 type Underlying = openssl::ssl::SslAcceptorBuilder;
27
28 fn underlying_mut(&mut self) -> &mut openssl::ssl::SslAcceptorBuilder {
29 &mut self.0
30 }
31
32 fn set_alpn_protocols(&mut self, protocols: &[&[u8]]) -> anyhow::Result<()> {
33 let protocols = encode_alpn_protos(protocols)?;
34 self.0
35 .set_alpn_select_callback(move |_ssl, client_protocols| {
36 match openssl::ssl::select_next_proto(&protocols, client_protocols) {
37 Some(selected) => Ok(selected),
38 None => Err(openssl::ssl::AlpnError::NOACK),
39 }
40 });
41 Ok(())
42 }
43
44 fn build(self) -> anyhow::Result<TlsAcceptor> {
45 Ok(TlsAcceptor(self.0.build()))
46 }
47}
48
49impl TlsAcceptorBuilder {
50 pub fn builder_mut(&mut self) -> &mut openssl::ssl::SslAcceptorBuilder {
51 &mut self.0
52 }
53}
54
55impl TlsAcceptor {
56 fn accept_impl<S>(
57 &self,
58 stream: S,
59 ) -> impl Future<Output = anyhow::Result<crate::TlsStream<S>>> + '_
60 where
61 S: AsyncSocket,
62 {
63 HandshakeFuture::Initial(
64 move |stream| self.0.accept(stream),
65 AsyncIoAsSyncIo::new(stream),
66 )
67 }
68}
69
70impl tls_api::TlsAcceptor for TlsAcceptor {
71 type Builder = TlsAcceptorBuilder;
72
73 type Underlying = openssl::ssl::SslAcceptor;
74 type TlsStream = crate::TlsStream<AsyncSocketBox>;
75
76 fn underlying_mut(&mut self) -> &mut Self::Underlying {
77 &mut self.0
78 }
79
80 const IMPLEMENTED: bool = true;
81 const SUPPORTS_ALPN: bool = true;
82 const SUPPORTS_DER_KEYS: bool = true;
83 const SUPPORTS_PKCS12_KEYS: bool = true;
84
85 fn info() -> ImplInfo {
86 crate::into()
87 }
88
89 fn builder_from_der_key(cert: &[u8], key: &[u8]) -> anyhow::Result<TlsAcceptorBuilder> {
90 let cert = openssl::x509::X509::from_der(cert).map_err(anyhow::Error::new)?;
91 let pkey = openssl::pkey::PKey::private_key_from_der(key).map_err(anyhow::Error::new)?;
92
93 let mut builder =
94 openssl::ssl::SslAcceptor::mozilla_intermediate(openssl::ssl::SslMethod::tls())
95 .map_err(anyhow::Error::new)?;
96
97 builder
98 .set_certificate(cert.as_ref())
99 .map_err(anyhow::Error::new)?;
100 builder
101 .set_private_key(pkey.as_ref())
102 .map_err(anyhow::Error::new)?;
103
104 Ok(TlsAcceptorBuilder(builder))
105 }
106
107 fn builder_from_pkcs12(pkcs12: &[u8], passphrase: &str) -> anyhow::Result<TlsAcceptorBuilder> {
108 let mut builder =
109 openssl::ssl::SslAcceptor::mozilla_intermediate(openssl::ssl::SslMethod::tls())
110 .map_err(anyhow::Error::new)?;
111
112 let pkcs12 = to_openssl_pkcs12(pkcs12, passphrase)?;
113
114 if let Some(cert) = &pkcs12.cert {
115 builder.set_certificate(cert).map_err(anyhow::Error::new)?;
116 }
117 if let Some(pkey) = &pkcs12.pkey {
118 builder.set_private_key(pkey).map_err(anyhow::Error::new)?;
119 }
120
121 if let Some(chain) = pkcs12.ca {
122 for x509 in chain {
123 builder
124 .add_extra_chain_cert(x509)
125 .map_err(anyhow::Error::new)?;
126 }
127 }
128
129 Ok(TlsAcceptorBuilder(builder))
130 }
131
132 spi_acceptor_common!(crate::TlsStream<S>);
133}