From a0b8b12978394c20e00797339bc2669f066fffe1 Mon Sep 17 00:00:00 2001 From: Benjamin Kitt Date: Sat, 1 Aug 2026 15:03:03 -0500 Subject: [PATCH] fix(tls): trust the OS certificate store on relay WebSocket connections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tokio-tungstenite is built with only rustls-tls-webpki-roots, and native_websocket.rs calls bare connect_async() with no custom Connector, so the relay WebSocket trusts a compiled-in Mozilla root list and nothing else. Behind a TLS-inspecting proxy the re-signed certificate is rejected with 'invalid peer certificate: UnknownIssuer', and no keychain entry, SSL_CERT_FILE or NODE_EXTRA_CA_CERTS can influence it. This is easy to misdiagnose because HTTPS works: reqwest uses rustls-platform-verifier, which does read the OS trust store. Only the WebSocket path is affected, so the app looks healthy until the relay never connects. The two root-store features are additive (tls.rs pushes both into one RootCertStore, and the webpki branch is not gated on not(rustls-tls-native-roots)), so this preserves current behaviour and additionally honours the platform store. Both Cargo.lock files are regenerated so `cargo build --locked` succeeds in CI. rustls-native-certs was already vendored in each lockfile via the reqwest/rustls-platform-verifier path, so the only change is the new dependency edge from tokio-tungstenite 0.29.0 — no new packages and no version bumps. Signed-off-by: Benjamin Kitt --- Cargo.lock | 1 + Cargo.toml | 2 +- desktop/src-tauri/Cargo.lock | 1 + desktop/src-tauri/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa02e17ce3..c35d78f114 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9671,6 +9671,7 @@ dependencies = [ "futures-util", "log", "rustls", + "rustls-native-certs", "rustls-pki-types", "tokio", "tokio-rustls", diff --git a/Cargo.toml b/Cargo.toml index 3268cfaf8d..d63fb643b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,7 @@ moka = { version = "0.12", features = ["sync"] } futures-util = "0.3" # WebSocket client (test client) -tokio-tungstenite = { version = "0.29", features = ["rustls-tls-webpki-roots"] } +tokio-tungstenite = { version = "0.29", features = ["rustls-tls-webpki-roots", "rustls-tls-native-roots"] } url = "2" # Property-based testing (dev-only) diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock index 00d3fba3b5..75cff2f5b9 100644 --- a/desktop/src-tauri/Cargo.lock +++ b/desktop/src-tauri/Cargo.lock @@ -10919,6 +10919,7 @@ dependencies = [ "futures-util", "log", "rustls", + "rustls-native-certs", "rustls-pki-types", "tokio", "tokio-rustls", diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index b80684f955..32f77f15e4 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -76,7 +76,7 @@ infer = "0.19" hex = "0.4" ed25519-dalek = "=3.0.0-rc.0" tokio = { version = "1", features = ["fs", "sync", "rt", "macros", "time", "net", "io-util"] } -tokio-tungstenite = { version = "0.29", features = ["rustls-tls-webpki-roots"] } +tokio-tungstenite = { version = "0.29", features = ["rustls-tls-webpki-roots", "rustls-tls-native-roots"] } tokio-util = { version = "0.7", features = ["rt"] } bytes = "1" futures-util = "0.3"