Skip to content

Commit 2f23518

Browse files
committed
Split off native-tls implementation into separate crate
1 parent 240f561 commit 2f23518

15 files changed

Lines changed: 225 additions & 165 deletions

File tree

.github/workflows/main.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -393,11 +393,6 @@ jobs:
393393
-p wasmtime-c-api --no-default-features
394394
-p wasmtime-c-api --no-default-features --features wat
395395
-p wasmtime-c-api --no-default-features --features wasi
396-
397-
- name: wasmtime-wasi-tls
398-
checks: |
399-
-p wasmtime-wasi-tls --no-default-features --features rustls
400-
-p wasmtime-wasi-tls --no-default-features --features nativetls
401396
runs-on: ubuntu-latest
402397
steps:
403398
- uses: actions/checkout@v4

Cargo.lock

Lines changed: 16 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ wasmtime-wasi = { workspace = true, default-features = true, optional = true }
5555
wasmtime-wasi-nn = { workspace = true, optional = true }
5656
wasmtime-wasi-config = { workspace = true, optional = true }
5757
wasmtime-wasi-tls = { workspace = true, optional = true }
58+
wasmtime-wasi-tls-nativetls = { workspace = true, optional = true }
5859
wasmtime-wasi-keyvalue = { workspace = true, optional = true }
5960
wasmtime-wasi-threads = { workspace = true, optional = true }
6061
wasmtime-wasi-http = { workspace = true, optional = true }
@@ -234,7 +235,8 @@ wasmtime-wasi-nn = { path = "crates/wasi-nn", version = "35.0.0" }
234235
wasmtime-wasi-config = { path = "crates/wasi-config", version = "35.0.0" }
235236
wasmtime-wasi-keyvalue = { path = "crates/wasi-keyvalue", version = "35.0.0" }
236237
wasmtime-wasi-threads = { path = "crates/wasi-threads", version = "35.0.0" }
237-
wasmtime-wasi-tls = { path = "crates/wasi-tls", version = "35.0.0", default-features = false }
238+
wasmtime-wasi-tls = { path = "crates/wasi-tls", version = "35.0.0" }
239+
wasmtime-wasi-tls-nativetls = { path = "crates/wasi-tls-nativetls", version = "35.0.0" }
238240
wasmtime-wast = { path = "crates/wast", version = "=35.0.0" }
239241

