tls_api_security_framework_2/
connector.rs1#[cfg(any(target_os = "macos", target_os = "ios"))]
2use security_framework::certificate::SecCertificate;
3#[cfg(any(target_os = "macos", target_os = "ios"))]
4use security_framework::secure_transport::ClientBuilder;
5
6use std::str;
7
8use std::future::Future;
9use tls_api::spi_connector_common;
10use tls_api::AsyncSocket;
11use tls_api::AsyncSocketBox;
12use tls_api::ImplInfo;
13
14#[cfg(not(any(target_os = "macos", target_os = "ios")))]
15type ClientBuilder = void::Void;
16
17pub struct TlsConnector(pub ClientBuilder);
18pub struct TlsConnectorBuilder(pub ClientBuilder);
19
20impl tls_api::TlsConnectorBuilder for TlsConnectorBuilder {
21 type Connector = TlsConnector;
22 type Underlying = ClientBuilder;
23
24 fn underlying_mut(&mut self) -> &mut Self::Underlying {
25 &mut self.0
26 }
27
28 fn set_alpn_protocols(&mut self, protocols: &[&[u8]]) -> anyhow::Result<()> {
29 #[cfg(any(target_os = "macos", target_os = "ios"))]
30 {
31 let protocols: Vec<&str> = protocols
32 .iter()
33 .map(|p| {
34 str::from_utf8(p)
35 .map_err(|e| crate::Error::ReturnedAlpnProtocolIsNotUtf8(e).into())
36 })
37 .collect::<anyhow::Result<_>>()?;
38 self.0.alpn_protocols(&protocols);
39 Ok(())
40 }
41 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
42 {
43 let _ = protocols;
44 crate::not_ios_or_macos()
45 }
46 }
47
48 fn set_verify_hostname(&mut self, verify: bool) -> anyhow::Result<()> {
49 #[cfg(any(target_os = "macos", target_os = "ios"))]
50 {
51 self.0.danger_accept_invalid_hostnames(!verify);
52 Ok(())
53 }
54 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
55 {
56 let _ = verify;
57 crate::not_ios_or_macos()
58 }
59 }
60
61 fn add_root_certificate(&mut self, cert: &[u8]) -> anyhow::Result<()> {
62 #[cfg(any(target_os = "macos", target_os = "ios"))]
63 {
64 let cert = SecCertificate::from_der(cert).map_err(anyhow::Error::new)?;
65 self.0.anchor_certificates(&[cert]);
67 Ok(())
68 }
69 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
70 {
71 let _ = cert;
72 crate::not_ios_or_macos()
73 }
74 }
75
76 fn build(self) -> anyhow::Result<TlsConnector> {
77 Ok(TlsConnector(self.0))
78 }
79}
80
81impl TlsConnector {
82 pub fn connect_impl<'a, S>(
83 &'a self,
84 domain: &'a str,
85 stream: S,
86 ) -> impl Future<Output = anyhow::Result<crate::TlsStream<S>>> + 'a
87 where
88 S: AsyncSocket,
89 {
90 #[cfg(any(target_os = "macos", target_os = "ios"))]
91 {
92 crate::handshake::new_slient_handshake(self, domain, stream)
93 }
94 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
95 {
96 let _ = (domain, stream);
97 async { crate::not_ios_or_macos() }
98 }
99 }
100}
101
102impl tls_api::TlsConnector for TlsConnector {
103 type Builder = TlsConnectorBuilder;
104
105 type Underlying = ClientBuilder;
106 type TlsStream = crate::TlsStream<AsyncSocketBox>;
107
108 fn underlying_mut(&mut self) -> &mut Self::Underlying {
109 &mut self.0
110 }
111
112 const IMPLEMENTED: bool = crate::IMPLEMENTED;
113 const SUPPORTS_ALPN: bool = true;
114
115 fn info() -> ImplInfo {
116 crate::info()
117 }
118
119 fn builder() -> anyhow::Result<TlsConnectorBuilder> {
120 #[cfg(any(target_os = "macos", target_os = "ios"))]
121 {
122 Ok(TlsConnectorBuilder(ClientBuilder::new()))
123 }
124 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
125 {
126 crate::not_ios_or_macos()
127 }
128 }
129
130 spi_connector_common!();
131}