1use std::sync::Arc;
13use std::sync::OnceLock;
14
15use quinn::crypto::rustls::QuicClientConfig;
16use quinn::crypto::rustls::QuicServerConfig;
17use rcgen::CertificateParams;
18use rcgen::KeyPair;
19use rustls::pki_types::CertificateDer;
20use rustls::pki_types::PrivateKeyDer;
21use rustls::pki_types::ServerName;
22use rustls::pki_types::UnixTime;
23
24struct SelfSigned {
26 cert_der: Vec<u8>,
27 key_der: Vec<u8>,
28}
29
30static SELF_SIGNED: OnceLock<SelfSigned> = OnceLock::new();
31
32fn self_signed() -> &'static SelfSigned {
39 SELF_SIGNED.get_or_init(|| {
40 let params = CertificateParams::new(vec!["localhost".to_string()]).expect("valid SAN list");
41 let key_pair = KeyPair::generate().expect("generate ECDSA key pair");
42 let cert = params
43 .self_signed(&key_pair)
44 .expect("self-sign certificate");
45 SelfSigned {
46 cert_der: cert.der().to_vec(),
47 key_der: key_pair.serialize_der(),
48 }
49 })
50}
51
52pub(crate) fn server_config() -> std::result::Result<quinn::ServerConfig, String> {
55 let signed = self_signed();
56 let cert = CertificateDer::from(signed.cert_der.clone());
57 let key = PrivateKeyDer::try_from(signed.key_der.clone())
58 .map_err(|e| format!("decode private key: {e}"))?;
59 let rustls_cfg = rustls::server::ServerConfig::builder()
60 .with_no_client_auth()
61 .with_single_cert(vec![cert], key)
62 .map_err(|e| format!("build rustls server config: {e}"))?;
63 let quic_cfg = QuicServerConfig::try_from(rustls_cfg)
64 .map_err(|e| format!("wrap rustls server config for quinn: {e}"))?;
65 Ok(quinn::ServerConfig::with_crypto(Arc::new(quic_cfg)))
66}
67
68pub(crate) fn client_config() -> std::result::Result<quinn::ClientConfig, String> {
72 let rustls_cfg = rustls::client::ClientConfig::builder()
77 .dangerous()
78 .with_custom_certificate_verifier(Arc::new(NoVerify))
79 .with_no_client_auth();
80 let quic_cfg = QuicClientConfig::try_from(rustls_cfg)
81 .map_err(|e| format!("wrap rustls client config for quinn: {e}"))?;
82 Ok(quinn::ClientConfig::new(Arc::new(quic_cfg)))
83}
84
85#[derive(Debug)]
88struct NoVerify;
89
90impl rustls::client::danger::ServerCertVerifier for NoVerify {
91 fn verify_server_cert(
92 &self,
93 _end_entity: &CertificateDer<'_>,
94 _intermediates: &[CertificateDer<'_>],
95 _server_name: &ServerName<'_>,
96 _ocsp_response: &[u8],
97 _now: UnixTime,
98 ) -> std::result::Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
99 Ok(rustls::client::danger::ServerCertVerified::assertion())
100 }
101
102 fn verify_tls12_signature(
103 &self,
104 _message: &[u8],
105 _cert: &CertificateDer<'_>,
106 _dss: &rustls::DigitallySignedStruct,
107 ) -> std::result::Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
108 Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
109 }
110
111 fn verify_tls13_signature(
112 &self,
113 _message: &[u8],
114 _cert: &CertificateDer<'_>,
115 _dss: &rustls::DigitallySignedStruct,
116 ) -> std::result::Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
117 Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
118 }
119
120 fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
121 vec![
122 rustls::SignatureScheme::ECDSA_NISTP256_SHA256,
123 rustls::SignatureScheme::ECDSA_NISTP384_SHA384,
124 rustls::SignatureScheme::ED25519,
125 rustls::SignatureScheme::RSA_PSS_SHA256,
126 rustls::SignatureScheme::RSA_PSS_SHA384,
127 rustls::SignatureScheme::RSA_PSS_SHA512,
128 ]
129 }
130}