net/quic: Drop private key type property

Use read_all helper from rustls_pemfile and drop the requirement for the
user having to specify the private key type.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1036>
This commit is contained in:
Sanchayan Maity 2024-05-01 11:41:08 +05:30
parent a306b1ce94
commit 97d8a79d36
3 changed files with 19 additions and 65 deletions

View file

@ -7,7 +7,6 @@
// //
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use super::QuicPrivateKeyType;
use crate::utils::{ use crate::utils::{
make_socket_addr, server_endpoint, wait, WaitError, CONNECTION_CLOSE_CODE, CONNECTION_CLOSE_MSG, make_socket_addr, server_endpoint, wait, WaitError, CONNECTION_CLOSE_CODE, CONNECTION_CLOSE_MSG,
}; };
@ -36,7 +35,6 @@ static DEFAULT_SERVER_PORT: u16 = 5000;
*/ */
const DEFAULT_ALPN: &str = "gst-quinn"; const DEFAULT_ALPN: &str = "gst-quinn";
const DEFAULT_TIMEOUT: u32 = 15; const DEFAULT_TIMEOUT: u32 = 15;
const DEFAULT_PRIVATE_KEY_TYPE: QuicPrivateKeyType = QuicPrivateKeyType::Pkcs8;
const DEFAULT_SECURE_CONNECTION: bool = true; const DEFAULT_SECURE_CONNECTION: bool = true;
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| { static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
@ -70,7 +68,6 @@ struct Settings {
caps: gst::Caps, caps: gst::Caps,
use_datagram: bool, use_datagram: bool,
certificate_path: Option<PathBuf>, certificate_path: Option<PathBuf>,
private_key_type: QuicPrivateKeyType,
} }
impl Default for Settings { impl Default for Settings {
@ -85,7 +82,6 @@ impl Default for Settings {
caps: gst::Caps::new_any(), caps: gst::Caps::new_any(),
use_datagram: false, use_datagram: false,
certificate_path: None, certificate_path: None,
private_key_type: DEFAULT_PRIVATE_KEY_TYPE,
} }
} }
} }
@ -111,8 +107,6 @@ impl GstObjectImpl for QuinnQuicSrc {}
impl ElementImpl for QuinnQuicSrc { impl ElementImpl for QuinnQuicSrc {
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> { fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| { static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
#[cfg(feature = "doc")]
QuicPrivateKeyType::static_type().mark_as_plugin_api(gst::PluginAPIFlags::empty());
gst::subclass::ElementMetadata::new( gst::subclass::ElementMetadata::new(
"Quinn QUIC Source", "Quinn QUIC Source",
"Source/Network/QUIC", "Source/Network/QUIC",
@ -218,10 +212,6 @@ impl ObjectImpl for QuinnQuicSrc {
.blurb("Use datagram for lower latency, unreliable messaging") .blurb("Use datagram for lower latency, unreliable messaging")
.default_value(false) .default_value(false)
.build(), .build(),
glib::ParamSpecEnum::builder_with_default::<QuicPrivateKeyType>("private-key-type", DEFAULT_PRIVATE_KEY_TYPE)
.nick("Whether PKCS8 or RSA key type is considered for private key")
.blurb("Read given private key as PKCS8 or RSA")
.build(),
] ]
}); });
@ -276,11 +266,6 @@ impl ObjectImpl for QuinnQuicSrc {
"use-datagram" => { "use-datagram" => {
settings.use_datagram = value.get().expect("type checked upstream"); settings.use_datagram = value.get().expect("type checked upstream");
} }
"private-key-type" => {
settings.private_key_type = value
.get::<QuicPrivateKeyType>()
.expect("type checked upstream");
}
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
@ -307,7 +292,6 @@ impl ObjectImpl for QuinnQuicSrc {
certpath.and_then(|file| file.to_str()).to_value() certpath.and_then(|file| file.to_str()).to_value()
} }
"use-datagram" => settings.use_datagram.to_value(), "use-datagram" => settings.use_datagram.to_value(),
"private-key-type" => settings.private_key_type.to_value(),
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
@ -537,7 +521,6 @@ impl QuinnQuicSrc {
let use_datagram; let use_datagram;
let secure_conn; let secure_conn;
let cert_path; let cert_path;
let private_key_type;
{ {
let settings = self.settings.lock().unwrap(); let settings = self.settings.lock().unwrap();
@ -551,23 +534,15 @@ impl QuinnQuicSrc {
use_datagram = settings.use_datagram; use_datagram = settings.use_datagram;
secure_conn = settings.secure_conn; secure_conn = settings.secure_conn;
cert_path = settings.certificate_path.clone(); cert_path = settings.certificate_path.clone();
private_key_type = settings.private_key_type;
} }
let endpoint = server_endpoint( let endpoint = server_endpoint(server_addr, &server_name, secure_conn, alpns, cert_path)
server_addr, .map_err(|err| {
&server_name, WaitError::FutureError(gst::error_msg!(
secure_conn, gst::ResourceError::Failed,
alpns, ["Failed to configure endpoint: {}", err]
cert_path, ))
private_key_type, })?;
)
.map_err(|err| {
WaitError::FutureError(gst::error_msg!(
gst::ResourceError::Failed,
["Failed to configure endpoint: {}", err]
))
})?;
let incoming_conn = endpoint.accept().await.unwrap(); let incoming_conn = endpoint.accept().await.unwrap();

View file

@ -12,16 +12,6 @@ use gst::prelude::*;
mod imp; mod imp;
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy, glib::Enum)]
#[repr(u32)]
#[enum_type(name = "GstQuicPrivateKeyType")]
pub enum QuicPrivateKeyType {
#[enum_value(name = "PKCS8: PKCS #8 Private Key.", nick = "pkcs8")]
Pkcs8,
#[enum_value(name = "RSA: RSA Private Key.", nick = "rsa")]
Rsa,
}
glib::wrapper! { glib::wrapper! {
pub struct QuinnQuicSrc(ObjectSubclass<imp::QuinnQuicSrc>) @extends gst_base::BaseSrc, gst::Element, gst::Object; pub struct QuinnQuicSrc(ObjectSubclass<imp::QuinnQuicSrc>) @extends gst_base::BaseSrc, gst::Element, gst::Object;
} }

View file

@ -7,7 +7,6 @@
// //
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use crate::quinnquicsrc::QuicPrivateKeyType;
use futures::future; use futures::future;
use futures::prelude::*; use futures::prelude::*;
use gst::ErrorMessage; use gst::ErrorMessage;
@ -158,7 +157,6 @@ fn configure_client(secure_conn: bool, alpns: Vec<String>) -> Result<ClientConfi
fn read_certs_from_file( fn read_certs_from_file(
certificate_path: Option<PathBuf>, certificate_path: Option<PathBuf>,
private_key_type: QuicPrivateKeyType,
) -> Result<(Vec<rustls::Certificate>, rustls::PrivateKey), Box<dyn Error>> { ) -> Result<(Vec<rustls::Certificate>, rustls::PrivateKey), Box<dyn Error>> {
/* /*
* NOTE: * NOTE:
@ -192,19 +190,18 @@ fn read_certs_from_file(
let key: rustls::PrivateKey = { let key: rustls::PrivateKey = {
let key_file = File::open(key_file.as_path())?; let key_file = File::open(key_file.as_path())?;
let mut key_file_rdr = BufReader::new(key_file); let mut key_file_rdr = BufReader::new(key_file);
let mut key_vec;
// If the file starts with "BEGIN RSA PRIVATE KEY" let keys_iter = rustls_pemfile::read_all(&mut key_file_rdr)?;
if let QuicPrivateKeyType::Rsa = private_key_type { let key_item = keys_iter
key_vec = rustls_pemfile::rsa_private_keys(&mut key_file_rdr)?; .into_iter()
} else { .next()
// If the file starts with "BEGIN PRIVATE KEY" .ok_or("Certificate should have at least one private key")?;
key_vec = rustls_pemfile::pkcs8_private_keys(&mut key_file_rdr)?;
match key_item {
rustls_pemfile::Item::RSAKey(key) => rustls::PrivateKey(key),
rustls_pemfile::Item::PKCS8Key(key) => rustls::PrivateKey(key),
_ => unimplemented!(),
} }
assert_eq!(key_vec.len(), 1);
rustls::PrivateKey(key_vec.remove(0))
}; };
Ok((certs, key)) Ok((certs, key))
@ -215,10 +212,9 @@ fn configure_server(
secure_conn: bool, secure_conn: bool,
certificate_path: Option<PathBuf>, certificate_path: Option<PathBuf>,
alpns: Vec<String>, alpns: Vec<String>,
private_key_type: QuicPrivateKeyType,
) -> Result<(ServerConfig, Vec<rustls::Certificate>), Box<dyn Error>> { ) -> Result<(ServerConfig, Vec<rustls::Certificate>), Box<dyn Error>> {
let (cert, key) = if secure_conn { let (cert, key) = if secure_conn {
read_certs_from_file(certificate_path, private_key_type).unwrap() read_certs_from_file(certificate_path).unwrap()
} else { } else {
let cert = rcgen::generate_simple_self_signed(vec![server_name.into()]).unwrap(); let cert = rcgen::generate_simple_self_signed(vec![server_name.into()]).unwrap();
let cert_der = cert.serialize_der().unwrap(); let cert_der = cert.serialize_der().unwrap();
@ -258,15 +254,8 @@ pub fn server_endpoint(
secure_conn: bool, secure_conn: bool,
alpns: Vec<String>, alpns: Vec<String>,
certificate_path: Option<PathBuf>, certificate_path: Option<PathBuf>,
private_key_type: QuicPrivateKeyType,
) -> Result<Endpoint, Box<dyn Error>> { ) -> Result<Endpoint, Box<dyn Error>> {
let (server_config, _) = configure_server( let (server_config, _) = configure_server(server_name, secure_conn, certificate_path, alpns)?;
server_name,
secure_conn,
certificate_path,
alpns,
private_key_type,
)?;
let endpoint = Endpoint::server(server_config, server_addr)?; let endpoint = Endpoint::server(server_config, server_addr)?;
Ok(endpoint) Ok(endpoint)