mysql_async/io/tls/
native_tls_io.rs

1#![cfg(feature = "native-tls-tls")]
2
3use native_tls::{Certificate, TlsConnector};
4
5use crate::io::Endpoint;
6use crate::{Result, SslOpts};
7
8impl SslOpts {
9    async fn load_root_certs(&self) -> crate::Result<Vec<Certificate>> {
10        let mut output = Vec::new();
11
12        for root_cert in self.root_certs() {
13            let root_cert_data = root_cert.read().await?;
14            output.extend(parse_certs(root_cert_data.as_ref())?);
15        }
16
17        Ok(output)
18    }
19}
20
21impl Endpoint {
22    pub async fn make_secure(&mut self, domain: String, ssl_opts: SslOpts) -> Result<()> {
23        #[cfg(unix)]
24        if self.is_socket() {
25            // won't secure socket connection
26            return Ok(());
27        }
28
29        let mut builder = TlsConnector::builder();
30        for root_cert in ssl_opts.load_root_certs().await? {
31            builder.add_root_certificate(root_cert);
32        }
33
34        if let Some(client_identity) = ssl_opts.client_identity() {
35            builder.identity(client_identity.load().await?);
36        }
37        builder.danger_accept_invalid_hostnames(ssl_opts.skip_domain_validation());
38        builder.danger_accept_invalid_certs(ssl_opts.accept_invalid_certs());
39        builder.disable_built_in_roots(ssl_opts.disable_built_in_roots());
40        let tls_connector: tokio_native_tls::TlsConnector = builder.build()?.into();
41
42        *self = match self {
43            Endpoint::Plain(ref mut stream) => {
44                let stream = stream.take().unwrap();
45                let tls_stream = tls_connector.connect(&domain, stream).await?;
46                Endpoint::Secure(tls_stream)
47            }
48            Endpoint::Secure(_) => unreachable!(),
49            #[cfg(unix)]
50            Endpoint::Socket(_) => unreachable!(),
51        };
52
53        Ok(())
54    }
55}
56
57fn parse_certs(buf: &[u8]) -> Result<Vec<Certificate>> {
58    Ok(Certificate::from_der(buf).map(|x| vec![x]).or_else(|_| {
59        pem::parse_many(buf)
60            .unwrap_or_default()
61            .iter()
62            .map(pem::encode)
63            .map(|s| Certificate::from_pem(s.as_bytes()))
64            .collect()
65    })?)
66}