fix(cast): accept X.509 v1 device certificates in TLS handshake

Connecting to Cast devices failed with:
Connection error: invalid peer certificate: Other(OtherError(UnsupportedCertVersion))

Many Cast devices (notably AV receivers with Chromecast built-in) serve a
self-signed X.509 version 1 certificate on port 8009. rust_cast 0.21's
NoCertificateVerification verifier accepts any certificate in
verify_server_cert, but its signature checks delegate to rustls helpers
that parse the certificate with webpki, which only supports version 3
certificates. The handshake therefore aborts for v1 device certificates;
this affects every rustls-based rust_cast release (0.19+) and only devices
happening to serve v3 certificates can connect.

Vendors rust_cast 0.21.0 under crates/vendor with a minimal patch: the
verifier's verify_tls12_signature/verify_tls13_signature now assert
validity, matching the verifier's no-validation contract and the rustls
danger verifier examples. Wired up via [patch.crates-io]; see
crates/vendor/rust_cast/QBZ_PATCH.md for the full analysis and how to drop
the patch once upstream releases the fix.

Verified against a real device serving a v1 certificate (TLS 1.2,
ECDHE-RSA-CHACHA20-POLY1305): handshake, receiver channel and heartbeat
now establish; unpatched fails at the first channel write. cargo
check/test -p qbz-cast pass (13 tests).

Refs: rustls/rustls#1298, rustls/webpki#29, #439
This commit is contained in:
mazipani committed 2026-08-31 14:50:01 +02:00
1 parent bb1b1a5648
commit 658524c404
27 files changed
+7384 -2

No files matched your search

+10
View File
@@ -114,6 +114,16 @@ strsim = "0.11"
# Note: Linux-specific dependencies (alsa) go in individual crate Cargo.toml files
# because workspace manifests cannot have [target] sections
# Local patch of rust_cast 0.21.0 (see crates/vendor/rust_cast/QBZ_PATCH.md):
# its NoCertificateVerification verifier delegates TLS signature checks to
# rustls helpers that parse the server certificate with webpki, which rejects
# the X.509 v1 self-signed certificates served by many Cast devices (AV
# receivers with Chromecast built-in) during the handshake. The vendored copy
# asserts signature validity instead, matching the verifier's no-validation
# contract. Drop this patch once a rust_cast release carries the fix upstream.
[patch.crates-io]
rust_cast = { path = "vendor/rust_cast" }
[profile.release]
# Strip symbol tables from release binaries. Measured on 2026-07-02:
# 400 MB -> 218 MB (-45%). Trade-off: panic backtraces show addresses instead