240242
# Internal Wasmtime-specific crates.
@@ -439,7 +441,6 @@ default = [
439441
"wasi-config",
440442
"wasi-keyvalue",
441443
"wasi-tls",
442-
"wasi-tls-rustls",
443444

444445
# Most features of Wasmtime are enabled by default.
445446
"wat",
@@ -480,7 +481,6 @@ trace-log = ["wasmtime/trace-log"]
480481
memory-protection-keys = ["wasmtime-cli-flags/memory-protection-keys"]
481482
profile-pulley = ["wasmtime/profile-pulley"]
482483
component-model-async = ["wasmtime-cli-flags/component-model-async", "component-model"]
483-
wasi-tls-nativetls = ["wasi-tls", "wasmtime-wasi-tls/nativetls"]
484484

485485
# This feature, when enabled, will statically compile out all logging statements
486486
# throughout Wasmtime and its dependencies.
@@ -493,7 +493,6 @@ disable-logging = ["log/max_level_off", "tracing/max_level_off"]
493493
# the internal mapping for what they enable in Wasmtime itself.
494494
wasi-nn = ["dep:wasmtime-wasi-nn"]
495495
wasi-tls = ["dep:wasmtime-wasi-tls"]
496-
wasi-tls-rustls = ["wasi-tls", "wasmtime-wasi-tls/rustls"]
497496
wasi-threads = ["dep:wasmtime-wasi-threads", "threads"]
498497
wasi-http = ["component-model", "dep:wasmtime-wasi-http", "dep:tokio", "dep:hyper"]
499498
wasi-config = ["dep:wasmtime-wasi-config"]

crates/cli-flags/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,6 @@ wasmtime_option_group! {
438438
pub tcplisten: Vec<String>,
439439
/// Enable support for WASI TLS (Transport Layer Security) imports (experimental)
440440
pub tls: Option<bool>,
441-
/// Which TLS provider to use for the wasi-tls interface. Either `rustls` or `nativetls`.
442-
pub tls_provider: Option<String>,
443441
/// Implement WASI Preview1 using new Preview2 implementation (true, default) or legacy
444442
/// implementation (false)
445443
pub preview2: Option<bool>,
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[package]
2+
name = "wasmtime-wasi-tls-nativetls"
3+
version.workspace = true
4+
authors.workspace = true
5+
edition.workspace = true
6+
rust-version.workspace = true
7+
repository = "https://github.com/bytecodealliance/wasmtime"
8+
license = "Apache-2.0 WITH LLVM-exception"
9+
description = "Wasmtime implementation of the wasi-tls API, using native-tls for TLS support."
10+
11+
[lints]
12+
workspace = true
13+
14+
[dependencies]
15+
wasmtime-wasi-tls = { workspace = true }
16+
tokio = { workspace = true }
17+
tokio-native-tls = { workspace = true }
18+
native-tls = { workspace = true }
19+
20+
[dev-dependencies]
21+
anyhow = { workspace = true }
22+
test-programs-artifacts = { workspace = true }
23+
wasmtime = { workspace = true, features = ["runtime", "component-model"] }
24+
wasmtime-wasi = { workspace = true }
25+
tokio = { workspace = true, features = ["macros"] }
26+
futures = { workspace = true }
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//! The `native_tls` provider.
2+
3+
use std::{io, pin::pin};
4+
5+
use wasmtime_wasi_tls::{TlsProvider, TlsStream, TlsTransport};
6+
7+
type BoxFuture<T> = std::pin::Pin<Box<dyn Future<Output = T> + Send>>;
8+
9+
/// The `native_tls` provider.
10+
pub struct NativeTlsProvider {
11+
_priv: (),
12+
}
13+
14+
impl TlsProvider for NativeTlsProvider {
15+
fn connect(
16+
&self,
17+
server_name: String,
18+
transport: Box<dyn TlsTransport>,
19+
) -> BoxFuture<io::Result<Box<dyn TlsStream>>> {
20+
async fn connect_impl(
21+
server_name: String,
22+
transport: Box<dyn TlsTransport>,
23+
) -> Result<NativeTlsStream, native_tls::Error> {
24+
let connector = native_tls::TlsConnector::new()?;
25+
let stream = tokio_native_tls::TlsConnector::from(connector)
26+
.connect(&server_name, transport)
27+
.await?;
28+
Ok(NativeTlsStream(stream))
29+
}
30+
31+
Box::pin(async move {
32+
let stream = connect_impl(server_name, transport)
33+
.await
34+
.map_err(|e| io::Error::other(e))?;
35+
Ok(Box::new(stream) as Box<dyn TlsStream>)
36+
})
37+
}
38+
}
39+
40+
impl Default for NativeTlsProvider {
41+
fn default() -> Self {
42+
Self { _priv: () }
43+
}
44+
}
45+
46+
struct NativeTlsStream(tokio_native_tls::TlsStream<Box<dyn TlsTransport>>);
47+
48+
impl TlsStream for NativeTlsStream {}
49+
50+
impl tokio::io::AsyncRead for NativeTlsStream {
51+
fn poll_read(
52+
mut self: std::pin::Pin<&mut Self>,
53+
cx: &mut std::task::Context<'_>,
54+
buf: &mut tokio::io::ReadBuf<'_>,
55+
) -> std::task::Poll<io::Result<()>> {
56+
pin!(&mut self.as_mut().0).poll_read(cx, buf)
57+
}
58+
}
59+
60+
impl tokio::io::AsyncWrite for NativeTlsStream {
61+
fn poll_write(
62+
mut self: std::pin::Pin<&mut Self>,
63+
cx: &mut std::task::Context<'_>,
64+
buf: &[u8],
65+
) -> std::task::Poll<io::Result<usize>> {
66+
pin!(&mut self.as_mut().0).poll_write(cx, buf)
67+
}
68+
69+
fn poll_flush(
70+
mut self: std::pin::Pin<&mut Self>,
71+
cx: &mut std::task::Context<'_>,
72+
) -> std::task::Poll<Result<(), io::Error>> {
73+
pin!(&mut self.as_mut().0).poll_flush(cx)
74+
}
75+
76+
fn poll_shutdown(
77+
mut self: std::pin::Pin<&mut Self>,
78+
cx: &mut std::task::Context<'_>,
79+
) -> std::task::Poll<Result<(), io::Error>> {
80+
pin!(&mut self.as_mut().0).poll_shutdown(cx)
81+
}
82+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use anyhow::{Result, anyhow};
2+
use wasmtime::{
3+
Store,
4+
component::{Component, Linker, ResourceTable},
5+
};
6+
use wasmtime_wasi::p2::{IoView, WasiCtx, WasiCtxBuilder, WasiView, bindings::Command};
7+
use wasmtime_wasi_tls::{LinkOptions, WasiTls, WasiTlsCtx, WasiTlsCtxBuilder};
8+
9+
struct Ctx {
10+
table: ResourceTable,
11+
wasi_ctx: WasiCtx,
12+
wasi_tls_ctx: WasiTlsCtx,
13+
}
14+
15+
impl IoView for Ctx {
16+
fn table(&mut self) -> &mut ResourceTable {
17+
&mut self.table
18+
}
19+
}
20+
impl WasiView for Ctx {
21+
fn ctx(&mut self) -> &mut WasiCtx {
22+
&mut self.wasi_ctx
23+
}
24+
}
25+
26+
async fn run_test(path: &str) -> Result<()> {
27+
let provider = Box::new(wasmtime_wasi_tls_nativetls::NativeTlsProvider::default());
28+
let ctx = Ctx {
29+
table: ResourceTable::new(),
30+
wasi_ctx: WasiCtxBuilder::new()
31+
.inherit_stderr()
32+
.inherit_network()
33+
.allow_ip_name_lookup(true)
34+
.build(),
35+
wasi_tls_ctx: WasiTlsCtxBuilder::new().provider(provider).build(),
36+
};
37+
38+
let engine = test_programs_artifacts::engine(|config| {
39+
config.async_support(true);
40+
});
41+
let mut store = Store::new(&engine, ctx);
42+
let component = Component::from_file(&engine, path)?;
43+
44+
let mut linker = Linker::new(&engine);
45+
wasmtime_wasi::p2::add_to_linker_async(&mut linker)?;
46+
let mut opts = LinkOptions::default();
47+
opts.tls(true);
48+
wasmtime_wasi_tls::add_to_linker(&mut linker, &mut opts, |h: &mut Ctx| {
49+
WasiTls::new(&h.wasi_tls_ctx, &mut h.table)
50+
})?;
51+
52+
let command = Command::instantiate_async(&mut store, &component, &linker).await?;
53+
command
54+
.wasi_cli_run()
55+
.call_run(&mut store)
56+
.await?
57+
.map_err(|()| anyhow!("command returned with failing exit status"))
58+
}
59+
60+
macro_rules! assert_test_exists {
61+
($name:ident) => {
62+
#[expect(unused_imports, reason = "just here to assert it exists")]
63+
use self::$name as _;
64+
};
65+
}
66+
67+
test_programs_artifacts::foreach_tls!(assert_test_exists);
68+
69+
#[tokio::test(flavor = "multi_thread")]
70+
async fn tls_sample_application() -> Result<()> {
71+
run_test(test_programs_artifacts::TLS_SAMPLE_APPLICATION_COMPONENT).await
72+
}

crates/wasi-tls/Cargo.toml

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ description = "Wasmtime implementation of the wasi-tls API"
1111
[lints]
1212
workspace = true
1313

14-
[features]
15-
default = ["rustls"]
16-
rustls = ["dep:rustls", "dep:tokio-rustls", "dep:webpki-roots"]
17-
nativetls = ["dep:native-tls", "dep:tokio-native-tls"]
18-
1914
[dependencies]
2015
anyhow = { workspace = true }
2116
bytes = { workspace = true }
@@ -27,13 +22,10 @@ tokio = { workspace = true, features = [
2722
] }
2823
wasmtime = { workspace = true, features = ["runtime", "component-model"] }
2924
wasmtime-wasi = { workspace = true }
30-
cfg-if = { workspace = true }
3125

32-
tokio-rustls = { workspace = true, optional = true }
33-
rustls = { workspace = true, optional = true }
34-
webpki-roots = { workspace = true, optional = true }
35-
tokio-native-tls = { workspace = true, optional = true }
36-
native-tls = { workspace = true, optional = true }
26+
tokio-rustls = { workspace = true }
27+
rustls = { workspace = true }
28+
webpki-roots = { workspace = true }
3729

3830
[dev-dependencies]
3931
test-programs-artifacts = { workspace = true }

crates/wasi-tls/src/lib.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@
4343
//! .allow_ip_name_lookup(true)
4444
//! .build(),
4545
//! wasi_tls_ctx: WasiTlsCtxBuilder::new()
46-
//! // Optionally, configure a specific TLS provider:
47-
//! // .provider(Box::new(wasmtime_wasi_tls::RustlsProvider::default()))
48-
//! // .provider(Box::new(wasmtime_wasi_tls::NativeTlsProvider::default()))
46+
//! // Optionally, configure a different TLS provider:
47+
//! // .provider(Box::new(wasmtime_wasi_tls_nativetls::NativeTlsProvider::default()))
4948
//! .build(),
5049
//! };
5150
//!
@@ -83,11 +82,11 @@ use wasmtime::component::{HasData, ResourceTable};
8382
pub mod bindings;
8483
mod host;
8584
mod io;
86-
mod providers;
85+
mod rustls;
8786

8887
pub use bindings::types::LinkOptions;
8988
pub use host::{HostClientConnection, HostClientHandshake, HostFutureClientStreams};
90-
pub use providers::*;
89+
pub use rustls::RustlsProvider;
9190

9291
/// Capture the state necessary for use in the `wasi-tls` API implementation.
9392
pub struct WasiTls<'a> {
@@ -128,12 +127,9 @@ impl WasiTlsCtxBuilder {
128127
Default::default()
129128
}
130129

131-
/// Sets the TLS provider to use for this context.
130+
/// Configure the TLS provider to use for this context.
132131
///
133-
/// By default, this is set to the [`DefaultProvider`] which is picked at
134-
/// compile time based on feature flags. If this crate is compiled with
135-
/// multiple TLS providers, this method can be used to specify the provider
136-
/// at runtime.
132+
/// By default, this is set to the [`RustlsProvider`].
137133
pub fn provider(mut self, provider: Box<dyn TlsProvider>) -> Self {
138134
self.provider = provider;
139135
self
@@ -149,7 +145,7 @@ impl WasiTlsCtxBuilder {
149145
impl Default for WasiTlsCtxBuilder {
150146
fn default() -> Self {
151147
Self {
152-
provider: Box::new(DefaultProvider::default()),
148+
provider: Box::new(RustlsProvider::default()),
153149
}
154150
}
155151
}

crates/wasi-tls/src/providers/mod.rs

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)