net/quinn: Port to quinn 0.11 and rustls 0.23

Co-authored-by: Felician Nemeth <nemethf@tmit.bme.hu>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1565>
This commit is contained in:
Tamas Levai 2024-05-09 13:49:33 +02:00
parent 2b7488a4c8
commit 13c3db7857
4 changed files with 236 additions and 123 deletions

208
Cargo.lock generated
View file

@ -352,7 +352,7 @@ dependencies = [
"hex",
"http 0.2.12",
"hyper 0.14.28",
"ring 0.17.8",
"ring",
"time",
"tokio",
"tracing",
@ -611,7 +611,7 @@ dependencies = [
"once_cell",
"p256",
"percent-encoding",
"ring 0.17.8",
"ring",
"sha2",
"subtle",
"time",
@ -723,7 +723,7 @@ dependencies = [
"once_cell",
"pin-project-lite",
"pin-utils",
"rustls",
"rustls 0.21.11",
"tokio",
"tracing",
]
@ -1046,6 +1046,12 @@ dependencies = [
"thiserror",
]
[[package]]
name = "cesu8"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
[[package]]
name = "cfg-expr"
version = "0.15.8"
@ -1159,6 +1165,16 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "combine"
version = "4.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
dependencies = [
"bytes",
"memchr",
]
[[package]]
name = "concurrent-queue"
version = "2.4.0"
@ -1744,7 +1760,7 @@ dependencies = [
"futures-core",
"futures-sink",
"nanorand",
"spin 0.9.8",
"spin",
]
[[package]]
@ -2654,8 +2670,9 @@ dependencies = [
"once_cell",
"quinn",
"rcgen",
"rustls",
"rustls-pemfile 1.0.4",
"rustls 0.23.5",
"rustls-pemfile 2.1.2",
"rustls-pki-types",
"serial_test",
"thiserror",
"tokio",
@ -3856,8 +3873,8 @@ dependencies = [
"http 0.2.12",
"hyper 0.14.28",
"log",
"rustls",
"rustls-native-certs",
"rustls 0.21.11",
"rustls-native-certs 0.6.3",
"tokio",
"tokio-rustls",
]
@ -4107,6 +4124,26 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "jobserver"
version = "0.1.31"
@ -4133,7 +4170,7 @@ checksum = "5c7ea04a7c5c055c175f189b6dc6ba036fd62306b58c66c9f6389036c503a3f4"
dependencies = [
"base64 0.21.7",
"js-sys",
"ring 0.17.8",
"ring",
"serde",
"serde_json",
]
@ -4626,7 +4663,7 @@ dependencies = [
"log",
"memchr",
"mime",
"spin 0.9.8",
"spin",
"version_check",
]
@ -5391,16 +5428,16 @@ dependencies = [
[[package]]
name = "quinn"
version = "0.10.2"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75"
checksum = "4bb80dc034523335a9fcc34271931dd97e9132d1fb078695db500339eb72e712"
dependencies = [
"bytes",
"pin-project-lite",
"quinn-proto",
"quinn-udp",
"rustc-hash",
"rustls",
"rustls 0.23.5",
"thiserror",
"tokio",
"tracing",
@ -5408,16 +5445,16 @@ dependencies = [
[[package]]
name = "quinn-proto"
version = "0.10.6"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a"
checksum = "a063a47a1aaee4b3b1c2dd44edb7867c10107a2ef171f3543ac40ec5e9092002"
dependencies = [
"bytes",
"rand",
"ring 0.16.20",
"ring",
"rustc-hash",
"rustls",
"rustls-native-certs",
"rustls 0.23.5",
"rustls-platform-verifier",
"slab",
"thiserror",
"tinyvec",
@ -5426,15 +5463,15 @@ dependencies = [
[[package]]
name = "quinn-udp"
version = "0.4.1"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7"
checksum = "cb7ad7bc932e4968523fa7d9c320ee135ff779de720e9350fee8728838551764"
dependencies = [
"bytes",
"libc",
"once_cell",
"socket2 0.5.6",
"tracing",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
]
[[package]]
@ -5550,12 +5587,13 @@ dependencies = [
[[package]]
name = "rcgen"
version = "0.12.1"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48406db8ac1f3cbc7dcdb56ec355343817958a356ff430259bb07baf7607e1e1"
checksum = "54077e1872c46788540de1ea3d7f4ccb1983d12f9aa909b234468676c1a36779"
dependencies = [
"pem",
"ring 0.17.8",
"ring",
"rustls-pki-types",
"time",
"yasna",
]
@ -5734,21 +5772,6 @@ dependencies = [
"bytemuck",
]
[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
dependencies = [
"cc",
"libc",
"once_cell",
"spin 0.5.2",
"untrusted 0.7.1",
"web-sys",
"winapi",
]
[[package]]
name = "ring"
version = "0.17.8"
@ -5759,8 +5782,8 @@ dependencies = [
"cfg-if",
"getrandom",
"libc",
"spin 0.9.8",
"untrusted 0.9.0",
"spin",
"untrusted",
"windows-sys 0.52.0",
]
@ -5875,11 +5898,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4"
dependencies = [
"log",
"ring 0.17.8",
"rustls-webpki",
"ring",
"rustls-webpki 0.101.7",
"sct",
]
[[package]]
name = "rustls"
version = "0.23.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afabcee0551bd1aa3e18e5adbf2c0544722014b899adb31bd186ec638d3da97e"
dependencies = [
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki 0.102.3",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-native-certs"
version = "0.6.3"
@ -5892,6 +5929,19 @@ dependencies = [
"security-framework",
]
[[package]]
name = "rustls-native-certs"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792"
dependencies = [
"openssl-probe",
"rustls-pemfile 2.1.2",
"rustls-pki-types",
"schannel",
"security-framework",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
@ -5917,14 +5967,52 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54"
[[package]]
name = "rustls-platform-verifier"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5f0d26fa1ce3c790f9590868f0109289a044acb954525f933e2aa3b871c157d"
dependencies = [
"core-foundation",
"core-foundation-sys",
"jni",
"log",
"once_cell",
"rustls 0.23.5",
"rustls-native-certs 0.7.0",
"rustls-platform-verifier-android",
"rustls-webpki 0.102.3",
"security-framework",
"security-framework-sys",
"webpki-roots",
"winapi",
]
[[package]]
name = "rustls-platform-verifier-android"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84e217e7fdc8466b5b35d30f8c0a30febd29173df4a3a0c2115d306b9c4117ad"
[[package]]
name = "rustls-webpki"
version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [
"ring 0.17.8",
"untrusted 0.9.0",
"ring",
"untrusted",
]
[[package]]
name = "rustls-webpki"
version = "0.102.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3bce581c0dd41bce533ce695a1437fa16a7ab5ac3ccfa99fe1a620a7885eabf"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
@ -5978,8 +6066,8 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
"ring 0.17.8",
"untrusted 0.9.0",
"ring",
"untrusted",
]
[[package]]
@ -6022,6 +6110,7 @@ dependencies = [
"core-foundation",
"core-foundation-sys",
"libc",
"num-bigint",
"security-framework-sys",
]
@ -6323,12 +6412,6 @@ dependencies = [
"serde",
]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spin"
version = "0.9.8"
@ -6644,7 +6727,7 @@ version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
dependencies = [
"rustls",
"rustls 0.21.11",
"tokio",
]
@ -6938,12 +7021,6 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "untrusted"
version = "0.9.0"
@ -7191,6 +7268,15 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webpki-roots"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "weezl"
version = "0.1.8"

View file

@ -16,10 +16,11 @@ gst-base.workspace = true
once_cell.workspace = true
tokio = { version = "1.36.0", default-features = false, features = ["time", "rt-multi-thread"] }
futures = "0.3.30"
quinn = "0.10.2"
rustls = { version = "0.21.8", default-features = false, features = ["dangerous_configuration", "quic"] }
rustls-pemfile = "1.0.3"
rcgen = "0.12.1"
quinn = { version = "0.11", default-features = true, features = ["ring"]}
rustls = { version = "0.23", default-features = false, features = ["ring", "std"]}
rustls-pemfile = "2"
rustls-pki-types = "1"
rcgen = "0.13"
bytes = "1.5.0"
thiserror = "1"

View file

@ -377,7 +377,6 @@ impl BaseSinkImpl for QuinnQuicSink {
fn stop(&self) -> Result<(), gst::ErrorMessage> {
let settings = self.settings.lock().unwrap();
let timeout = settings.timeout;
let use_datagram = settings.use_datagram;
drop(settings);
@ -385,30 +384,14 @@ impl BaseSinkImpl for QuinnQuicSink {
if let State::Started(ref mut state) = *state {
let connection = &state.connection;
let mut close_msg = CONNECTION_CLOSE_MSG.to_string();
let close_msg = CONNECTION_CLOSE_MSG.to_string();
if !use_datagram {
let send = &mut state.stream.as_mut().unwrap();
// Shutdown stream gracefully
match wait(&self.canceller, send.finish(), timeout) {
Ok(r) => {
if let Err(e) = r {
close_msg = format!("Stream finish request error: {}", e);
gst::error!(CAT, imp: self, "{}", close_msg);
}
}
Err(e) => match e {
WaitError::FutureAborted => {
close_msg = "Stream finish request aborted".to_string();
gst::warning!(CAT, imp: self, "{}", close_msg);
}
WaitError::FutureError(e) => {
close_msg = format!("Stream finish request future error: {}", e);
gst::error!(CAT, imp: self, "{}", close_msg);
}
},
};
// This may fail, but the error is harmless.
let _ = send.finish();
}
connection.close(CONNECTION_CLOSE_CODE.into(), close_msg.as_bytes());

View file

@ -11,7 +11,10 @@ use futures::future;
use futures::prelude::*;
use gst::ErrorMessage;
use once_cell::sync::Lazy;
use quinn::{ClientConfig, Endpoint, ServerConfig};
use quinn::{
crypto::rustls::QuicClientConfig, crypto::rustls::QuicServerConfig, ClientConfig, Endpoint,
ServerConfig,
};
use std::error::Error;
use std::fs::File;
use std::io::BufReader;
@ -114,6 +117,7 @@ pub fn make_socket_addr(addr: &str) -> Result<SocketAddr, WaitError> {
/*
* Following functions are taken from Quinn documentation/repository
*/
#[derive(Debug)]
struct SkipServerVerification;
impl SkipServerVerification {
@ -122,17 +126,52 @@ impl SkipServerVerification {
}
}
impl rustls::client::ServerCertVerifier for SkipServerVerification {
impl rustls::client::danger::ServerCertVerifier for SkipServerVerification {
fn verify_server_cert(
&self,
_end_entity: &rustls::Certificate,
_intermediates: &[rustls::Certificate],
_server_name: &rustls::ServerName,
_scts: &mut dyn Iterator<Item = &[u8]>,
_end_entity: &rustls_pki_types::CertificateDer,
_intermediates: &[rustls_pki_types::CertificateDer],
_server_name: &rustls::pki_types::ServerName,
_ocsp_response: &[u8],
_now: std::time::SystemTime,
) -> Result<rustls::client::ServerCertVerified, rustls::Error> {
Ok(rustls::client::ServerCertVerified::assertion())
_now: rustls::pki_types::UnixTime,
) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
Ok(rustls::client::danger::ServerCertVerified::assertion())
}
fn verify_tls12_signature(
&self,
_: &[u8],
_: &rustls_pki_types::CertificateDer<'_>,
_: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
}
fn verify_tls13_signature(
&self,
_: &[u8],
_: &rustls_pki_types::CertificateDer<'_>,
_: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
}
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
vec![
rustls::SignatureScheme::RSA_PKCS1_SHA1,
rustls::SignatureScheme::ECDSA_SHA1_Legacy,
rustls::SignatureScheme::RSA_PKCS1_SHA256,
rustls::SignatureScheme::ECDSA_NISTP256_SHA256,
rustls::SignatureScheme::RSA_PKCS1_SHA384,
rustls::SignatureScheme::ECDSA_NISTP384_SHA384,
rustls::SignatureScheme::RSA_PKCS1_SHA512,
rustls::SignatureScheme::ECDSA_NISTP521_SHA512,
rustls::SignatureScheme::RSA_PSS_SHA256,
rustls::SignatureScheme::RSA_PSS_SHA384,
rustls::SignatureScheme::RSA_PSS_SHA512,
rustls::SignatureScheme::ED25519,
rustls::SignatureScheme::ED448,
]
}
}
@ -145,18 +184,14 @@ fn configure_client(
let mut crypto = if secure_conn {
let (certs, key) = read_certs_from_file(certificate_file, private_key_file)?;
let mut cert_store = rustls::RootCertStore::empty();
for cert in &certs {
cert_store.add(cert)?;
}
cert_store.add_parsable_certificates(certs.clone());
rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(Arc::new(cert_store))
.with_client_auth_cert(certs, key)?
} else {
rustls::ClientConfig::builder()
.with_safe_defaults()
.dangerous()
.with_custom_certificate_verifier(SkipServerVerification::new())
.with_no_client_auth()
};
@ -168,13 +203,21 @@ fn configure_client(
crypto.alpn_protocols = alpn_protocols;
crypto.key_log = Arc::new(rustls::KeyLogFile::new());
Ok(ClientConfig::new(Arc::new(crypto)))
Ok(ClientConfig::new(Arc::new(QuicClientConfig::try_from(
crypto,
)?)))
}
fn read_certs_from_file(
certificate_file: Option<PathBuf>,
private_key_file: Option<PathBuf>,
) -> Result<(Vec<rustls::Certificate>, rustls::PrivateKey), Box<dyn Error>> {
) -> Result<
(
Vec<rustls_pki_types::CertificateDer<'static>>,
rustls_pki_types::PrivateKeyDer<'static>,
),
Box<dyn Error>,
> {
/*
* NOTE:
*
@ -194,26 +237,27 @@ fn read_certs_from_file(
.expect("Expected path to certificates be valid");
let key_file = private_key_file.expect("Expected path to certificates be valid");
let certs: Vec<rustls::Certificate> = {
let certs: Vec<rustls_pki_types::CertificateDer<'static>> = {
let cert_file = File::open(cert_file.as_path())?;
let mut cert_file_rdr = BufReader::new(cert_file);
let cert_vec = rustls_pemfile::certs(&mut cert_file_rdr)?;
cert_vec.into_iter().map(rustls::Certificate).collect()
let cert_vec = rustls_pemfile::certs(&mut cert_file_rdr);
cert_vec.into_iter().map(|c| c.unwrap()).collect()
};
let key: rustls::PrivateKey = {
let key: rustls_pki_types::PrivateKeyDer<'static> = {
let key_file = File::open(key_file.as_path())?;
let mut key_file_rdr = BufReader::new(key_file);
let keys_iter = rustls_pemfile::read_all(&mut key_file_rdr)?;
let keys_iter = rustls_pemfile::read_all(&mut key_file_rdr);
let key_item = keys_iter
.into_iter()
.map(|c| c.unwrap())
.next()
.ok_or("Certificate should have at least one private key")?;
match key_item {
rustls_pemfile::Item::RSAKey(key) => rustls::PrivateKey(key),
rustls_pemfile::Item::PKCS8Key(key) => rustls::PrivateKey(key),
rustls_pemfile::Item::Pkcs1Key(key) => rustls_pki_types::PrivateKeyDer::from(key),
rustls_pemfile::Item::Pkcs8Key(key) => rustls_pki_types::PrivateKeyDer::from(key),
_ => unimplemented!(),
}
};
@ -227,33 +271,31 @@ fn configure_server(
certificate_file: Option<PathBuf>,
private_key_file: Option<PathBuf>,
alpns: Vec<String>,
) -> Result<(ServerConfig, Vec<rustls::Certificate>), Box<dyn Error>> {
) -> Result<(ServerConfig, Vec<rustls_pki_types::CertificateDer>), Box<dyn Error>> {
let (certs, key) = if secure_conn {
read_certs_from_file(certificate_file, private_key_file)?
} else {
let cert = rcgen::generate_simple_self_signed(vec![server_name.into()]).unwrap();
let cert_der = cert.serialize_der().unwrap();
let priv_key = cert.serialize_private_key_der();
let priv_key = rustls::PrivateKey(priv_key);
let cert_chain = vec![rustls::Certificate(cert_der)];
let rcgen::CertifiedKey { cert: _, key_pair } =
rcgen::generate_simple_self_signed(vec![server_name.into()]).unwrap();
let cert_der = key_pair.serialize_der();
let priv_key = rustls_pki_types::PrivateKeyDer::try_from(cert_der.clone()).unwrap();
let cert_chain = vec![rustls_pki_types::CertificateDer::from(cert_der)];
(cert_chain, priv_key)
};
let mut crypto = if secure_conn {
let mut cert_store = rustls::RootCertStore::empty();
for cert in &certs {
cert_store.add(cert)?;
}
cert_store.add_parsable_certificates(certs.clone());
let auth_client = rustls::server::AllowAnyAuthenticatedClient::new(cert_store);
let auth_client = rustls::server::WebPkiClientVerifier::builder(Arc::new(cert_store))
.build()
.unwrap();
rustls::ServerConfig::builder()
.with_safe_defaults()
.with_client_cert_verifier(Arc::new(auth_client))
.with_client_cert_verifier(auth_client)
.with_single_cert(certs.clone(), key)
} else {
rustls::ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(certs.clone(), key)
}?;
@ -264,7 +306,8 @@ fn configure_server(
.collect::<Vec<_>>();
crypto.alpn_protocols = alpn_protocols;
crypto.key_log = Arc::new(rustls::KeyLogFile::new());
let mut server_config = ServerConfig::with_crypto(Arc::new(crypto));
let mut server_config =
ServerConfig::with_crypto(Arc::new(QuicServerConfig::try_from(crypto)?));
Arc::get_mut(&mut server_config.transport)
.unwrap()