net/quinn: Specify crypto provider explicitly

rustls allows the choice of ring or aws-lc-rs as the cryptographic
library implementation. This is enabled/selected via Cargo feature
flags. We have plugins directly or indirectly depending on rustls
like quinn, aws and spotify. In the presence of multiple plugins,
selecting different implementations as the default, rustls can
panic.

The safest way to avoid this is by using builder_with_provider
and selecting a provider explicitly.

See below issues for further discussion and clarifications.
https://github.com/rustls/rustls/issues/1877
https://github.com/seanmonstar/reqwest/pull/2225

While at it, also specify features explicitly for quinn and rustls.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1878>
This commit is contained in:
Sanchayan Maity 2024-10-23 17:40:31 +05:30
parent dc1d63419e
commit af54b2396b
4 changed files with 35 additions and 94 deletions

76
Cargo.lock generated
View file

@ -1049,12 +1049,6 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "cesu8"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
[[package]] [[package]]
name = "cexpr" name = "cexpr"
version = "0.6.0" version = "0.6.0"
@ -1214,16 +1208,6 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "combine"
version = "4.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
dependencies = [
"bytes",
"memchr",
]
[[package]] [[package]]
name = "concurrent-queue" name = "concurrent-queue"
version = "2.5.0" version = "2.5.0"
@ -4357,26 +4341,6 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "jni"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec"
dependencies = [
"cesu8",
"combine",
"jni-sys",
"log",
"thiserror",
"walkdir",
]
[[package]]
name = "jni-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]] [[package]]
name = "jobserver" name = "jobserver"
version = "0.1.32" version = "0.1.32"
@ -5775,7 +5739,6 @@ dependencies = [
"ring", "ring",
"rustc-hash 2.0.0", "rustc-hash 2.0.0",
"rustls 0.23.15", "rustls 0.23.15",
"rustls-platform-verifier",
"slab", "slab",
"thiserror", "thiserror",
"tinyvec", "tinyvec",
@ -6033,7 +5996,7 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"web-sys", "web-sys",
"webpki-roots 0.25.4", "webpki-roots",
"winreg", "winreg",
] ]
@ -6350,33 +6313,6 @@ version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b"
[[package]]
name = "rustls-platform-verifier"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afbb878bdfdf63a336a5e63561b1835e7a8c91524f51621db870169eac84b490"
dependencies = [
"core-foundation",
"core-foundation-sys",
"jni",
"log",
"once_cell",
"rustls 0.23.15",
"rustls-native-certs 0.7.3",
"rustls-platform-verifier-android",
"rustls-webpki 0.102.8",
"security-framework",
"security-framework-sys",
"webpki-roots 0.26.6",
"winapi",
]
[[package]]
name = "rustls-platform-verifier-android"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
[[package]] [[package]]
name = "rustls-webpki" name = "rustls-webpki"
version = "0.101.7" version = "0.101.7"
@ -6500,7 +6436,6 @@ dependencies = [
"core-foundation", "core-foundation",
"core-foundation-sys", "core-foundation-sys",
"libc", "libc",
"num-bigint",
"security-framework-sys", "security-framework-sys",
] ]
@ -7913,15 +7848,6 @@ version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
[[package]]
name = "webpki-roots"
version = "0.26.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958"
dependencies = [
"rustls-pki-types",
]
[[package]] [[package]]
name = "weezl" name = "weezl"
version = "0.1.8" version = "0.1.8"

View file

@ -15,9 +15,9 @@ gst.workspace = true
gst-base.workspace = true gst-base.workspace = true
tokio = { version = "1.36.0", default-features = false, features = ["time", "rt-multi-thread"] } tokio = { version = "1.36.0", default-features = false, features = ["time", "rt-multi-thread"] }
futures = "0.3.30" futures = "0.3.30"
quinn = { version = "0.11.2", default-features = true, features = ["ring"]} quinn = { version = "0.11.5", default-features = false, features = ["ring", "rustls", "runtime-tokio"] }
quinn-proto = "0.11.2" quinn-proto ={ version = "0.11.8", default-features = false, features = ["rustls"] }
rustls = { version = "0.23", default-features = false, features = ["ring", "std"]} rustls = { version = "0.23", default-features = false, features = ["std"] }
rustls-pemfile = "2" rustls-pemfile = "2"
rustls-pki-types = "1" rustls-pki-types = "1"
rcgen = "0.13" rcgen = "0.13"

View file

