From 91f93ceffacbe977a3c2cb3ce7ef1fdf6c6716ee Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 16 Dec 2025 15:47:59 +0100 Subject: [PATCH 1/3] feat(p3): add `client` interface Signed-off-by: Roman Volosatovs --- wit-0.3.0-draft/client.wit | 36 ++++++++++++++++++++++++++++++++++++ wit-0.3.0-draft/world.wit | 5 +++++ 2 files changed, 41 insertions(+) create mode 100644 wit-0.3.0-draft/client.wit create mode 100644 wit-0.3.0-draft/world.wit diff --git a/wit-0.3.0-draft/client.wit b/wit-0.3.0-draft/client.wit new file mode 100644 index 0000000..26ecf27 --- /dev/null +++ b/wit-0.3.0-draft/client.wit @@ -0,0 +1,36 @@ +interface client { + resource hello { + /// Constructs a new ClientHello message. + constructor(); + + /// Sets the server name indicator. + /// + /// Returns an error if it is not valid. + /// + /// If this function is not called, the SNI extension will not be sent. + set-server-name: func(server-name: string) -> result; + + /// Sets the ALPN IDs advertised by the client. + set-alpn-ids: func(alpn-ids: list>); + + /// Sets a list of the symmetric cipher options supported by + /// the client, specifically the record protection algorithm + /// (including secret key length) and a hash to be used with HKDF, in + /// descending order of client preference. + /// + /// If this list is empty, the implementation must use a reasonable default. + set-cipher-suites: func(cipher-suites: list); + } + + resource handshake { + /// Gets the single cipher suite selected by the server from + /// the list in ClientHello.cipher_suites. + get-cipher-suite: func() -> u16; + + /// Closing the `data` stream will trigger `close_notify`. + finish: static func(this: handshake, data: stream) -> tuple, future>; + } + + /// Initiate the client TLS handshake + connect: func(hello: hello, incoming: stream) -> tuple, future>>; +} diff --git a/wit-0.3.0-draft/world.wit b/wit-0.3.0-draft/world.wit new file mode 100644 index 0000000..39abc1e --- /dev/null +++ b/wit-0.3.0-draft/world.wit @@ -0,0 +1,5 @@ +package wasi:tls@0.3.0-draft; + +world imports { + import client; +} From 3090989eb9befa0d6ad81f610169332e03d0e148 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 13 Jan 2026 17:31:33 +0100 Subject: [PATCH 2/3] chore(p3): keep the API surface minimal Signed-off-by: Roman Volosatovs --- wit-0.3.0-draft/client.wit | 42 ++++++++++++-------------------------- wit-0.3.0-draft/types.wit | 5 +++++ wit-0.3.0-draft/world.wit | 1 + 3 files changed, 19 insertions(+), 29 deletions(-) create mode 100644 wit-0.3.0-draft/types.wit diff --git a/wit-0.3.0-draft/client.wit b/wit-0.3.0-draft/client.wit index 26ecf27..b7ff192 100644 --- a/wit-0.3.0-draft/client.wit +++ b/wit-0.3.0-draft/client.wit @@ -1,36 +1,20 @@ interface client { - resource hello { - /// Constructs a new ClientHello message. + resource connector { constructor(); - /// Sets the server name indicator. - /// - /// Returns an error if it is not valid. - /// - /// If this function is not called, the SNI extension will not be sent. - set-server-name: func(server-name: string) -> result; + /// 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) -> tuple, future>>; - /// Sets the ALPN IDs advertised by the client. - set-alpn-ids: func(alpn-ids: list>); + /// 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) -> tuple, future>>; - /// Sets a list of the symmetric cipher options supported by - /// the client, specifically the record protection algorithm - /// (including secret key length) and a hash to be used with HKDF, in - /// descending order of client preference. - /// - /// If this list is empty, the implementation must use a reasonable default. - set-cipher-suites: func(cipher-suites: list); + /// 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>; } - - resource handshake { - /// Gets the single cipher suite selected by the server from - /// the list in ClientHello.cipher_suites. - get-cipher-suite: func() -> u16; - - /// Closing the `data` stream will trigger `close_notify`. - finish: static func(this: handshake, data: stream) -> tuple, future>; - } - - /// Initiate the client TLS handshake - connect: func(hello: hello, incoming: stream) -> tuple, future>>; } diff --git a/wit-0.3.0-draft/types.wit b/wit-0.3.0-draft/types.wit new file mode 100644 index 0000000..fc6c4b1 --- /dev/null +++ b/wit-0.3.0-draft/types.wit @@ -0,0 +1,5 @@ +interface types { + resource error { + to-debug-string: func() -> string; + } +} diff --git a/wit-0.3.0-draft/world.wit b/wit-0.3.0-draft/world.wit index 39abc1e..599d496 100644 --- a/wit-0.3.0-draft/world.wit +++ b/wit-0.3.0-draft/world.wit @@ -2,4 +2,5 @@ package wasi:tls@0.3.0-draft; world imports { import client; + import types; } From 52e5f815c5b535a51f7a6b03fe68bfe3b4602f40 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 17 Feb 2026 13:02:09 +0100 Subject: [PATCH 3/3] fixup suggestion interface Signed-off-by: Roman Volosatovs --- wit-0.3.0-draft/client.wit | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wit-0.3.0-draft/client.wit b/wit-0.3.0-draft/client.wit index b7ff192..8f282db 100644 --- a/wit-0.3.0-draft/client.wit +++ b/wit-0.3.0-draft/client.wit @@ -1,4 +1,6 @@ interface client { + use types.{error}; + resource connector { constructor(); @@ -15,6 +17,6 @@ interface client { /// 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>; + connect: static async func(this: connector, server-name: string) -> result<_, error>; } }