What’s the problem with WebSockets?

Enabling WSS across the libp2p network discussed how we could assign every node a subdomain of [libp2p.direct](<http://libp2p.direct>) and help every node obtain a TLS certificate from LetsEncrypt, thereby enabling browser nodes to connect to the rest of the network. While this approach would work, it is a hack to allow the browser to accept the certificate within the WebPKI framework. In particular, the most important downsides are:

For a comparison of handshake latencies see below.

What is WebTransport?

Think of it as WebSockets over QUIC. It’s a way for browsers to establish a stream-multiplexed connection to servers that allows bidirectional streaming.

The WebTransport protocol is currently under development at the IETF. Chrome has implemented and shipped support for draft-02.

The most exciting feature for us (other than the improved performance and hole punching success rates that QUIC gives us) is that the W3C added a browser API allowing browsers to establish connections to nodes with self-signed certificates, provided they know the hash of the certificate in advance: [serverCertificateHashes](<https://www.w3.org/TR/webtransport/#dom-webtransportoptions-servercertificatehashes>) . Even more exciting, this is already implemented in Chrome and will ship with version 100.

Firefox is working on a WebTransport implementation and is likely to implement serverCertificateHashes as well.

How can we use this in libp2p?

Certificates

(Browser) Nodes need to know the hash of the certificate before establishing a WebTransport connection. The W3C spec limits the use of certificates used with the serverCertificateHashes option to 2 weeks, thus we need to be prepared to roll certificates on a regular basis.

One option is to include (up to) two certificate hashes in the multiaddr: /ip4/1.2.3.4/udp/1234/quic/webtransport/<hash1><hash2>. This would allow the node to roll to prepare a new certificate one week in advance, and advertise the hash to the network.

Handshake

The WebTransport handshake doesn’t give us quite the security properties that we want: assuming that the multiaddr was received in a signed peer record, the client is able to verify that it connected to the right node, but the server still doesn’t know the identity of the client.

We therefore need to run a separate handshake on top of the WebTransport connection and double-encrypt application data. For example, we could use the first (WebTransport) stream to run a TLS 1.3 handshake, and use HKDF to derive a separate symmetric key to encrypt every subsequent stream. Note that this adds an additional roundtrip to connection establishment.

Implementation