Skip to content

Commit

Permalink
net/quinn: Specify crypto provider explicitly
Browse files Browse the repository at this point in the history
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.
rustls/rustls#1877
seanmonstar/reqwest#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>
  • Loading branch information
SanchayanMaity committed Oct 23, 2024
1 parent dc1d634 commit af54b23
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 94 deletions.
76 changes: 1 addition & 75 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions net/quinn/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ gst.workspace = true
gst-base.workspace = true
tokio = { version = "1.36.0", default-features = false, features = ["time", "rt-multi-thread"] }
futures = "0.3.30"
quinn = { version = "0.11.2", default-features = true, features = ["ring"]}
quinn-proto = "0.11.2"
rustls = { version = "0.23", default-features = false, features = ["ring", "std"]}
quinn = { version = "0.11.5", default-features = false, features = ["ring", "rustls", "runtime-tokio"] }
quinn-proto ={ version = "0.11.8", default-features = false, features = ["rustls"] }
rustls = { version = "0.23", default-features = false, features = ["std"] }
rustls-pemfile = "2"
rustls-pki-types = "1"
rcgen = "0.13"
Expand Down
44 changes: 31 additions & 13 deletions net/quinn/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ use futures::future;
use futures::prelude::*;
use gst::ErrorMessage;
use quinn::{
crypto::rustls::QuicClientConfig, crypto::rustls::QuicServerConfig, default_runtime,
ClientConfig, Connection, Endpoint, EndpointConfig, MtuDiscoveryConfig, ServerConfig,
TransportConfig,
crypto::rustls::QuicClientConfig, crypto::rustls::QuicServerConfig, ClientConfig, Connection,
Endpoint, EndpointConfig, MtuDiscoveryConfig, ServerConfig, TokioRuntime, TransportConfig,
};
use quinn_proto::{ConnectionStats, FrameStats, PathStats, UdpStats};
use std::error::Error;
Expand Down Expand Up @@ -209,6 +208,8 @@ impl rustls::client::danger::ServerCertVerifier for SkipServerVerification {
}

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 (certs, key) = read_certs_from_file(
ep_config.certificate_file.clone(),
Expand All @@ -217,11 +218,15 @@ fn configure_client(ep_config: &QuinnQuicEndpointConfig) -> Result<ClientConfig,
let mut cert_store = rustls::RootCertStore::empty();
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_client_auth_cert(certs, key)?
} else {
rustls::ClientConfig::builder()
rustls::ClientConfig::builder_with_provider(ring_provider.into())
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.dangerous()
.with_custom_certificate_verifier(SkipServerVerification::new())
.with_no_client_auth()
Expand Down Expand Up @@ -340,18 +345,28 @@ fn configure_server(
(cert_chain, priv_key)
};

let ring_provider = rustls::crypto::ring::default_provider();

let mut crypto = if ep_config.secure_conn {
let mut cert_store = rustls::RootCertStore::empty();
cert_store.add_parsable_certificates(certs.clone());

let auth_client = rustls::server::WebPkiClientVerifier::builder(Arc::new(cert_store))
.build()
.unwrap();
rustls::ServerConfig::builder()
let auth_client = rustls::server::WebPkiClientVerifier::builder_with_provider(
Arc::new(cert_store),
ring_provider.clone().into(),
)
.build()
.unwrap();

rustls::ServerConfig::builder_with_provider(ring_provider.into())
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_client_cert_verifier(auth_client)
.with_single_cert(certs.clone(), key)
} else {
rustls::ServerConfig::builder()
rustls::ServerConfig::builder_with_provider(ring_provider.into())
.with_protocol_versions(&[&rustls::version::TLS13])
.unwrap()
.with_no_client_auth()
.with_single_cert(certs.clone(), key)
}?;
Expand Down Expand Up @@ -394,13 +409,16 @@ fn configure_server(
pub fn server_endpoint(ep_config: &QuinnQuicEndpointConfig) -> Result<Endpoint, Box<dyn Error>> {
let (server_config, _) = configure_server(ep_config)?;
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()
.max_udp_payload_size(ep_config.transport_config.max_udp_payload_size)
.unwrap()
.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)
}
Expand Down
3 changes: 0 additions & 3 deletions net/quinn/tests/quinnquic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ fn init() {
INIT.call_once(|| {
gst::init().unwrap();
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");
});
}

Expand Down

0 comments on commit af54b23

Please sign in to comment.