use pollen_types::{Result, TransportError};
use rcgen::{CertifiedKey, generate_simple_self_signed};
use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
use std::sync::Arc;
pub fn generate_self_signed_cert() -> Result<(Vec<CertificateDer<'static>>, PrivateKeyDer<'static>)> {
let CertifiedKey { cert, key_pair } = generate_simple_self_signed(vec!["pollen".to_string()])
.map_err(|e| TransportError::Tls(e.to_string()))?;
let cert_der = CertificateDer::from(cert.der().to_vec());
let key_der = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(key_pair.serialize_der()));
Ok((vec![cert_der], key_der))
}
pub fn server_config() -> Result<quinn::ServerConfig> {
let (certs, key) = generate_self_signed_cert()?;
let mut config = rustls::ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(certs.clone(), key.clone_key())
.map_err(|e| TransportError::Tls(e.to_string()))?;
config.alpn_protocols = vec![b"pollen".to_vec()];
let quic_config = quinn::crypto::rustls::QuicServerConfig::try_from(config)
.map_err(|e| TransportError::Tls(e.to_string()))?;
let mut transport_config = quinn::TransportConfig::default();
transport_config.max_idle_timeout(Some(
std::time::Duration::from_secs(30)
.try_into()
.unwrap(),
));
let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(quic_config));
server_config.transport_config(Arc::new(transport_config));
Ok(server_config)
}
pub fn client_config() -> Result<quinn::ClientConfig> {
let config = rustls::ClientConfig::builder()
.dangerous()
.with_custom_certificate_verifier(Arc::new(SkipServerVerification))
.with_no_client_auth();
let quic_config = quinn::crypto::rustls::QuicClientConfig::try_from(config)
.map_err(|e| TransportError::Tls(e.to_string()))?;
let mut transport_config = quinn::TransportConfig::default();
transport_config.max_idle_timeout(Some(
std::time::Duration::from_secs(30)
.try_into()
.unwrap(),
));
let mut client_config = quinn::ClientConfig::new(Arc::new(quic_config));
client_config.transport_config(Arc::new(transport_config));
Ok(client_config)
}
#[derive(Debug)]
struct SkipServerVerification;
impl rustls::client::danger::ServerCertVerifier for SkipServerVerification {
fn verify_server_cert(
&self,
_end_entity: &CertificateDer<'_>,
_intermediates: &[CertificateDer<'_>],
_server_name: &rustls::pki_types::ServerName<'_>,
_ocsp_response: &[u8],
_now: rustls::pki_types::UnixTime,
) -> std::result::Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
Ok(rustls::client::danger::ServerCertVerified::assertion())
}
fn verify_tls12_signature(
&self,
_message: &[u8],
_cert: &CertificateDer<'_>,
_dss: &rustls::DigitallySignedStruct,
) -> std::result::Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
}
fn verify_tls13_signature(
&self,
_message: &[u8],
_cert: &CertificateDer<'_>,
_dss: &rustls::DigitallySignedStruct,
) -> std::result::Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
}
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
vec![
rustls::SignatureScheme::RSA_PKCS1_SHA256,
rustls::SignatureScheme::RSA_PKCS1_SHA384,
rustls::SignatureScheme::RSA_PKCS1_SHA512,
rustls::SignatureScheme::ECDSA_NISTP256_SHA256,
rustls::SignatureScheme::ECDSA_NISTP384_SHA384,
rustls::SignatureScheme::ECDSA_NISTP521_SHA512,
rustls::SignatureScheme::RSA_PSS_SHA256,
rustls::SignatureScheme::RSA_PSS_SHA384,
rustls::SignatureScheme::RSA_PSS_SHA512,
rustls::SignatureScheme::ED25519,
]
}
}