Skip to main content

wasmtime_wasi_tls/providers/
openssl.rs

1//! The `openssl` provider.
2
3use crate::{BoxFutureTlsStream, Error, TlsProvider, TlsStream, TlsTransport};
4use openssl::ssl::{SslConnector, SslMethod};
5use std::io;
6use std::pin::{Pin, pin};
7
8/// The `openssl` provider.
9pub struct OpenSslProvider {
10    _priv: (),
11}
12
13impl TlsProvider for OpenSslProvider {
14    fn connect(&self, server_name: String, transport: Box<dyn TlsTransport>) -> BoxFutureTlsStream {
15        Box::pin(async move {
16            // Per the `openssl` crate's recommendation, we're using the
17            // `SslConnector` to set up a Ssl object with secure defaults:
18            //
19            // https://docs.rs/openssl/latest/openssl/ssl/struct.SslConnector.html
20            // > OpenSSL's default configuration is highly insecure. This
21            // > connector manages the OpenSSL structures, configuring cipher
22            // > suites, session options, hostname verification, and more.
23            let config = SslConnector::builder(SslMethod::tls_client())?
24                .build()
25                .configure()?;
26            let ssl = config.into_ssl(&server_name)?;
27            let mut stream = tokio_openssl::SslStream::new(ssl, transport)?;
28            Pin::new(&mut stream).connect().await?;
29            Ok(Box::new(OpenSslStream(stream)) as Box<dyn TlsStream>)
30        })
31    }
32}
33
34impl Default for OpenSslProvider {
35    fn default() -> Self {
36        Self { _priv: () }
37    }
38}
39
40struct OpenSslStream(tokio_openssl::SslStream<Box<dyn TlsTransport>>);
41
42impl TlsStream for OpenSslStream {}
43
44impl tokio::io::AsyncRead for OpenSslStream {
45    fn poll_read(
46        mut self: std::pin::Pin<&mut Self>,
47        cx: &mut std::task::Context<'_>,
48        buf: &mut tokio::io::ReadBuf<'_>,
49    ) -> std::task::Poll<io::Result<()>> {
50        pin!(&mut self.as_mut().0).poll_read(cx, buf)
51    }
52}
53
54impl tokio::io::AsyncWrite for OpenSslStream {
55    fn poll_write(
56        mut self: std::pin::Pin<&mut Self>,
57        cx: &mut std::task::Context<'_>,
58        buf: &[u8],
59    ) -> std::task::Poll<io::Result<usize>> {
60        pin!(&mut self.as_mut().0).poll_write(cx, buf)
61    }
62
63    fn poll_flush(
64        mut self: std::pin::Pin<&mut Self>,
65        cx: &mut std::task::Context<'_>,
66    ) -> std::task::Poll<Result<(), io::Error>> {
67        pin!(&mut self.as_mut().0).poll_flush(cx)
68    }
69
70    fn poll_shutdown(
71        mut self: std::pin::Pin<&mut Self>,
72        cx: &mut std::task::Context<'_>,
73    ) -> std::task::Poll<Result<(), io::Error>> {
74        pin!(&mut self.as_mut().0).poll_shutdown(cx)
75    }
76}
77
78impl From<openssl::ssl::Error> for Error {
79    fn from(e: openssl::ssl::Error) -> Self {
80        Error::msg(e.to_string())
81    }
82}
83impl From<openssl::error::ErrorStack> for Error {
84    fn from(e: openssl::error::ErrorStack) -> Self {
85        openssl::ssl::Error::from(e).into()
86    }
87}