diff --git a/net/quinn/src/quinnquicsink/imp.rs b/net/quinn/src/quinnquicsink/imp.rs index c3770864..888facbd 100644 --- a/net/quinn/src/quinnquicsink/imp.rs +++ b/net/quinn/src/quinnquicsink/imp.rs @@ -68,7 +68,8 @@ struct Settings { timeout: u32, secure_conn: bool, use_datagram: bool, - certificate_path: Option, + certificate_file: Option, + private_key_file: Option, } impl Default for Settings { @@ -83,7 +84,8 @@ impl Default for Settings { timeout: DEFAULT_TIMEOUT, secure_conn: DEFAULT_SECURE_CONNECTION, use_datagram: false, - certificate_path: None, + certificate_file: None, + private_key_file: None, } } } @@ -146,11 +148,13 @@ impl ElementImpl for QuinnQuicSink { * Fail the state change if a secure connection was requested but * no certificate path was provided. */ - if settings.secure_conn && settings.certificate_path.is_none() { + if settings.secure_conn + && (settings.certificate_file.is_none() || settings.private_key_file.is_none()) + { gst::error!( CAT, imp: self, - "Certificate path not provided for secure connection" + "Certificate or private key file not provided for secure connection" ); return Err(gst::StateChangeError); } @@ -211,9 +215,13 @@ impl ObjectImpl for QuinnQuicSink { .blurb("Use certificates for QUIC connection. False: Insecure connection, True: Secure connection.") .default_value(DEFAULT_SECURE_CONNECTION) .build(), - glib::ParamSpecString::builder("certificate-path") - .nick("Certificate Path") - .blurb("Path where the certificate files cert.pem and privkey.pem are stored") + glib::ParamSpecString::builder("certificate-file") + .nick("Certificate file") + .blurb("Path to certificate chain in single file") + .build(), + glib::ParamSpecString::builder("private-key-file") + .nick("Private key file") + .blurb("Path to a PKCS8 or RSA private key file") .build(), glib::ParamSpecBoolean::builder("use-datagram") .nick("Use datagram") @@ -264,9 +272,13 @@ impl ObjectImpl for QuinnQuicSink { "secure-connection" => { settings.secure_conn = value.get().expect("type checked upstream"); } - "certificate-path" => { + "certificate-file" => { let value: String = value.get().unwrap(); - settings.certificate_path = Some(value.into()); + settings.certificate_file = Some(value.into()); + } + "private-key-file" => { + let value: String = value.get().unwrap(); + settings.private_key_file = Some(value.into()); } "use-datagram" => { settings.use_datagram = value.get().expect("type checked upstream"); @@ -296,9 +308,13 @@ impl ObjectImpl for QuinnQuicSink { } "timeout" => settings.timeout.to_value(), "secure-connection" => settings.secure_conn.to_value(), - "certificate-path" => { - let certpath = settings.certificate_path.as_ref(); - certpath.and_then(|file| file.to_str()).to_value() + "certificate-file" => { + let certfile = settings.certificate_file.as_ref(); + certfile.and_then(|file| file.to_str()).to_value() + } + "private-key-file" => { + let privkey = settings.private_key_file.as_ref(); + privkey.and_then(|file| file.to_str()).to_value() } "use-datagram" => settings.use_datagram.to_value(), _ => unimplemented!(), @@ -495,7 +511,8 @@ impl QuinnQuicSink { let alpns; let use_datagram; let secure_conn; - let cert_path; + let cert_file; + let private_key_file; { let settings = self.settings.lock().unwrap(); @@ -511,16 +528,19 @@ impl QuinnQuicSink { alpns = settings.alpns.clone(); use_datagram = settings.use_datagram; secure_conn = settings.secure_conn; - cert_path = settings.certificate_path.clone(); + cert_file = settings.certificate_file.clone(); + private_key_file = settings.private_key_file.clone(); } let endpoint = - client_endpoint(client_addr, secure_conn, alpns, cert_path).map_err(|err| { - WaitError::FutureError(gst::error_msg!( - gst::ResourceError::Failed, - ["Failed to configure endpoint: {}", err] - )) - })?; + client_endpoint(client_addr, secure_conn, alpns, cert_file, private_key_file).map_err( + |err| { + WaitError::FutureError(gst::error_msg!( + gst::ResourceError::Failed, + ["Failed to configure endpoint: {}", err] + )) + }, + )?; let connection = endpoint .connect(server_addr, &server_name) diff --git a/net/quinn/src/quinnquicsrc/imp.rs b/net/quinn/src/quinnquicsrc/imp.rs index 6546fb3b..23f36190 100644 --- a/net/quinn/src/quinnquicsrc/imp.rs +++ b/net/quinn/src/quinnquicsrc/imp.rs @@ -67,7 +67,8 @@ struct Settings { secure_conn: bool, caps: gst::Caps, use_datagram: bool, - certificate_path: Option, + certificate_file: Option, + private_key_file: Option, } impl Default for Settings { @@ -81,7 +82,8 @@ impl Default for Settings { secure_conn: DEFAULT_SECURE_CONNECTION, caps: gst::Caps::new_any(), use_datagram: false, - certificate_path: None, + certificate_file: None, + private_key_file: None, } } } @@ -144,11 +146,13 @@ impl ElementImpl for QuinnQuicSrc { * Fail the state change if a secure connection was requested but * no certificate path was provided. */ - if settings.secure_conn && settings.certificate_path.is_none() { + if settings.secure_conn + && (settings.certificate_file.is_none() || settings.private_key_file.is_none()) + { gst::error!( CAT, imp: self, - "Certificate path not provided for secure connection" + "Certificate or private key file not provided for secure connection" ); return Err(gst::StateChangeError); } @@ -199,9 +203,13 @@ impl ObjectImpl for QuinnQuicSrc { .blurb("Use certificates for QUIC connection. False: Insecure connection, True: Secure connection.") .default_value(DEFAULT_SECURE_CONNECTION) .build(), - glib::ParamSpecString::builder("certificate-path") - .nick("Certificate Path") - .blurb("Path where the certificate files cert.pem and privkey.pem are stored") + glib::ParamSpecString::builder("certificate-file") + .nick("Certificate file") + .blurb("Path to certificate chain in single file") + .build(), + glib::ParamSpecString::builder("private-key-file") + .nick("Private key file") + .blurb("Path to a PKCS8 or RSA private key file") .build(), glib::ParamSpecBoxed::builder::("caps") .nick("caps") @@ -259,9 +267,13 @@ impl ObjectImpl for QuinnQuicSrc { "secure-connection" => { settings.secure_conn = value.get().expect("type checked upstream"); } - "certificate-path" => { + "certificate-file" => { let value: String = value.get().unwrap(); - settings.certificate_path = Some(value.into()); + settings.certificate_file = Some(value.into()); + } + "private-key-file" => { + let value: String = value.get().unwrap(); + settings.private_key_file = Some(value.into()); } "use-datagram" => { settings.use_datagram = value.get().expect("type checked upstream"); @@ -287,9 +299,13 @@ impl ObjectImpl for QuinnQuicSrc { "caps" => settings.caps.to_value(), "timeout" => settings.timeout.to_value(), "secure-connection" => settings.secure_conn.to_value(), - "certificate-path" => { - let certpath = settings.certificate_path.as_ref(); - certpath.and_then(|file| file.to_str()).to_value() + "certificate-file" => { + let certfile = settings.certificate_file.as_ref(); + certfile.and_then(|file| file.to_str()).to_value() + } + "private-key-file" => { + let privkey = settings.private_key_file.as_ref(); + privkey.and_then(|file| file.to_str()).to_value() } "use-datagram" => settings.use_datagram.to_value(), _ => unimplemented!(), @@ -520,7 +536,8 @@ impl QuinnQuicSrc { let alpns; let use_datagram; let secure_conn; - let cert_path; + let cert_file; + let private_key_file; { let settings = self.settings.lock().unwrap(); @@ -533,16 +550,24 @@ impl QuinnQuicSrc { alpns = settings.alpns.clone(); use_datagram = settings.use_datagram; secure_conn = settings.secure_conn; - cert_path = settings.certificate_path.clone(); + cert_file = settings.certificate_file.clone(); + private_key_file = settings.private_key_file.clone(); } - let endpoint = server_endpoint(server_addr, &server_name, secure_conn, alpns, cert_path) - .map_err(|err| { - WaitError::FutureError(gst::error_msg!( - gst::ResourceError::Failed, - ["Failed to configure endpoint: {}", err] - )) - })?; + let endpoint = server_endpoint( + server_addr, + &server_name, + secure_conn, + alpns, + cert_file, + private_key_file, + ) + .map_err(|err| { + WaitError::FutureError(gst::error_msg!( + gst::ResourceError::Failed, + ["Failed to configure endpoint: {}", err] + )) + })?; let incoming_conn = endpoint.accept().await.unwrap(); diff --git a/net/quinn/src/utils.rs b/net/quinn/src/utils.rs index c6ff38b3..775d783e 100644 --- a/net/quinn/src/utils.rs +++ b/net/quinn/src/utils.rs @@ -138,11 +138,12 @@ impl rustls::client::ServerCertVerifier for SkipServerVerification { fn configure_client( secure_conn: bool, - certificate_path: Option, + certificate_file: Option, + private_key_file: Option, alpns: Vec, ) -> Result> { let mut crypto = if secure_conn { - let (certs, key) = read_certs_from_file(certificate_path)?; + let (certs, key) = read_certs_from_file(certificate_file, private_key_file)?; let mut cert_store = rustls::RootCertStore::empty(); for cert in &certs { @@ -171,7 +172,8 @@ fn configure_client( } fn read_certs_from_file( - certificate_path: Option, + certificate_file: Option, + private_key_file: Option, ) -> Result<(Vec, rustls::PrivateKey), Box> { /* * NOTE: @@ -187,13 +189,10 @@ fn read_certs_from_file( * chain in a single file. For example, this is the case of modern day * Apache and nginx. */ - let cert_file = certificate_path + let cert_file = certificate_file .clone() - .expect("Expected path to certificates be valid") - .join("fullchain.pem"); - let key_file = certificate_path - .expect("Expected path to certificates be valid") - .join("privkey.pem"); + .expect("Expected path to certificates be valid"); + let key_file = private_key_file.expect("Expected path to certificates be valid"); let certs: Vec = { let cert_file = File::open(cert_file.as_path())?; @@ -225,11 +224,12 @@ fn read_certs_from_file( fn configure_server( server_name: &str, secure_conn: bool, - certificate_path: Option, + certificate_file: Option, + private_key_file: Option, alpns: Vec, ) -> Result<(ServerConfig, Vec), Box> { let (certs, key) = if secure_conn { - read_certs_from_file(certificate_path)? + 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(); @@ -279,9 +279,16 @@ pub fn server_endpoint( server_name: &str, secure_conn: bool, alpns: Vec, - certificate_path: Option, + certificate_file: Option, + private_key_file: Option, ) -> Result> { - let (server_config, _) = configure_server(server_name, secure_conn, certificate_path, alpns)?; + let (server_config, _) = configure_server( + server_name, + secure_conn, + certificate_file, + private_key_file, + alpns, + )?; let endpoint = Endpoint::server(server_config, server_addr)?; Ok(endpoint) @@ -291,9 +298,10 @@ pub fn client_endpoint( client_addr: SocketAddr, secure_conn: bool, alpns: Vec, - certificate_path: Option, + certificate_file: Option, + private_key_file: Option, ) -> Result> { - let client_cfg = configure_client(secure_conn, certificate_path, alpns)?; + let client_cfg = configure_client(secure_conn, certificate_file, private_key_file, alpns)?; let mut endpoint = Endpoint::client(client_addr)?; endpoint.set_default_client_config(client_cfg);