Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation of Wasi-tls (Transport Layer Security) #10249

Merged
merged 18 commits into from
Mar 7, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Remove configuration object for now
Signed-off-by: James Sturtevant <jstur@microsoft.com>
jsturtevant committed Mar 7, 2025
commit 7ce991ec13366a183ddeb3a0cb635b54865bbf1d
53 changes: 19 additions & 34 deletions crates/wasi-tls/src/lib.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
//!
//! This crate provides the Wasmtime host implementation for the [wasi-tls] API.
//! The [wasi-tls] world allows WebAssembly modules to perform SSL/TLS operations,
//! such as establishing secure connections to servers. TLS often relies on other wasi networking systems
//! such as establishing secure connections to servers. TLS often relies on other wasi networking systems
//! to provide the stream so it will be common to enable the [wasi:cli] world as well with the networking features enabled.
//!
//! # An example of how to configure [wasi-tls] is the following:
@@ -13,25 +13,25 @@
//! component::{Linker, ResourceTable},
//! Store, Engine, Result, Config
//! };
//! use wasmtime_wasi_tls::{LinkOptions, WasiTlsConfig, WasiTlsCtx};
//! use wasmtime_wasi_tls::{LinkOptions, WasiTlsCtx};
//!
//! struct Ctx {
//! table: ResourceTable,
//! wasi_ctx: WasiCtx,
//! config: WasiTlsConfig,
//! }
//!
//! impl IoView for Ctx {
//! fn table(&mut self) -> &mut ResourceTable {
//! &mut self.table
//! }
//! }
//!
//!
//! impl WasiView for Ctx {
//! fn ctx(&mut self) -> &mut WasiCtx {
//! &mut self.wasi_ctx
//! }
//! }
//!
//!
//! #[tokio::main]
//! async fn main() -> Result<()> {
//! let ctx = Ctx {
@@ -41,35 +41,33 @@
//! .inherit_network()
//! .allow_ip_name_lookup(true)
//! .build(),
//! config: WasiTlsConfig::new(),
//! };
//!
//!
//! let mut config = Config::new();
//! config.async_support(true);
//! let engine = Engine::new(&config)?;
//!
//!
//! // Set up wasi-cli
//! let mut store = Store::new(&engine, ctx);
//! let mut linker = Linker::new(&engine);
//! wasmtime_wasi::add_to_linker_async(&mut linker)?;
//!
//!
//! // Add wasi-tls types and turn on the feature in linker
//! let mut opts = LinkOptions::default();
//! opts.tls(true);
//! wasmtime_wasi_tls::add_to_linker(&mut linker, &mut opts, |h: &mut Ctx| {
//! WasiTlsCtx::new(&h.config, &mut h.table)
//! WasiTlsCtx::new(&mut h.table)
//! })?;
//!
//! // ... use `linker` to instantiate within `store` ...
//!
//!
//! // ... use `linker` to instantiate within `store` ...
//!
//! Ok(())
//! }
//!
//!
//! ```
//! [wasi-tls]: https://github.com/WebAssembly/wasi-tls
//! [wasi:cli]: https://docs.rs/wasmtime-wasi/latest


#![deny(missing_docs)]
#![doc(test(attr(deny(warnings))))]
#![doc(test(attr(allow(dead_code, unused_variables, unused_mut))))]
@@ -130,28 +128,15 @@ fn default_client_config() -> Arc<rustls::ClientConfig> {
Arc::clone(&CONFIG)
}

/// Struct for configuring tls
#[derive(Default)]
pub struct WasiTlsConfig {}

/// Generate default configuration
impl WasiTlsConfig {
/// Creates new
pub fn new() -> Self {
Default::default()
}
}

/// Wasi TLS context needed fro internal `wasi-tls`` state
pub struct WasiTlsCtx<'a> {
table: &'a mut ResourceTable,
config: &'a WasiTlsConfig,
}

impl<'a> WasiTlsCtx<'a> {
/// Create a new Wasi TLS context
pub fn new(config: &'a WasiTlsConfig, table: &'a mut ResourceTable) -> Self {
Self { config, table }
pub fn new(table: &'a mut ResourceTable) -> Self {
Self { table }
}
}

@@ -221,7 +206,7 @@ impl<'a> generated::types::HostClientHandshake for WasiTlsCtx<'a> {
}
}

