Skip to content

Conversation

@rvolosatovs
Copy link
Contributor

@rvolosatovs rvolosatovs commented Dec 16, 2025

Introduce the client interface designed for wasip3, which is at feature-parity with what's currently available in main for wasip2 with a few additions

bytecodealliance/wasmtime#12174 contains mostly-complete host implementation of the interface in the proposed shape with a passing test (adapted directly from existing wasip2 test). The interface in the PR is an in-progress superset of the interface proposed in this PR.

This is by no means complete and is intended to just be the first step with more PRs to follow as I validate the design by continuing the host implementation in Wasmtime as well as a Python guest implementation utilizing these (have not started on Python work yet)

refs WebAssembly/wasi-sockets#100
refs WebAssembly/wasi-sockets#104

Signed-off-by: Roman Volosatovs <[email protected]>
@badeend
Copy link
Member

badeend commented Dec 23, 2025

A recap of what Roman & I have discussed out-of-band:

  • The 0.2 wasi-tls interface uses wasi-io's error type to communicate failure. The proposed interface in this PR doesn't have any error handling yet. We could add a separate types interface in wasi-tls with e.g. a verbatim copy of the old wasi-io error type.
  • Compared to the 0.2 interface, Roman's proposal turns certificate verification from a host concern into a guest concern. I can see that as a valuable advanced option for the future, but I don't think that should be the default.
  • The proposed interface also adds alpn & cipher-suite functions. For the sake of true feature parity with 0.2, I'd prefer to postpone these to a follow-up PR because there will be some implementation challenges.
  • Regarding the placement of the streams; the proposed interface is strictly speaking the most correct thing to do from a type state POV. But it also results in some gnarly function signatures. In the sockets interfaces we had the same problem and eventually went with removing the I/O streams from the connect method and instead added separate send & receive methods. Maybe we can do something similar in wasi-tls.

All of this combined then results in an interface closer to:

interface types {
    resource error {
        to-debug-string: func() -> string;
    }
}

interface client {
    resource connector {
        constructor();

        /// Set up the encryption stream transform.
        /// This takes an unprotected `cleartext` application data stream and
        /// returns an encrypted data stream, ready to be sent out over the network.
        /// Closing the `cleartext` stream will cause a `close_notify` packet to be emitted on the returned output stream.
        send: func(cleartext: stream<u8>) -> tuple<stream<u8>, future<result<_, error>>>;

        /// Set up the decryption stream transform.
        /// This takes an encrypted data stream, as received via e.g. the network,
        /// and returns a decrypted application data stream.
        receive: func(ciphertext: stream<u8>) -> tuple<stream<u8>, future<result<_, error>>>;

        /// Perform the handshake.
        /// The `send` & `receive` streams must be set up before calling this method.
        connect: async func(this: connector, server-name: string) -> result<_, error>;
    }
}

The connect method here doesn't return anything yet. The idea is that in a later version, it will return a connection resource through which the guest can read back the negotiated TLS version, ALPN id, cipher suite, server certificate, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants