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

WebTransport #143

Closed
totaam opened this issue Jan 5, 2022 · 4 comments
Closed

WebTransport #143

totaam opened this issue Jan 5, 2022 · 4 comments
Labels
enhancement New feature or request

Comments

@totaam
Copy link
Collaborator

totaam commented Jan 5, 2022

chrome status : WebTransport

There's going to be a lot of overlap with Xpra-org/xpra#3376

@totaam
Copy link
Collaborator Author

totaam commented Jun 21, 2024

According to this SO answer, we should be able to open a WebTransport connection using a self-signed certificate with the serverCertificateHashes option.

Something like:

openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -x509 -nodes -days 10 \
    -out ./cert.pem -keyout ./key.pem -subj '/CN=Test Certificate' -addext "subjectAltName = DNS:localhost"
openssl x509 -in cert.pem | openssl dgst -sha256 -binary | openssl enc -base64 > cert-hash.b64
xpra start --bind-quic=0.0.0.0:10000  --no-daemon \
    --start=xterm -d websocket,http,quic --ssl-cert=./cert.pem --ssl-key=./key.pem 

Then this Javascript should work:

const hash = "bVBYOdvpjg5QYaOl9QZXnktoqu7XhMDiTdwbzBn6cAI=";
function base64ToArrayBuffer(base64) {
    var binaryString = atob(base64);
    var bytes = new Uint8Array(binaryString.length);
    for (var i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
    }
    return bytes.buffer;
}
const wt = new WebTransport('https://127.0.0.1:10000/', {
        serverCertificateHashes: [
          {
            algorithm: 'sha-256',
            value: base64ToArrayBuffer(hash)
          }
        ]
      });
await wt.ready

Unfortunately, this raises a: WebTransportError: Opening handshake failed..
I also tried with aioquic's example http server, it also fails, showing this message:

INFO quic [69d01f836aa19fc7] Connection close received (code 0x12E, reason 199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown)

Important note: do not use localhost, use 127.0.0.1 - because IPv6 breaks things, as always.

This would be extremely useful for testing, or even for deployments were the key hash can be exchanged securely through other means.


Another example here: GoogleChrome: webtransport_server.py does not use serverCertificateHashes so perhaps this is not supported by chrome?

@totaam
Copy link
Collaborator Author

totaam commented Jun 22, 2024

W3C WebTransport: Authentication using Certificate Hashes

Chrome

The only test I can find actually checks that hashes don't work..
chromium w3c: server-certificate-hashes.https.any.js
Despite using both the chrome command line switches and the serverCertificateHashes option, both xpra and the aioquic test server report the exact same message:

INFO quic [1673eed874a5ffe5] Connection close received (code 0x12E, reason 199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown)

Firefox

Issues: Support serverCertificateHashes in the WebTransport constructor options and Webtransport: serverCertificateHashes does not work as expected
Reads like this should work as of Firefox 125.
Fedora 40 has Firefox 127 now, but I get WebTransport connection rejected:

Uncaught (in promise) 
WebTransportError { source: "session", streamErrorCode: null, name: "WebTransportError", message: "WebTransport connection rejected", code: 0, result: 0, filename: "", lineNumber: 0, columnNumber: 0, data: null }

And both xpra and the aioquic test server report the same sequence of events:

[509ff5d9deec30d3] Network path ('127.0.0.1', 40808) discovered
[509ff5d9deec30d3] QuicConnectionState.FIRSTFLIGHT -> QuicConnectionState.CONNECTED
[509ff5d9deec30d3] TLS State.SERVER_EXPECT_CLIENT_HELLO -> State.SERVER_EXPECT_FINISHED
[ce348454c92e82cf465d19d41aecd864c7] Network path ('127.0.0.1', 44281) discovered
[ce348454c92e82cf465d19d41aecd864c7] QuicConnectionState.FIRSTFLIGHT -> QuicConnectionState.CONNECTED
[ce348454c92e82cf465d19d41aecd864c7] TLS State.SERVER_EXPECT_CLIENT_HELLO -> State.SERVER_EXPECT_FINISHED
[509ff5d9deec30d3] Discarding epoch Epoch.INITIAL
[509ff5d9deec30d3] Connection close received (code 0x12B, reason )
[509ff5d9deec30d3] QuicConnectionState.CONNECTED -> QuicConnectionState.DRAINING
[ce348454c92e82cf465d19d41aecd864c7] Discarding epoch Epoch.INITIAL
[ce348454c92e82cf465d19d41aecd864c7] Connection close received (code 0x12B, reason )
[ce348454c92e82cf465d19d41aecd864c7] QuicConnectionState.CONNECTED -> QuicConnectionState.DRAINING
[ce348454c92e82cf465d19d41aecd864c7] Discarding epoch Epoch.HANDSHAKE
[ce348454c92e82cf465d19d41aecd864c7] Discarding epoch Epoch.ONE_RTT
[ce348454c92e82cf465d19d41aecd864c7] QuicConnectionState.DRAINING -> QuicConnectionState.TERMINATED
[509ff5d9deec30d3] Discarding epoch Epoch.HANDSHAKE
[509ff5d9deec30d3] Discarding epoch Epoch.ONE_RTT
[509ff5d9deec30d3] QuicConnectionState.DRAINING -> QuicConnectionState.TERMINATED

Safari

is the new IE - it is hopeless:
web-platform-tests dashboard: server-certificate-hashes test: Can't find variable: WebTransport!

@totaam
Copy link
Collaborator Author

totaam commented Jun 24, 2024

Only managed to connect by using an mkcert CA and an https context hosting the Javascript - without any serverCertificateHashes shenanigans.

My guess is that the default CSP is preventing the browser from connecting to a WebTransport endpoint unless the Javascript is also running from a secure page + maybe some more hosts restrictions.

@totaam
Copy link
Collaborator Author

totaam commented Jun 29, 2024

Working as of the commit above and xpra 6.1 from git master.

To use it:

  • start an xpra server with a valid SSL certificate (more below):
xpra start --start=xterm --no-daemon -d quic \
    --bind-tcp=0.0.0.0:10000 --bind-quic=0.0.0.0:10000 \
    --ssl-cert=./cert.pem --ssl-key=./key.pem 
  • browse to https://host:10000/ and toggle webtransport on
  • connect

Note: using a valid certificate is a pain.
I have used mkcert successfully with Firefox, but not with Chrome..
Valid letsencrypt certificates work with both.


To verify that the connection uses WebTransport instead of secure websockets, run:

xpra info | grep -i connection.type

It should show webtransport and not wss.
(this requires Xpra-org/xpra@ed03934 or later version of the xpra server)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant