use rcgen::{
BasicConstraints, CertificateParams, DnType, ExtendedKeyUsagePurpose, IsCa, Issuer, KeyPair,
KeyUsagePurpose,
};
use std::{fs, path::PathBuf, process};
use time::{Duration as Span, OffsetDateTime};
pub struct Certs {
pub ca: String,
pub cert: PathBuf,
pub key: PathBuf,
pub cert_pem: String,
pub key_pem: String,
pub client_cert: String,
pub client_key: String,
}
pub fn certs(name: &str) -> Certs {
let now = OffsetDateTime::now_utc();
let ca_key = KeyPair::generate().unwrap();
let mut ca = CertificateParams::new(Vec::<String>::new()).unwrap();
ca.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
ca.key_usages = vec![
KeyUsagePurpose::KeyCertSign,
KeyUsagePurpose::CrlSign,
KeyUsagePurpose::DigitalSignature,
];
ca.distinguished_name
.push(DnType::CommonName, "atap test authority");
ca.not_before = now - Span::days(1);
ca.not_after = now + Span::days(1);
let ca_cert = ca.self_signed(&ca_key).unwrap();
let issuer = Issuer::new(ca, ca_key);
let leaf_key = KeyPair::generate().unwrap();
let mut leaf = CertificateParams::new(vec!["localhost".to_string()]).unwrap();
leaf.key_usages = vec![KeyUsagePurpose::DigitalSignature];
leaf.extended_key_usages = vec![ExtendedKeyUsagePurpose::ServerAuth];
leaf.distinguished_name
.push(DnType::CommonName, "localhost");
leaf.not_before = now - Span::days(1);
leaf.not_after = now + Span::days(1);
let leaf_cert = leaf.signed_by(&leaf_key, &issuer).unwrap();
let client_key = KeyPair::generate().unwrap();
let mut client = CertificateParams::new(Vec::<String>::new()).unwrap();
client.key_usages = vec![KeyUsagePurpose::DigitalSignature];
client.extended_key_usages = vec![ExtendedKeyUsagePurpose::ClientAuth];
client
.distinguished_name
.push(DnType::CommonName, "atap test client");
client.not_before = now - Span::days(1);
client.not_after = now + Span::days(1);
let client_cert = client.signed_by(&client_key, &issuer).unwrap();
let dir = std::env::temp_dir().join(format!("atap-tls-{}-{name}", process::id()));
fs::create_dir_all(&dir).unwrap();
let cert = dir.join("cert.pem");
let key = dir.join("key.pem");
fs::write(&cert, leaf_cert.pem()).unwrap();
fs::write(&key, leaf_key.serialize_pem()).unwrap();
Certs {
ca: ca_cert.pem(),
cert,
key,
cert_pem: leaf_cert.pem(),
key_pem: leaf_key.serialize_pem(),
client_cert: client_cert.pem(),
client_key: client_key.serialize_pem(),
}
}