1use std::sync::Arc;
7
8use quinn::crypto::rustls::{NoInitialCipherSuite, QuicClientConfig, QuicServerConfig};
9use tracing::warn;
10
11use self::certificate::AlwaysResolvesCert;
12use crate::key::{PublicKey, SecretKey};
13
14pub mod certificate;
15mod verifier;
16
17#[derive(Debug, thiserror::Error)]
19pub enum CreateConfigError {
20 #[error("Error generating the certificate")]
22 CertError(#[from] certificate::GenError),
23 #[error("Error creating QUIC config")]
25 ConfigError(#[from] NoInitialCipherSuite),
26}
27
28pub fn make_client_config(
34 secret_key: &SecretKey,
35 remote_peer_id: Option<PublicKey>,
36 alpn_protocols: Vec<Vec<u8>>,
37 keylog: bool,
38) -> Result<QuicClientConfig, CreateConfigError> {
39 let (certificate, secret_key) = certificate::generate(secret_key)?;
40
41 let cert_resolver = Arc::new(
42 AlwaysResolvesCert::new(certificate, &secret_key)
43 .expect("Client cert key DER is valid; qed"),
44 );
45
46 let mut crypto = rustls::ClientConfig::builder_with_provider(Arc::new(
47 rustls::crypto::ring::default_provider(),
48 ))
49 .with_protocol_versions(verifier::PROTOCOL_VERSIONS)
50 .expect("version supported by ring")
51 .dangerous()
52 .with_custom_certificate_verifier(Arc::new(
53 verifier::Libp2pCertificateVerifier::with_remote_peer_id(remote_peer_id),
54 ))
55 .with_client_cert_resolver(cert_resolver);
56 crypto.alpn_protocols = alpn_protocols;
57 if keylog {
58 warn!("enabling SSLKEYLOGFILE for TLS pre-master keys");
59 crypto.key_log = Arc::new(rustls::KeyLogFile::new());
60 }
61 let config = crypto.try_into()?;
62 Ok(config)
63}
64
65pub fn make_server_config(
71 secret_key: &SecretKey,
72 alpn_protocols: Vec<Vec<u8>>,
73 keylog: bool,
74) -> Result<QuicServerConfig, CreateConfigError> {
75 let (certificate, secret_key) = certificate::generate(secret_key)?;
76
77 let cert_resolver = Arc::new(
78 AlwaysResolvesCert::new(certificate, &secret_key)
79 .expect("Server cert key DER is valid; qed"),
80 );
81
82 let mut crypto = rustls::ServerConfig::builder_with_provider(Arc::new(
83 rustls::crypto::ring::default_provider(),
84 ))
85 .with_protocol_versions(verifier::PROTOCOL_VERSIONS)
86 .expect("fixed config")
87 .with_client_cert_verifier(Arc::new(verifier::Libp2pCertificateVerifier::new()))
88 .with_cert_resolver(cert_resolver);
89 crypto.alpn_protocols = alpn_protocols;
90 if keylog {
91 warn!("enabling SSLKEYLOGFILE for TLS pre-master keys");
92 crypto.key_log = Arc::new(rustls::KeyLogFile::new());
93 }
94 let config = crypto.try_into()?;
95 Ok(config)
96}