Closed totaam closed 2 months ago
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?
W3C WebTransport: Authentication using Certificate Hashes
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)
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
is the new IE - it is hopeless:
web-platform-tests dashboard: server-certificate-hashes test: Can't find variable: WebTransport
!
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.
Working as of the commit above and xpra 6.1 from git master.
To use it:
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
https://host:10000/
and toggle webtransport
onNote: 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 https://github.com/Xpra-org/xpra/commit/ed03934e5271fc4b3090d8796b64b98d66ee2f7e or later version of the xpra server)
chrome status : WebTransport
There's going to be a lot of overlap with https://github.com/Xpra-org/xpra/issues/3376