certificate/
certificate.rs

1use std::{error::Error, sync::Arc};
2
3use noq::{
4    ClientConfig,
5    crypto::rustls::{NoInitialCipherSuite, QuicClientConfig},
6};
7use rustls::{
8    DigitallySignedStruct, SignatureScheme,
9    client::danger,
10    crypto::{CryptoProvider, verify_tls12_signature, verify_tls13_signature},
11    pki_types::{
12        CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer, ServerName, UnixTime, pem::PemObject,
13    },
14};
15
16#[allow(unused_variables)]
17fn main() {
18    let (self_signed_certs, self_signed_key) = generate_self_signed_cert().unwrap();
19    let (certs, key) = read_certs_from_file().unwrap();
20    let server_config = noq::ServerConfig::with_single_cert(certs, key);
21    let client_config = noq::ClientConfig::try_with_platform_verifier().unwrap();
22}
23
24#[allow(dead_code)] // Included in `certificate.md`
25fn configure_client() -> Result<ClientConfig, NoInitialCipherSuite> {
26    let crypto = rustls::ClientConfig::builder()
27        .dangerous()
28        .with_custom_certificate_verifier(SkipServerVerification::new())
29        .with_no_client_auth();
30
31    Ok(ClientConfig::new(Arc::new(QuicClientConfig::try_from(
32        crypto,
33    )?)))
34}
35
36// Implementation of `ServerCertVerifier` that verifies everything as trustworthy.
37#[derive(Debug)]
38struct SkipServerVerification(Arc<CryptoProvider>);
39
40impl SkipServerVerification {
41    fn new() -> Arc<Self> {
42        Arc::new(Self(Arc::new(rustls::crypto::ring::default_provider())))
43    }
44}
45
46impl danger::ServerCertVerifier for SkipServerVerification {
47    fn verify_server_cert(
48        &self,
49        _end_entity: &CertificateDer<'_>,
50        _intermediates: &[CertificateDer<'_>],
51        _server_name: &ServerName<'_>,
52        _ocsp: &[u8],
53        _now: UnixTime,
54    ) -> Result<danger::ServerCertVerified, rustls::Error> {
55        Ok(danger::ServerCertVerified::assertion())
56    }
57    fn verify_tls12_signature(
58        &self,
59        message: &[u8],
60        cert: &CertificateDer<'_>,
61        dss: &DigitallySignedStruct,
62    ) -> Result<danger::HandshakeSignatureValid, rustls::Error> {
63        verify_tls12_signature(
64            message,
65            cert,
66            dss,
67            &self.0.signature_verification_algorithms,
68        )
69    }
70
71    fn verify_tls13_signature(
72        &self,
73        message: &[u8],
74        cert: &CertificateDer<'_>,
75        dss: &DigitallySignedStruct,
76    ) -> Result<danger::HandshakeSignatureValid, rustls::Error> {
77        verify_tls13_signature(
78            message,
79            cert,
80            dss,
81            &self.0.signature_verification_algorithms,
82        )
83    }
84
85    fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
86        self.0.signature_verification_algorithms.supported_schemes()
87    }
88}
89
90fn generate_self_signed_cert()
91-> Result<(CertificateDer<'static>, PrivatePkcs8KeyDer<'static>), Box<dyn Error>> {
92    let cert = rcgen::generate_simple_self_signed(vec!["localhost".to_string()])?;
93    let cert_der = CertificateDer::from(cert.cert);
94    let key = PrivatePkcs8KeyDer::from(cert.signing_key.serialize_der());
95    Ok((cert_der, key))
96}
97
98fn read_certs_from_file()
99-> Result<(Vec<CertificateDer<'static>>, PrivateKeyDer<'static>), Box<dyn Error>> {
100    let certs = CertificateDer::pem_file_iter("./fullchain.pem")
101        .unwrap()
102        .map(|cert| cert.unwrap())
103        .collect();
104    let key = PrivateKeyDer::from_pem_file("./privkey.pem").unwrap();
105    Ok((certs, key))
106}