diff options
author | Alex Auvolat <alex@adnab.me> | 2021-12-07 13:50:44 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2021-12-07 13:50:44 +0100 |
commit | 5535c4951a832d65755afa53822a36e96681320f (patch) | |
tree | f5b46340c16dbf97f69711f519824512b8d0db80 /src/cert.rs | |
parent | 61e6df6209b3c55e4c07c6baf2fabfba23a474f1 (diff) | |
download | tricot-5535c4951a832d65755afa53822a36e96681320f.tar.gz tricot-5535c4951a832d65755afa53822a36e96681320f.zip |
Retrieve let's encrypt certificates
Diffstat (limited to 'src/cert.rs')
-rw-r--r-- | src/cert.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/cert.rs b/src/cert.rs new file mode 100644 index 0000000..de0d821 --- /dev/null +++ b/src/cert.rs @@ -0,0 +1,59 @@ +use anyhow::Result; + +use chrono::{Date, NaiveDate, Utc}; +use rustls::sign::CertifiedKey; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +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: 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 = CertifiedKey::new(certs, keys.into_iter().next().unwrap()); + + Ok(Cert { ser, certkey }) + } + + pub fn is_old(&self) -> bool { + let date = Date::<Utc>::from_utc(self.ser.date, Utc); + let today = Utc::today(); + today - date > chrono::Duration::days(self.ser.valid_days / 2) + } +} |