aboutsummaryrefslogtreecommitdiff
path: root/src/cert.rs
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2021-12-07 13:50:44 +0100
committerAlex Auvolat <alex@adnab.me>2021-12-07 13:50:44 +0100
commit5535c4951a832d65755afa53822a36e96681320f (patch)
treef5b46340c16dbf97f69711f519824512b8d0db80 /src/cert.rs
parent61e6df6209b3c55e4c07c6baf2fabfba23a474f1 (diff)
downloadtricot-5535c4951a832d65755afa53822a36e96681320f.tar.gz
tricot-5535c4951a832d65755afa53822a36e96681320f.zip
Retrieve let's encrypt certificates
Diffstat (limited to 'src/cert.rs')
-rw-r--r--src/cert.rs59
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)
+ }
+}