use std::fs::File; use std::io::BufReader; use std::path::Path; use std::sync::Arc; use quinn::Endpoint; use quinn::crypto::rustls::QuicClientConfig; use rustls::crypto::CryptoProvider; use rustls::crypto::ring; use rustls::pki_types::CertificateDer; use rustls::pki_types::PrivateKeyDer; use rustls::pki_types::ServerName; use rustls_pemfile::{certs, pkcs8_private_keys, private_key}; pub fn quic_init() -> Endpoint { let default_provider = ring::default_provider(); CryptoProvider::install_default(default_provider).unwrap(); let certificate_chain = load_certs_from_pem("./ca/ca.crt").unwrap(); let mut root_store = rustls::RootCertStore::empty(); for cert in certificate_chain { root_store.add(cert).unwrap(); } let mut rustls_config = rustls::ClientConfig::builder() .dangerous() .with_custom_certificate_verifier(Arc::new(SkipServerVerification{})) .with_no_client_auth(); rustls_config.alpn_protocols = vec![b"punchnet/1.0".to_vec()]; let quinn_client_config = quinn::ClientConfig::new(Arc::new(QuicClientConfig::try_from(rustls_config).unwrap())); let mut endpoint = Endpoint::client("0.0.0.0:0".parse().unwrap()).unwrap(); endpoint.set_default_client_config(quinn_client_config); endpoint } #[derive(Debug)] struct SkipServerVerification; impl rustls::client::danger::ServerCertVerifier for SkipServerVerification { fn verify_server_cert(&self, _: &CertificateDer<'_>, _: &[CertificateDer<'_>], _: &ServerName<'_>, _: &[u8], _: rustls::pki_types::UnixTime) -> Result { Ok(rustls::client::danger::ServerCertVerified::assertion()) } fn verify_tls12_signature(&self, _: &[u8], _: &CertificateDer<'_>, _: &rustls::DigitallySignedStruct) -> Result { Ok(rustls::client::danger::HandshakeSignatureValid::assertion()) } fn verify_tls13_signature(&self, _: &[u8], _: &CertificateDer<'_>, _: &rustls::DigitallySignedStruct) -> Result { Ok(rustls::client::danger::HandshakeSignatureValid::assertion()) } fn supported_verify_schemes(&self) -> Vec { rustls::crypto::ring::default_provider().signature_verification_algorithms.supported_schemes() } } pub fn load_certs_from_pem(path: impl AsRef) -> Result>, Box> { let file = File::open(path.as_ref())?; let mut reader = BufReader::new(file); let certs = certs(&mut reader) .into_iter() .map(|it| it.unwrap()) .collect::>(); Ok(certs) } pub fn load_private_key_from_pem(path: impl AsRef) -> Option>{ let Ok(file) = File::open(path.as_ref()) else { return None; }; let mut reader = BufReader::new(file); let key = private_key(&mut reader).unwrap(); key }