use std::{sync::Arc, time::Duration};
use ed25519_dalek::pkcs8::EncodePrivateKey;
use quinn::{
TransportConfig,
crypto::rustls::QuicServerConfig,
rustls::pki_types::{CertificateDer, PrivatePkcs8KeyDer},
};
use rustls::{crypto::CryptoProvider, pki_types::PrivateKeyDer};
pub fn generate_cert(
seed: [u8; 32],
subject_alt_names: Vec<String>,
alpn_protocols: Vec<Vec<u8>>,
) -> (CertificateDer<'static>, quinn::ServerConfig) {
let dalek_keypair = ed25519_dalek::SigningKey::from_bytes(&seed);
let kp = ed25519_dalek::pkcs8::KeypairBytes {
secret_key: *dalek_keypair.as_bytes(),
public_key: Some(ed25519_dalek::pkcs8::PublicKeyBytes(
*dalek_keypair.verifying_key().as_bytes(),
)),
};
let pkcs8 = kp.to_pkcs8_der().unwrap();
let pem = pem::Pem::new("PRIVATE KEY", pkcs8.as_bytes());
let pem_str = pem::encode(&pem);
let key_pair = rcgen::KeyPair::from_pem(&pem_str).unwrap();
let cert = rcgen::CertificateParams::new(subject_alt_names)
.unwrap()
.self_signed(&key_pair)
.unwrap();
let cert_der = CertificateDer::from(cert.der().to_vec());
let priv_key = PrivatePkcs8KeyDer::from(key_pair.serialize_der());
let mut tls_config = rustls::ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(vec![cert_der.clone()], PrivateKeyDer::Pkcs8(priv_key))
.unwrap();
tls_config.alpn_protocols = alpn_protocols;
let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(
QuicServerConfig::try_from(tls_config).expect("is valid config"),
));
let mut transport_config = TransportConfig::default();
transport_config.keep_alive_interval(Some(Duration::from_secs(5)));
server_config.transport_config(Arc::new(transport_config));
(cert_der, server_config)
}
pub fn install_rustls_crypto_provider() {
use std::sync::Once;
static START: Once = Once::new();
START.call_once(|| {
CryptoProvider::install_default(rustls::crypto::ring::default_provider()).unwrap();
});
}