2026-02-25 16:06:44 +08:00

77 lines
3.0 KiB
Rust

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<rustls::client::danger::ServerCertVerified, rustls::Error> {
Ok(rustls::client::danger::ServerCertVerified::assertion())
}
fn verify_tls12_signature(&self, _: &[u8], _: &CertificateDer<'_>, _: &rustls::DigitallySignedStruct) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
}
fn verify_tls13_signature(&self, _: &[u8], _: &CertificateDer<'_>, _: &rustls::DigitallySignedStruct) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
}
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
rustls::crypto::ring::default_provider().signature_verification_algorithms.supported_schemes()
}
}
pub fn load_certs_from_pem(path: impl AsRef<Path>) -> Result<Vec<CertificateDer<'static>>, Box<dyn std::error::Error>> {
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::<Vec<_>>();
Ok(certs)
}
pub fn load_private_key_from_pem(path: impl AsRef<Path>) -> Option<PrivateKeyDer<'static>>{
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
}