/// Future TLS connection after the handshake is completed.
/// Future TLS connection after the handshake is completed.
pub struct FutureClientStreams(StreamState<Result<TlsStream<TcpStreams>>>);

#[async_trait]
@@ -609,10 +594,10 @@ impl AsyncTlsWriteStream {
Err(err) => return Some(Err(err)),
};

match writer.close_notify(){
match writer.close_notify() {
None => None,
Some(Ok(())) => Some(Ok(())),
Some(Err(e)) => Some(Err(StreamError::LastOperationFailed(e.into())))
Some(Err(e)) => Some(Err(StreamError::LastOperationFailed(e.into()))),
}
}
}
@@ -649,4 +634,4 @@ fn try_lock_for_stream<TlsWriter>(
mutex
.try_lock()
.map_err(|_| StreamError::trap("concurrent access to resource not supported"))
}
}
6 changes: 2 additions & 4 deletions crates/wasi-tls/tests/main.rs
Original file line number Diff line number Diff line change
@@ -5,12 +5,11 @@ use wasmtime::{
Store,
};
use wasmtime_wasi::{bindings::Command, IoView, WasiCtx, WasiCtxBuilder, WasiView};
use wasmtime_wasi_tls::{LinkOptions, WasiTlsConfig, WasiTlsCtx};
use wasmtime_wasi_tls::{LinkOptions, WasiTlsCtx};

struct Ctx {
table: ResourceTable,
wasi_ctx: WasiCtx,
config: WasiTlsConfig,
}

impl IoView for Ctx {
@@ -37,7 +36,7 @@ async fn run_wasi(path: &str, ctx: Ctx) -> Result<()> {
let mut opts = LinkOptions::default();
opts.tls(true);
wasmtime_wasi_tls::add_to_linker(&mut linker, &mut opts, |h: &mut Ctx| {
WasiTlsCtx::new(&h.config, &mut h.table)
WasiTlsCtx::new(&mut h.table)
})?;

let command = Command::instantiate_async(&mut store, &component, &linker).await?;
@@ -68,7 +67,6 @@ async fn tls_sample_application() -> Result<()> {
.inherit_network()
.allow_ip_name_lookup(true)
.build(),
config: WasiTlsConfig::new(),
},
)
.await
1 change: 0 additions & 1 deletion crates/wasi-tls/wit/world.wit
Original file line number Diff line number Diff line change
@@ -30,7 +30,6 @@ interface types {
close-notify: func() -> option<result<_, io-error>>;
}


@unstable(feature = tls)
resource future-client-streams {
@unstable(feature = tls)
12 changes: 2 additions & 10 deletions src/commands/run.rs
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ use std::thread;
use wasi_common::sync::{ambient_authority, Dir, TcpListener, WasiCtxBuilder};
use wasmtime::{Engine, Func, Module, Store, StoreLimits, Val, ValType};
use wasmtime_wasi::{IoView, WasiView};
use wasmtime_wasi_tls::{WasiTlsConfig, WasiTlsCtx};
use wasmtime_wasi_tls::WasiTlsCtx;

#[cfg(feature = "wasi-nn")]
use wasmtime_wasi_nn::wit::WasiNnView;
@@ -845,15 +845,10 @@ impl RunCommand {
h.preview2_ctx.as_mut().expect("wasip2 is not configured");
let preview2_ctx =
Arc::get_mut(preview2_ctx).unwrap().get_mut().unwrap();
WasiTlsCtx::new(
Arc::get_mut(h.wasi_tls_config.as_mut().unwrap()).unwrap(),
preview2_ctx.table(),
)
WasiTlsCtx::new(preview2_ctx.table())
})?;
}
}

store.data_mut().wasi_tls_config = Some(Arc::new(WasiTlsConfig::new()));
}
}

@@ -962,9 +957,6 @@ struct Host {
wasi_config: Option<Arc<WasiConfigVariables>>,
#[cfg(feature = "wasi-keyvalue")]
wasi_keyvalue: Option<Arc<WasiKeyValueCtx>>,

#[cfg(feature = "wasi-tls")]
wasi_tls_config: Option<Arc<WasiTlsConfig>>,
}

impl Host {