qbzd: install the rustls process-level CryptoProvider

The rustls crypto provider was not installed for `qbzd`, which caused the
process to panic:

> thread 'tokio-rt-worker' (15737) panicked at [...]/rustls-0.23.37/src/crypto/mod.rs:249:14:
>
> Could not automatically determine the process-level CryptoProvider from
> Rustls crate features.
> Call CryptoProvider::install_default() before this point to select a
> provider manually, or make sure exactly one of the 'aws-lc-rs' and 'ring'
> features is enabled.
> See the documentation of the CryptoProvider type for more information.

The function `ensure_crypto_provider()` was defined in the `qbz-cast` crate
which is obviously not a dependency of `qbzd`.

This commit moves `ensure_crypto_provider()` to `qbz-app`, calls it from `qbzd`
and updates `qbz` accordingly.
This commit is contained in:
François Laignel committed 2026-07-26 21:12:44 +02:00
1 parent 6fff4aae31
commit a01097708e
9 files changed
+26 -46

No files matched your search

-6
View File
@@ -8,12 +8,6 @@ description = "Casting support for QBZ - Chromecast, DLNA"
# Chromecast
rust_cast = "0.21"
# TLS provider selection. rust_cast uses rustls; in the multi-crate binary both
# the aws-lc-rs and ring providers end up enabled (reqwest pulls ring), so
# rustls can't auto-pick one and panics on connect. We install aws-lc-rs
# explicitly before connecting (see `ensure_crypto_provider`).
rustls = { version = "0.23", features = ["aws_lc_rs"] }
# mDNS discovery
mdns-sd = "0.11"
-3
View File
@@ -75,9 +75,6 @@ impl ChromecastHandle {
/// Connect to a Chromecast device
pub fn connect(&self, ip: String, port: u16) -> Result<(), CastError> {
// rust_cast opens a rustls TLS channel; make sure a CryptoProvider is
// installed first (the worker thread would otherwise panic).
crate::ensure_crypto_provider();
let (reply_tx, reply_rx) = mpsc::channel();
self.sender
.send(CastCommand::Connect {
-3
View File
@@ -60,9 +60,6 @@ pub struct DlnaConnection {
impl DlnaConnection {
/// Connect to a DLNA device and discover service URLs
pub async fn connect(device: DiscoveredDlnaDevice) -> Result<Self, DlnaError> {
// Defensive: the device-description fetch may go over TLS in some
// setups; ensure a rustls CryptoProvider is installed (idempotent).
crate::ensure_crypto_provider();
let device_url: Uri = device
.url
.parse()
-22
View File
@@ -38,25 +38,3 @@ pub use dlna::{
/// Cast device type alias for backwards compatibility
pub type CastDevice = CastDeviceConnection;
/// Install the rustls process-level `CryptoProvider` (aws-lc-rs) exactly once.
///
/// `rust_cast` opens a TLS control channel to the Chromecast via rustls. In the
/// full QBZ binary BOTH the `aws-lc-rs` and `ring` providers are enabled (reqwest
/// pulls `ring`, rust_cast pulls `aws-lc-rs`), so rustls can't auto-select one
/// and panics with "Could not automatically determine the process-level
/// CryptoProvider". Installing one explicitly before any TLS use fixes it.
///
/// Idempotent (a second call is a no-op); harmless if some other component
/// already installed a default (`install_default` then returns Err, ignored).
pub fn ensure_crypto_provider() {
use std::sync::Once;
static INIT: Once = Once::new();
INIT.call_once(|| {
if rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.is_err()
{
log::debug!("[cast] rustls CryptoProvider already installed");
}
});
}