mirror of
https://github.com/librespot-org/librespot.git
synced 2025-10-02 17:29:22 +02:00
fix: rustls-tls features to support certificate stores (#1542)
Add separate features for native system roots and Mozilla webpki roots. Update documentation and build configs to reflect new options.
This commit is contained in:
parent
0a4969ffe2
commit
78ce118d32
15 changed files with 126 additions and 79 deletions
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
|
@ -80,12 +80,14 @@ jobs:
|
|||
- name: Check workspace with native-tls
|
||||
run: >
|
||||
cargo hack check -p librespot --each-feature --exclude-all-features
|
||||
--include-features native-tls --exclude-features rustls-tls
|
||||
--include-features native-tls
|
||||
--exclude-features rustls-tls-native-roots,rustls-tls-webpki-roots
|
||||
|
||||
- name: Check workspace with rustls-tls
|
||||
- name: Check workspace with rustls-tls-native-roots
|
||||
run: >
|
||||
cargo hack check -p librespot --each-feature --exclude-all-features
|
||||
--include-features rustls-tls --exclude-features native-tls
|
||||
--include-features rustls-tls-native-roots
|
||||
--exclude-features native-tls,rustls-tls-webpki-roots
|
||||
|
||||
- name: Build binary with default features
|
||||
run: cargo build --frozen
|
||||
|
|
4
.github/workflows/cross-compile.yml
vendored
4
.github/workflows/cross-compile.yml
vendored
|
@ -61,14 +61,14 @@ jobs:
|
|||
toolchain: ${{ matrix.toolchain }}
|
||||
args: --locked --verbose
|
||||
|
||||
- name: Build binary with rustls-tls and no default features
|
||||
- name: Build binary without system dependencies
|
||||
if: matrix.platform.target == 'riscv64gc-unknown-linux-gnu'
|
||||
uses: houseabsolute/actions-rust-cross@v1
|
||||
with:
|
||||
command: build
|
||||
target: ${{ matrix.platform.target }}
|
||||
toolchain: ${{ matrix.toolchain }}
|
||||
args: --locked --verbose --no-default-features --features rustls-tls
|
||||
args: --locked --verbose --no-default-features --features rustls-tls-webpki-roots
|
||||
|
||||
- name: Upload debug artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
|
|
14
.github/workflows/quality.yml
vendored
14
.github/workflows/quality.yml
vendored
|
@ -71,9 +71,17 @@ jobs:
|
|||
- name: Run clippy with native-tls
|
||||
run: >
|
||||
cargo hack clippy -p librespot --each-feature --exclude-all-features
|
||||
--include-features native-tls --exclude-features rustls-tls
|
||||
--include-features native-tls
|
||||
--exclude-features rustls-tls-native-roots,rustls-tls-webpki-roots
|
||||
|
||||
- name: Run clippy with rustls-tls
|
||||
- name: Run clippy with rustls-tls-native-roots
|
||||
run: >
|
||||
cargo hack clippy -p librespot --each-feature --exclude-all-features
|
||||
--include-features rustls-tls --exclude-features native-tls
|
||||
--include-features rustls-tls-native-roots
|
||||
--exclude-features native-tls,rustls-tls-webpki-roots
|
||||
|
||||
- name: Run clippy with rustls-tls-webpki-roots
|
||||
run: >
|
||||
cargo hack clippy -p librespot --each-feature --exclude-all-features
|
||||
--include-features rustls-tls-webpki-roots
|
||||
--exclude-features native-tls,rustls-tls-native-roots
|
||||
|
|
17
COMPILING.md
17
COMPILING.md
|
@ -96,10 +96,18 @@ sudo dnf install openssl-devel pkg-config
|
|||
```
|
||||
|
||||
#### rustls-tls
|
||||
Uses a Rust-based TLS implementation with `rustls-platform-verifier` for certificate authority (CA) verification:
|
||||
Uses a Rust-based TLS implementation with certificate authority (CA) verification. Two certificate store options are available:
|
||||
|
||||
**rustls-tls-native-roots**:
|
||||
- **Linux**: Uses system ca-certificates package
|
||||
- **macOS**: Uses Security.framework for CA verification
|
||||
- **Windows**: Uses Windows certificate store
|
||||
- Integrates with system certificate management and security updates
|
||||
|
||||
**rustls-tls-webpki-roots**:
|
||||
- Uses Mozilla's compiled-in certificate store (webpki-roots)
|
||||
- Certificate trust is independent of host system
|
||||
- Best for reproducible builds, containers, or embedded systems
|
||||
|
||||
**When to choose rustls-tls:**
|
||||
- You want to avoid external OpenSSL dependencies
|
||||
|
@ -118,8 +126,11 @@ cargo build
|
|||
# Explicitly use native-tls
|
||||
cargo build --no-default-features --features "native-tls rodio-backend with-libmdns"
|
||||
|
||||
# Use rustls-tls instead
|
||||
cargo build --no-default-features --features "rustls-tls rodio-backend with-libmdns"
|
||||
# Use rustls-tls with native certificate stores
|
||||
cargo build --no-default-features --features "rustls-tls-native-roots rodio-backend with-libmdns"
|
||||
|
||||
# Use rustls-tls with Mozilla's webpki certificate store
|
||||
cargo build --no-default-features --features "rustls-tls-webpki-roots rodio-backend with-libmdns"
|
||||
```
|
||||
|
||||
**Important:** The TLS backends are mutually exclusive. Attempting to enable both will result in a compile-time error.
|
||||
|
|
46
Cargo.lock
generated
46
Cargo.lock
generated
|
@ -1324,6 +1324,7 @@ dependencies = [
|
|||
"tokio-rustls 0.25.0",
|
||||
"tower-service",
|
||||
"webpki",
|
||||
"webpki-roots 0.26.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1343,6 +1344,7 @@ dependencies = [
|
|||
"tokio",
|
||||
"tokio-rustls 0.25.0",
|
||||
"tower-service",
|
||||
"webpki-roots 0.26.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1355,12 +1357,12 @@ dependencies = [
|
|||
"hyper",
|
||||
"hyper-util",
|
||||
"rustls 0.23.31",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-pki-types",
|
||||
"rustls-platform-verifier",
|
||||
"tokio",
|
||||
"tokio-rustls 0.26.2",
|
||||
"tower-service",
|
||||
"webpki-roots",
|
||||
"webpki-roots 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3028,6 +3030,7 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
"quinn",
|
||||
"rustls 0.23.31",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -3043,7 +3046,7 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"webpki-roots",
|
||||
"webpki-roots 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3201,33 +3204,6 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-platform-verifier"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be59af91596cac372a6942530653ad0c3a246cdd491aaa9dcaee47f88d67d5a0"
|
||||
dependencies = [
|
||||
"core-foundation 0.10.1",
|
||||
"core-foundation-sys",
|
||||
"jni",
|
||||
"log",
|
||||
"once_cell",
|
||||
"rustls 0.23.31",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-platform-verifier-android",
|
||||
"rustls-webpki 0.103.4",
|
||||
"security-framework 3.3.0",
|
||||
"security-framework-sys",
|
||||
"webpki-root-certs",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-platform-verifier-android"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.102.8"
|
||||
|
@ -3936,11 +3912,13 @@ dependencies = [
|
|||
"log",
|
||||
"native-tls",
|
||||
"rustls 0.23.31",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls 0.26.2",
|
||||
"tungstenite",
|
||||
"webpki-roots 0.26.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4366,12 +4344,12 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-root-certs"
|
||||
version = "1.0.2"
|
||||
name = "webpki-roots"
|
||||
version = "0.26.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4ffd8df1c57e87c325000a3d6ef93db75279dc3a231125aac571650f22b12a"
|
||||
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
"webpki-roots 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
29
Cargo.toml
29
Cargo.toml
|
@ -48,14 +48,27 @@ default = ["native-tls", "rodio-backend", "with-libmdns"]
|
|||
# system-managed certificates.
|
||||
native-tls = ["librespot-core/native-tls", "librespot-oauth/native-tls"]
|
||||
|
||||
# rustls-tls: Uses the Rust-based rustls TLS implementation with platform certificate verification.
|
||||
# This provides a Rust TLS stack (with assembly optimizations) that uses rustls-platform-verifier to
|
||||
# automatically select the appropriate certificate authority (CA) certificates from your system's
|
||||
# trust store. Choose this for avoiding external OpenSSL dependencies, reproducible builds, or when
|
||||
# targeting platforms where native TLS dependencies are unavailable or problematic (musl, embedded,
|
||||
# static linking). On Linux it uses ca-certificates, on macOS it uses Security.framework, and on
|
||||
# Windows it uses the Windows certificate store.
|
||||
rustls-tls = ["librespot-core/rustls-tls", "librespot-oauth/rustls-tls"]
|
||||
# rustls-tls: Uses the Rust-based rustls TLS implementation with certificate authority (CA)
|
||||
# verification. This provides a Rust TLS stack (with assembly optimizations). Choose this for
|
||||
# avoiding external OpenSSL dependencies, reproducible builds, or when targeting platforms where
|
||||
# native TLS dependencies are unavailable or problematic (musl, embedded, static linking).
|
||||
#
|
||||
# Two certificate store options are available:
|
||||
#
|
||||
# - rustls-tls-native-roots: Uses rustls with native system certificate stores (ca-certificates on
|
||||
# Linux, Security.framework on macOS, Windows certificate store on Windows). Best for most users as
|
||||
# it integrates with system-managed certificates and gets security updates through the OS.
|
||||
rustls-tls-native-roots = [
|
||||
"librespot-core/rustls-tls-native-roots",
|
||||
"librespot-oauth/rustls-tls-native-roots",
|
||||
]
|
||||
# rustls-tls-webpki-roots: Uses rustls with Mozilla's compiled-in certificate store (webpki-roots).
|
||||
# Best for reproducible builds, containerized environments, or when you want certificate handling
|
||||
# to be independent of the host system.
|
||||
rustls-tls-webpki-roots = [
|
||||
"librespot-core/rustls-tls-webpki-roots",
|
||||
"librespot-oauth/rustls-tls-webpki-roots",
|
||||
]
|
||||
|
||||
# Audio backends - see README.md for audio backend selection guide
|
||||
# Cross-platform backends:
|
||||
|
|
|
@ -14,7 +14,8 @@ default = ["native-tls"]
|
|||
|
||||
# TLS backend propagation
|
||||
native-tls = ["librespot-core/native-tls"]
|
||||
rustls-tls = ["librespot-core/rustls-tls"]
|
||||
rustls-tls-native-roots = ["librespot-core/rustls-tls-native-roots"]
|
||||
rustls-tls-webpki-roots = ["librespot-core/rustls-tls-webpki-roots"]
|
||||
|
||||
[dependencies]
|
||||
librespot-core.workspace = true
|
||||
|
|
|
@ -13,8 +13,9 @@ edition.workspace = true
|
|||
default = ["native-tls"]
|
||||
|
||||
# TLS backend propagation
|
||||
native-tls = ["librespot-core/native-tls", "librespot-playback/native-tls"]
|
||||
rustls-tls = ["librespot-core/rustls-tls", "librespot-playback/rustls-tls"]
|
||||
native-tls = ["librespot-core/native-tls"]
|
||||
rustls-tls-native-roots = ["librespot-core/rustls-tls-native-roots"]
|
||||
rustls-tls-webpki-roots = ["librespot-core/rustls-tls-webpki-roots"]
|
||||
|
||||
[dependencies]
|
||||
librespot-core.workspace = true
|
||||
|
|
|
@ -21,12 +21,23 @@ native-tls = [
|
|||
"librespot-oauth/native-tls",
|
||||
"tokio-tungstenite/native-tls",
|
||||
]
|
||||
rustls-tls = [
|
||||
"dep:hyper-rustls",
|
||||
rustls-tls-native-roots = [
|
||||
"__rustls",
|
||||
"hyper-proxy2/rustls",
|
||||
"librespot-oauth/rustls-tls",
|
||||
"tokio-tungstenite/__rustls-tls",
|
||||
"hyper-rustls/native-tokio",
|
||||
"librespot-oauth/rustls-tls-native-roots",
|
||||
"tokio-tungstenite/rustls-tls-native-roots",
|
||||
]
|
||||
rustls-tls-webpki-roots = [
|
||||
"__rustls",
|
||||
"hyper-proxy2/rustls-webpki",
|
||||
"hyper-rustls/webpki-tokio",
|
||||
"librespot-oauth/rustls-tls-webpki-roots",
|
||||
"tokio-tungstenite/rustls-tls-webpki-roots",
|
||||
]
|
||||
|
||||
# Internal features - these are not meant to be used by end users
|
||||
__rustls = []
|
||||
|
||||
[dependencies]
|
||||
librespot-oauth.workspace = true
|
||||
|
@ -60,8 +71,6 @@ hyper-rustls = { version = "0.27", default-features = false, features = [
|
|||
"http1",
|
||||
"http2",
|
||||
"ring",
|
||||
"rustls-platform-verifier",
|
||||
"tls12",
|
||||
], optional = true }
|
||||
hyper-tls = { version = "0.6", optional = true }
|
||||
hyper-util = { version = "0.1", default-features = false, features = [
|
||||
|
|
|
@ -22,9 +22,9 @@ use parking_lot::Mutex;
|
|||
use thiserror::Error;
|
||||
use url::Url;
|
||||
|
||||
#[cfg(all(feature = "rustls-tls", not(feature = "native-tls")))]
|
||||
#[cfg(all(feature = "__rustls", not(feature = "native-tls")))]
|
||||
use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder};
|
||||
#[cfg(all(feature = "native-tls", not(feature = "rustls-tls")))]
|
||||
#[cfg(all(feature = "native-tls", not(feature = "__rustls")))]
|
||||
use hyper_tls::HttpsConnector;
|
||||
|
||||
use crate::{
|
||||
|
@ -150,13 +150,16 @@ impl HttpClient {
|
|||
fn try_create_hyper_client(proxy_url: Option<&Url>) -> Result<HyperClient, Error> {
|
||||
// configuring TLS is expensive and should be done once per process
|
||||
|
||||
#[cfg(all(feature = "rustls-tls", not(feature = "native-tls")))]
|
||||
#[cfg(all(feature = "__rustls", not(feature = "native-tls")))]
|
||||
let https_connector = {
|
||||
let tls = HttpsConnectorBuilder::new().with_platform_verifier();
|
||||
#[cfg(feature = "rustls-tls-native-roots")]
|
||||
let tls = HttpsConnectorBuilder::new().with_native_roots()?;
|
||||
#[cfg(feature = "rustls-tls-webpki-roots")]
|
||||
let tls = HttpsConnectorBuilder::new().with_webpki_roots();
|
||||
tls.https_or_http().enable_http1().enable_http2().build()
|
||||
};
|
||||
|
||||
#[cfg(all(feature = "native-tls", not(feature = "rustls-tls")))]
|
||||
#[cfg(all(feature = "native-tls", not(feature = "__rustls")))]
|
||||
let https_connector = HttpsConnector::new();
|
||||
|
||||
// When not using a proxy a dummy proxy is configured that will not intercept any traffic.
|
||||
|
|
|
@ -19,7 +19,8 @@ with-libmdns = ["dep:libmdns"]
|
|||
|
||||
# TLS backend propagation
|
||||
native-tls = ["librespot-core/native-tls"]
|
||||
rustls-tls = ["librespot-core/rustls-tls"]
|
||||
rustls-tls-native-roots = ["librespot-core/rustls-tls-native-roots"]
|
||||
rustls-tls-webpki-roots = ["librespot-core/rustls-tls-webpki-roots"]
|
||||
|
||||
[dependencies]
|
||||
librespot-core.workspace = true
|
||||
|
|
|
@ -14,7 +14,8 @@ default = ["native-tls"]
|
|||
|
||||
# TLS backend propagation
|
||||
native-tls = ["librespot-core/native-tls"]
|
||||
rustls-tls = ["librespot-core/rustls-tls"]
|
||||
rustls-tls-native-roots = ["librespot-core/rustls-tls-native-roots"]
|
||||
rustls-tls-webpki-roots = ["librespot-core/rustls-tls-webpki-roots"]
|
||||
|
||||
[dependencies]
|
||||
librespot-core.workspace = true
|
||||
|
|
|
@ -14,7 +14,19 @@ default = ["native-tls"]
|
|||
|
||||
# TLS backends (mutually exclusive - compile-time checks in src/lib.rs)
|
||||
native-tls = ["oauth2/native-tls", "reqwest/native-tls"]
|
||||
rustls-tls = ["oauth2/rustls-tls", "reqwest/rustls-tls"]
|
||||
rustls-tls-native-roots = [
|
||||
"__rustls",
|
||||
"oauth2/rustls-tls",
|
||||
"reqwest/rustls-tls-native-roots",
|
||||
]
|
||||
rustls-tls-webpki-roots = [
|
||||
"__rustls",
|
||||
"oauth2/rustls-tls",
|
||||
"reqwest/rustls-tls-webpki-roots",
|
||||
]
|
||||
|
||||
# Internal features - these are not meant to be used by end users
|
||||
__rustls = []
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
|
|
|
@ -39,12 +39,14 @@ use url::Url;
|
|||
// The dependency chain is: workspace -> core -> oauth
|
||||
// So oauth's feature validation runs before core's, catching configuration errors quickly.
|
||||
|
||||
#[cfg(all(feature = "native-tls", feature = "rustls-tls"))]
|
||||
compile_error!("Features 'native-tls' and 'rustls-tls' are mutually exclusive. Enable only one.");
|
||||
|
||||
#[cfg(not(any(feature = "native-tls", feature = "rustls-tls")))]
|
||||
#[cfg(all(feature = "native-tls", feature = "__rustls"))]
|
||||
compile_error!(
|
||||
"Either feature \"native-tls\" (default) or \"rustls-tls\" must be enabled for this crate."
|
||||
"Feature \"native-tls\" is mutually exclusive with \"rustls-tls-native-roots\" and \"rustls-tls-webpki-roots\". Enable only one."
|
||||
);
|
||||
|
||||
#[cfg(not(any(feature = "native-tls", feature = "__rustls")))]
|
||||
compile_error!(
|
||||
"Either feature \"native-tls\" (default), \"rustls-tls-native-roots\" or \"rustls-tls-webpki-roots\" must be enabled for this crate."
|
||||
);
|
||||
|
||||
/// Possible errors encountered during the OAuth authentication flow.
|
||||
|
|
|
@ -35,10 +35,15 @@ native-tls = [
|
|||
"librespot-audio/native-tls",
|
||||
"librespot-metadata/native-tls",
|
||||
]
|
||||
rustls-tls = [
|
||||
"librespot-core/rustls-tls",
|
||||
"librespot-audio/rustls-tls",
|
||||
"librespot-metadata/rustls-tls",
|
||||
rustls-tls-native-roots = [
|
||||
"librespot-core/rustls-tls-native-roots",
|
||||
"librespot-audio/rustls-tls-native-roots",
|
||||
"librespot-metadata/rustls-tls-native-roots",
|
||||
]
|
||||
rustls-tls-webpki-roots = [
|
||||
"librespot-core/rustls-tls-webpki-roots",
|
||||
"librespot-audio/rustls-tls-webpki-roots",
|
||||
"librespot-metadata/rustls-tls-webpki-roots",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue