badeend opened issue #10089:
wasi-tls has recently been accepted as a phase 1 proposal.
We'd like to start implementing this in wasmtime. There already exists some prior efforts:
- @dicej created a standalone WASI host with TLS support at: https://github.com/dicej/dotnet-wasi-tls
- This implements a minimal subset of the draft spec.
- Uses thenative-tls
crate.- @jsturtevant modified the .NET runtime to use Joel's implementation at: https://github.com/dotnet/runtime/compare/main...jsturtevant:runtime:wasi-tls-2
- This successfully runs their SqlClient.- Based on Joel's work, I (@badeend) started integrating it into wasmtime itself: https://github.com/badeend/wasmtime/tree/wasi-tls
- This too is just a minimal subset of the draft spec. Although the WIT in this branch has evolved slightly.
- Uses therustls
crate.
- The changes are part of the wasi-sockets interface, which is not the right place.
- And some boilerplate:
- threading through a newtls
CLI flag
- Changerustls
from awasi-http
-only dependency to a workspace dependency.
My suggestion is to add a new standalone
wasi-tls
crate:
- under the
/crates
folder, similar to the other proposals.- with its own
world.wit
andtypes.wit
.- that targets WASI v0.2 for the time being. Work on a v0.3 interface can happen in parallel in the future.
- that is completely experimental and therefore behind a
tls
flag.- uses
rustls
for its implementation? (up for discussion, see next comment)Thoughts?
CC @dicej @jsturtevant
badeend commented on issue #10089:
I did an inventory of the two most popular rust TLS crates to see how suitable they are to implement the draft spec:
rustls
:
- doesn't support post-handshake authentication.
- supports programmatic client certificate selection, but the callback isn't async.
- supports programmatic peer certificate verification, but the callback isn't async.
native-tls
:
- does not support TLS1.3 (yet)
- uses MacOS Secure Transport, which is deprecated and will likely never receive TLS1.3 support.
- does not support programmatic client certificate selection
- does not support programmatic peer certificate verification
- can't inspect the peer's certificate chain, only the leaf cert
- can't inspect ClientHello nor select server certificate & other configurations based on SNI
- can't read SNI submitted server name
- can't read negotiated TLS version
- can't read negotiated cipher suite
- can't configure ALPN ids on the server side
- can't configure cipher suites
- can't request mid-handshake client certificate on the server side
- doesn't support post-handshake authentication
From wasmtime's POV,
rustls
seems an obvious choice:
- it is already used by wasi-http,
- it is the most feature complete,
- allows us to quickly iterate on the WIT definitions. Most additions are simply hooking it up to the corresponding rustls methods.
Despite its shortcomings, from a Standards POV,
native-tls
has one important leg up:
Instant validation of portability goals against three different industry-standard back-ends (OpenSSL, SChannel, SecureTransport).
AFAIK, most of these shortcomings are of thenative-tls
crate itself and not of the underlying providers. Case in point: .NET's SSLStream is also built on top of SChannel & OpenSSL, yet _does_ support the desired features.
In the current stage the interface is still simple enough that it doesn't really matter which one we choose. I just wanted to throw it out there before we start sinking too much time into the integration of either option.
alexcrichton commented on issue #10089:
How unreasonable do you think it would be to support both rustls and native-tls? For example via compile-time Cargo features? It seems reasonable to have rustls as the default given its breadth of features but being able to showcase both in the same codebase would be a nice example for others looking to implement the proposal as well.
badeend commented on issue #10089:
Given the current simplicity of the WASI interface, it should be doable to have both backends. Looking into the future, I can't vouch for how tenable the situation will be.
The current plan is that @jsturtevant will work on the initial implementation. I haven't checked in with him on this specific point yet, but I suspect that we'll start with just a single backend. We could add the secondary backend in a follow-up PR.
@jsturtevant Does this sound about right to you?
jsturtevant commented on issue #10089:
Sounds good to me. My biggest concern would be the lack of features on the native-tls side but the initial interface is pretty minimal so shouldn't be an issue initially. We can adjust as we go.
alexcrichton commented on issue #10089:
Also to be clear if you the implementor @jsturtevant would prefer to pick one or the other I think that's totally ok too. I wouldn't consider it a requirement to support both at the beginning at all. Given how things are leaning I think it would make sense to start with rustls and once that's all working we could see if adding a native-tls backend would make sense?
alexcrichton commented on issue #10089:
Ok sorry early morning strikes again, @badeend already said all that, disregard me.
jsturtevant commented on issue #10089:
Just an update, I've gotten pretty far on this, debugging one last issue before opening up a PR.
Last updated: Feb 28 2025 at 03:10 UTC