tls_api_native_tls/
connector.rs1use std::str;
2
3use crate::handshake::HandshakeFuture;
4
5use std::future::Future;
6use tls_api::async_as_sync::AsyncIoAsSyncIo;
7use tls_api::spi_connector_common;
8use tls_api::AsyncSocket;
9use tls_api::AsyncSocketBox;
10use tls_api::ImplInfo;
11
12pub struct TlsConnectorBuilder {
13 pub builder: native_tls::TlsConnectorBuilder,
14 pub verify_hostname: bool,
15}
16
17pub struct TlsConnector {
18 pub connector: native_tls::TlsConnector,
19 pub verify_hostname: bool,
20}
21
22impl tls_api::TlsConnectorBuilder for TlsConnectorBuilder {
23 type Connector = TlsConnector;
24
25 type Underlying = native_tls::TlsConnectorBuilder;
26
27 fn underlying_mut(&mut self) -> &mut native_tls::TlsConnectorBuilder {
28 &mut self.builder
29 }
30
31 fn set_alpn_protocols(&mut self, protocols: &[&[u8]]) -> anyhow::Result<()> {
32 let protocols: Vec<&str> = protocols
33 .iter()
34 .map(|p| str::from_utf8(p).map_err(|e| crate::Error::AlpnProtocolNotUtf8(e).into()))
35 .collect::<anyhow::Result<_>>()?;
36 self.builder.request_alpns(&protocols);
37 Ok(())
38 }
39
40 fn set_verify_hostname(&mut self, verify: bool) -> anyhow::Result<()> {
41 self.builder.danger_accept_invalid_hostnames(!verify);
42 self.verify_hostname = verify;
43 Ok(())
44 }
45
46 fn add_root_certificate(&mut self, cert: &[u8]) -> anyhow::Result<()> {
47 let cert = native_tls::Certificate::from_der(cert).map_err(anyhow::Error::new)?;
48
49 self.builder.add_root_certificate(cert);
50
51 Ok(())
52 }
53
54 fn build(self) -> anyhow::Result<TlsConnector> {
55 let connector = self.builder.build().map_err(anyhow::Error::new)?;
56 Ok(TlsConnector {
57 connector,
58 verify_hostname: self.verify_hostname,
59 })
60 }
61}
62
63impl TlsConnector {
64 pub fn connect_impl<'a, S>(
65 &'a self,
66 domain: &'a str,
67 stream: S,
68 ) -> impl Future<Output = anyhow::Result<crate::TlsStream<S>>> + 'a
69 where
70 S: AsyncSocket,
71 {
72 HandshakeFuture::Initial(
73 move |s| self.connector.connect(domain, s),
74 AsyncIoAsSyncIo::new(stream),
75 )
76 }
77}
78
79impl tls_api::TlsConnector for TlsConnector {
80 type Builder = TlsConnectorBuilder;
81
82 type Underlying = native_tls::TlsConnector;
83 type TlsStream = crate::TlsStream<AsyncSocketBox>;
84
85 fn underlying_mut(&mut self) -> &mut Self::Underlying {
86 &mut self.connector
87 }
88
89 const IMPLEMENTED: bool = true;
90 const SUPPORTS_ALPN: bool = true;
91
92 fn info() -> ImplInfo {
93 crate::info()
94 }
95
96 fn builder() -> anyhow::Result<TlsConnectorBuilder> {
97 let builder = native_tls::TlsConnector::builder();
98 Ok(TlsConnectorBuilder {
99 builder,
100 verify_hostname: true,
101 })
102 }
103
104 spi_connector_common!(crate::TlsStream<S>);
105}