tricot/src/cert.rs

61 lines
1.4 KiB
Rust

use std::sync::Arc;
use anyhow::Result;
use chrono::{NaiveDate, Utc};
use rustls::sign::CertifiedKey;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CertSer {
pub hostname: String,
pub date: NaiveDate,
pub valid_days: i64,
pub key_pem: String,
pub cert_pem: String,
}
pub struct Cert {
pub ser: CertSer,
pub certkey: Arc<CertifiedKey>,
}
impl Cert {
pub fn new(ser: CertSer) -> Result<Self> {
let pem_certs = rustls_pemfile::read_all(&mut ser.cert_pem.as_bytes())?;
let certs = pem_certs
.into_iter()
.filter_map(|cert| match cert {
rustls_pemfile::Item::X509Certificate(cert) => Some(rustls::Certificate(cert)),
_ => None,
})
.collect::<Vec<_>>();
let pem_keys = rustls_pemfile::read_all(&mut ser.key_pem.as_bytes())?;
let keys = pem_keys
.into_iter()
.filter_map(|key| match key {
rustls_pemfile::Item::RSAKey(bytes) | rustls_pemfile::Item::PKCS8Key(bytes) => {
Some(rustls::sign::any_supported_type(&rustls::PrivateKey(bytes)).ok()?)
}
_ => None,
})
.collect::<Vec<_>>();
if keys.len() != 1 {
bail!("{} keys present in pem file", keys.len());
}
let certkey = Arc::new(CertifiedKey::new(certs, keys.into_iter().next().unwrap()));
Ok(Cert { ser, certkey })
}
pub fn is_old(&self) -> bool {
let today = Utc::now().date_naive();
today - self.ser.date > chrono::Duration::days(self.ser.valid_days / 2)
}
}