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