From 13c3db785755cfa54743cd82739ab40938695406 Mon Sep 17 00:00:00 2001 From: Tamas Levai Date: Thu, 9 May 2024 13:49:33 +0200 Subject: [PATCH] net/quinn: Port to quinn 0.11 and rustls 0.23 Co-authored-by: Felician Nemeth Part-of: --- Cargo.lock | 208 ++++++++++++++++++++--------- net/quinn/Cargo.toml | 9 +- net/quinn/src/quinnquicsink/imp.rs | 23 +--- net/quinn/src/utils.rs | 119 +++++++++++------ 4 files changed, 236 insertions(+), 123 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 163a0b7c..4c3750a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/net/quinn/Cargo.toml b/net/quinn/Cargo.toml index 30e5383c..9e7faf6f 100644 --- a/net/quinn/Cargo.toml +++ b/net/quinn/Cargo.toml @@ -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" diff --git a/net/quinn/src/quinnquicsink/imp.rs b/net/quinn/src/quinnquicsink/imp.rs index c1aa730f..2fac3429 100644 --- a/net/quinn/src/quinnquicsink/imp.rs +++ b/net/quinn/src/quinnquicsink/imp.rs @@ -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()); diff --git a/net/quinn/src/utils.rs b/net/quinn/src/utils.rs index 775d783e..ecd5792c 100644 --- a/net/quinn/src/utils.rs +++ b/net/quinn/src/utils.rs @@ -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 { /* * 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, + _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 { - Ok(rustls::client::ServerCertVerified::assertion()) + _now: rustls::pki_types::UnixTime, + ) -> Result { + Ok(rustls::client::danger::ServerCertVerified::assertion()) + } + + fn verify_tls12_signature( + &self, + _: &[u8], + _: &rustls_pki_types::CertificateDer<'_>, + _: &rustls::DigitallySignedStruct, + ) -> Result { + Ok(rustls::client::danger::HandshakeSignatureValid::assertion()) + } + + fn verify_tls13_signature( + &self, + _: &[u8], + _: &rustls_pki_types::CertificateDer<'_>, + _: &rustls::DigitallySignedStruct, + ) -> Result { + Ok(rustls::client::danger::HandshakeSignatureValid::assertion()) + } + + fn supported_verify_schemes(&self) -> Vec { + 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, private_key_file: Option, -) -> Result<(Vec, rustls::PrivateKey), Box> { +) -> Result< + ( + Vec>, + rustls_pki_types::PrivateKeyDer<'static>, + ), + Box, +> { /* * 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 = { + let certs: Vec> = { 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, private_key_file: Option, alpns: Vec, -) -> Result<(ServerConfig, Vec), Box> { +) -> Result<(ServerConfig, Vec), Box> { 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::>(); 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()