@ -12,9 +12,8 @@ use futures::future;
use futures::prelude::*; use futures::prelude::*;
use gst::ErrorMessage; use gst::ErrorMessage;
use quinn::{ use quinn::{
crypto::rustls::QuicClientConfig, crypto::rustls::QuicServerConfig, default_runtime, crypto::rustls::QuicClientConfig, crypto::rustls::QuicServerConfig, ClientConfig, Connection,
ClientConfig, Connection, Endpoint, EndpointConfig, MtuDiscoveryConfig, ServerConfig, Endpoint, EndpointConfig, MtuDiscoveryConfig, ServerConfig, TokioRuntime, TransportConfig,
TransportConfig,
}; };
use quinn_proto::{ConnectionStats, FrameStats, PathStats, UdpStats}; use quinn_proto::{ConnectionStats, FrameStats, PathStats, UdpStats};
use std::error::Error; use std::error::Error;
@ -209,6 +208,8 @@ impl rustls::client::danger::ServerCertVerifier for SkipServerVerification {
} }
fn configure_client(ep_config: &QuinnQuicEndpointConfig) -> Result<ClientConfig, Box<dyn Error>> { fn configure_client(ep_config: &QuinnQuicEndpointConfig) -> Result<ClientConfig, Box<dyn Error>> {
let ring_provider = rustls::crypto::ring::default_provider();
let mut crypto = if ep_config.secure_conn { let mut crypto = if ep_config.secure_conn {
let (certs, key) = read_certs_from_file( let (certs, key) = read_certs_from_file(
ep_config.certificate_file.clone(), ep_config.certificate_file.clone(),
@ -217,11 +218,15 @@ fn configure_client(ep_config: &QuinnQuicEndpointConfig) -> Result<ClientConfig,
let mut cert_store = rustls::RootCertStore::empty(); let mut cert_store = rustls::RootCertStore::empty();
cert_store.add_parsable_certificates(certs.clone()); cert_store.add_parsable_certificates(certs.clone());
rustls::ClientConfig::builder() rustls::ClientConfig::builder_with_provider(ring_provider.into())
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_root_certificates(Arc::new(cert_store)) .with_root_certificates(Arc::new(cert_store))
.with_client_auth_cert(certs, key)? .with_client_auth_cert(certs, key)?
} else { } else {
rustls::ClientConfig::builder() rustls::ClientConfig::builder_with_provider(ring_provider.into())
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.dangerous() .dangerous()
.with_custom_certificate_verifier(SkipServerVerification::new()) .with_custom_certificate_verifier(SkipServerVerification::new())
.with_no_client_auth() .with_no_client_auth()
@ -340,18 +345,28 @@ fn configure_server(
(cert_chain, priv_key) (cert_chain, priv_key)
}; };
let ring_provider = rustls::crypto::ring::default_provider();
let mut crypto = if ep_config.secure_conn { let mut crypto = if ep_config.secure_conn {
let mut cert_store = rustls::RootCertStore::empty(); let mut cert_store = rustls::RootCertStore::empty();
cert_store.add_parsable_certificates(certs.clone()); cert_store.add_parsable_certificates(certs.clone());
let auth_client = rustls::server::WebPkiClientVerifier::builder(Arc::new(cert_store)) let auth_client = rustls::server::WebPkiClientVerifier::builder_with_provider(
.build() Arc::new(cert_store),
.unwrap(); ring_provider.clone().into(),
rustls::ServerConfig::builder() )
.build()
.unwrap();
rustls::ServerConfig::builder_with_provider(ring_provider.into())
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_client_cert_verifier(auth_client) .with_client_cert_verifier(auth_client)
.with_single_cert(certs.clone(), key) .with_single_cert(certs.clone(), key)
} else { } else {
rustls::ServerConfig::builder() rustls::ServerConfig::builder_with_provider(ring_provider.into())
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_no_client_auth() .with_no_client_auth()
.with_single_cert(certs.clone(), key) .with_single_cert(certs.clone(), key)
}?; }?;
@ -394,13 +409,16 @@ fn configure_server(
pub fn server_endpoint(ep_config: &QuinnQuicEndpointConfig) -> Result<Endpoint, Box<dyn Error>> { pub fn server_endpoint(ep_config: &QuinnQuicEndpointConfig) -> Result<Endpoint, Box<dyn Error>> {
let (server_config, _) = configure_server(ep_config)?; let (server_config, _) = configure_server(ep_config)?;
let socket = std::net::UdpSocket::bind(ep_config.server_addr)?; let socket = std::net::UdpSocket::bind(ep_config.server_addr)?;
let runtime = default_runtime()
.ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "No async runtime found"))?;
let endpoint_config = EndpointConfig::default() let endpoint_config = EndpointConfig::default()
.max_udp_payload_size(ep_config.transport_config.max_udp_payload_size) .max_udp_payload_size(ep_config.transport_config.max_udp_payload_size)
.unwrap() .unwrap()
.to_owned(); .to_owned();
let endpoint = Endpoint::new(endpoint_config, Some(server_config), socket, runtime)?; let endpoint = Endpoint::new(
endpoint_config,
Some(server_config),
socket,
Arc::new(TokioRuntime),
)?;
Ok(endpoint) Ok(endpoint)
} }

View file

@ -18,9 +18,6 @@ fn init() {
INIT.call_once(|| { INIT.call_once(|| {
gst::init().unwrap(); gst::init().unwrap();
gstquinn::plugin_register_static().expect("QUIC source sink send receive tests"); gstquinn::plugin_register_static().expect("QUIC source sink send receive tests");
rustls::crypto::ring::default_provider()
.install_default()
.expect("Failed to install ring crypto provider");
}); });
} }