qs_core/
lib.rs

1use quinn::{crypto::rustls::QuicClientConfig, ClientConfig};
2use rustls::{
3    crypto,
4    pki_types::{CertificateDer, ServerName, UnixTime},
5};
6use std::sync::Arc;
7use thiserror::Error;
8
9pub mod common;
10pub mod packets;
11pub mod receive;
12pub mod send;
13pub mod utils;
14
15pub const BUF_SIZE: usize = 8192;
16pub const SEND_SERVER_NAME: &str = "quic-send";
17pub const KEEP_ALIVE_INTERVAL_SECS: u64 = 5;
18pub const QS_PROTO_VERSION: &str = "0.4.0"; 
19pub const QS_ALPN: &[u8] = b"quic-send/0.4.0";
20
21#[derive(Error, Debug)]
22pub enum QuicSendError {
23    #[error("rcgen error: {0}")]
24    RcGen(#[from] rcgen::Error),
25    #[error("send error: {0}")]
26    Send(#[from] send::SendError),
27    #[error("receive error: {0}")]
28    Receive(#[from] receive::ReceiveError),
29    #[error("bind error: {0}")]
30    Bind(String),
31}
32
33/// Client config that ignores the server certificate
34pub fn unsafe_client_config() -> ClientConfig {
35    let mut binding = rustls::ClientConfig::builder()
36        .with_root_certificates(rustls::RootCertStore::empty())
37        .with_no_client_auth();
38
39    let mut crypto = binding.dangerous();
40
41    crypto.set_certificate_verifier(SkipServerVerification::new(Arc::new(
42        crypto::ring::default_provider(),
43    )));
44
45    ClientConfig::new(Arc::new(
46        QuicClientConfig::try_from(crypto.cfg.to_owned()).unwrap(),
47    ))
48}
49
50/// Implementation of `ServerCertVerifier` that verifies everything as trustworthy.
51/// https://quinn-rs.github.io/quinn/quinn/certificate.html
52/// Dummy certificate verifier that treats any certificate as valid.
53/// NOTE, such verification is vulnerable to MITM attacks, but convenient for testing.
54#[derive(Debug)]
55pub struct SkipServerVerification(Arc<rustls::crypto::CryptoProvider>);
56
57impl SkipServerVerification {
58    fn new(provider: Arc<rustls::crypto::CryptoProvider>) -> Arc<Self> {
59        Arc::new(Self(provider))
60    }
61}
62
63impl rustls::client::danger::ServerCertVerifier for SkipServerVerification {
64    fn verify_server_cert(
65        &self,
66        _end_entity: &CertificateDer<'_>,
67        _intermediates: &[CertificateDer<'_>],
68        _server_name: &ServerName<'_>,
69        _ocsp: &[u8],
70        _now: UnixTime,
71    ) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
72        Ok(rustls::client::danger::ServerCertVerified::assertion())
73    }
74
75    fn verify_tls12_signature(
76        &self,
77        message: &[u8],
78        cert: &CertificateDer<'_>,
79        dss: &rustls::DigitallySignedStruct,
80    ) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
81        rustls::crypto::verify_tls12_signature(
82            message,
83            cert,
84            dss,
85            &self.0.signature_verification_algorithms,
86        )
87    }
88
89    fn verify_tls13_signature(
90        &self,
91        message: &[u8],
92        cert: &CertificateDer<'_>,
93        dss: &rustls::DigitallySignedStruct,
94    ) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
95        rustls::crypto::verify_tls13_signature(
96            message,
97            cert,
98            dss,
99            &self.0.signature_verification_algorithms,
100        )
101    }
102
103    fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
104        self.0.signature_verification_algorithms.supported_schemes()
105    }
106}