From a4e0ccfa51db9917b0e5e0175cea80dca9c5c680 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Fri, 12 Jun 2020 12:24:55 +0200 Subject: [PATCH] Correctly handle certificate expiration on openssl The `openssl` crate now include methods to manipulate Asn1Time objects. Before this improvement, the certificate had to be parsed from the DER format using the `x509-parser` crate (which is therefore no longer required). https://github.com/sfackler/rust-openssl/pull/1173 https://github.com/sfackler/rust-openssl/issues/687 --- CONTRIBUTING.md | 7 +------ acme_common/Cargo.toml | 1 - acme_common/src/crypto/openssl_certificate.rs | 16 ++++++++-------- acme_common/src/error.rs | 6 ++++++ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7bfc240..c516665 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,12 +15,7 @@ Since the author is not a native English speaker, some of the texts used in this ### rust-openssl -The [openssl](https://crates.io/crates/openssl) crate does not expose the Asn1Time in a usable way, which requires ACMEd to parse certificates using an external library in order to get the `not after` field. This is sub-optimal. - -- https://github.com/sfackler/rust-openssl/issues/687 -- https://github.com/sfackler/rust-openssl/pull/673 - -An other improvement that would be appreciable is to add Curve 25519 support. +An improvement that would be appreciable is to add Curve 25519 support to the [openssl](https://crates.io/crates/openssl) crate. - https://github.com/sfackler/rust-openssl/issues/947 diff --git a/acme_common/Cargo.toml b/acme_common/Cargo.toml index cf87373..4015097 100644 --- a/acme_common/Cargo.toml +++ b/acme_common/Cargo.toml @@ -24,7 +24,6 @@ reqwest = { version = "0.10", features = ["blocking", "default-tls"] } serde_json = "1.0" syslog = "5.0" toml = "0.5" -x509-parser = "0.7" [target.'cfg(unix)'.dependencies] nix = "0.17" diff --git a/acme_common/src/crypto/openssl_certificate.rs b/acme_common/src/crypto/openssl_certificate.rs index 24eaf23..16e7895 100644 --- a/acme_common/src/crypto/openssl_certificate.rs +++ b/acme_common/src/crypto/openssl_certificate.rs @@ -8,8 +8,7 @@ use openssl::stack::Stack; use openssl::x509::extension::{BasicConstraints, SubjectAlternativeName}; use openssl::x509::{X509Builder, X509Extension, X509NameBuilder, X509Req, X509ReqBuilder, X509}; use std::collections::HashSet; -use std::time::Duration; -use x509_parser::parse_x509_der; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; const APP_ORG: &str = "ACMEd"; const APP_NAME: &str = "ACMEd"; @@ -67,12 +66,13 @@ impl X509Certificate { } pub fn expires_in(&self) -> Result { - let raw_crt = self.inner_cert.to_der()?; - let (_, crt) = parse_x509_der(&raw_crt).map_err(|_| Error::from("Invalid certificate."))?; - crt.tbs_certificate - .validity - .time_to_expiration() - .ok_or_else(|| Error::from("Invalid certificate validity.")) + let timestamp = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64; + let now = Asn1Time::from_unix(timestamp)?; + let not_after = self.inner_cert.not_after(); + let diff = now.diff(not_after)?; + let nb_secs = diff.days * 24 * 60 * 60 + diff.secs; + let nb_secs = if nb_secs > 0 { nb_secs as u64 } else { 0 }; + Ok(Duration::from_secs(nb_secs)) } pub fn subject_alt_names(&self) -> HashSet { diff --git a/acme_common/src/error.rs b/acme_common/src/error.rs index d81caff..ea2d652 100644 --- a/acme_common/src/error.rs +++ b/acme_common/src/error.rs @@ -57,6 +57,12 @@ impl From for Error { } } +impl From for Error { + fn from(error: std::time::SystemTimeError) -> Self { + format!("SystemTimeError difference: {:?}", error.duration()).into() + } +} + impl From for Error { fn from(error: syslog::Error) -> Self { format!("syslog error: {}", error).into()