tor_rtcompat/impls/
native_tls.rs
1use crate::traits::{CertifiedConn, StreamOps, TlsConnector, TlsProvider};
4
5use async_trait::async_trait;
6use futures::{AsyncRead, AsyncWrite};
7use native_tls_crate as native_tls;
8use std::io::{Error as IoError, Result as IoResult};
9
10#[cfg_attr(
14 docsrs,
15 doc(cfg(all(feature = "native-tls", any(feature = "tokio", feature = "async-std"))))
16)]
17#[derive(Default, Clone)]
18#[non_exhaustive]
19pub struct NativeTlsProvider {}
20
21impl<S> CertifiedConn for async_native_tls::TlsStream<S>
22where
23 S: AsyncRead + AsyncWrite + Unpin,
24{
25 fn peer_certificate(&self) -> IoResult<Option<Vec<u8>>> {
26 let cert = self.peer_certificate();
27 match cert {
28 Ok(Some(c)) => {
29 let der = c.to_der().map_err(IoError::other)?;
30 Ok(Some(der))
31 }
32 Ok(None) => Ok(None),
33 Err(e) => Err(IoError::other(e)),
34 }
35 }
36
37 fn export_keying_material(
38 &self,
39 _len: usize,
40 _label: &[u8],
41 _context: Option<&[u8]>,
42 ) -> IoResult<Vec<u8>> {
43 Err(std::io::Error::new(
44 std::io::ErrorKind::Unsupported,
45 tor_error::bad_api_usage!("native-tls does not support exporting keying material"),
46 ))
47 }
48}
49
50impl<S: AsyncRead + AsyncWrite + StreamOps + Unpin> StreamOps for async_native_tls::TlsStream<S> {
51 fn set_tcp_notsent_lowat(&self, notsent_lowat: u32) -> IoResult<()> {
52 self.get_ref().set_tcp_notsent_lowat(notsent_lowat)
53 }
54
55 fn new_handle(&self) -> Box<dyn StreamOps + Send + Unpin> {
56 self.get_ref().new_handle()
57 }
58}
59
60pub struct NativeTlsConnector<S> {
62 connector: async_native_tls::TlsConnector,
64 _phantom: std::marker::PhantomData<fn(S) -> S>,
66}
67
68#[async_trait]
69impl<S> TlsConnector<S> for NativeTlsConnector<S>
70where
71 S: AsyncRead + AsyncWrite + StreamOps + Unpin + Send + 'static,
72{
73 type Conn = async_native_tls::TlsStream<S>;
74
75 async fn negotiate_unvalidated(&self, stream: S, sni_hostname: &str) -> IoResult<Self::Conn> {
76 let conn = self
77 .connector
78 .connect(sni_hostname, stream)
79 .await
80 .map_err(IoError::other)?;
81 Ok(conn)
82 }
83}
84
85impl<S> TlsProvider<S> for NativeTlsProvider
86where
87 S: AsyncRead + AsyncWrite + StreamOps + Unpin + Send + 'static,
88{
89 type Connector = NativeTlsConnector<S>;
90
91 type TlsStream = async_native_tls::TlsStream<S>;
92
93 fn tls_connector(&self) -> Self::Connector {
94 let mut builder = native_tls::TlsConnector::builder();
95 builder
100 .danger_accept_invalid_certs(true)
101 .danger_accept_invalid_hostnames(true);
102
103 builder.disable_built_in_roots(true);
106
107 let connector = builder.into();
108
109 NativeTlsConnector {
110 connector,
111 _phantom: std::marker::PhantomData,
112 }
113 }
114
115 fn supports_keying_material_export(&self) -> bool {
116 false
117 }
118}