feat(tls): add certificate expiry validation and self-signed warning
This commit is contained in:
@@ -28,6 +28,9 @@ pub fn build_server_config(
|
|||||||
let cert_bytes = std::fs::read(cert_path).context("read cert")?;
|
let cert_bytes = std::fs::read(cert_path).context("read cert")?;
|
||||||
let key_bytes = std::fs::read(key_path).context("read key")?;
|
let key_bytes = std::fs::read(key_path).context("read key")?;
|
||||||
|
|
||||||
|
// Validate certificate expiry and warn about self-signed certs.
|
||||||
|
validate_certificate(&cert_bytes)?;
|
||||||
|
|
||||||
let cert_chain = vec![CertificateDer::from(cert_bytes)];
|
let cert_chain = vec![CertificateDer::from(cert_bytes)];
|
||||||
let key = PrivateKeyDer::try_from(key_bytes).map_err(|_| anyhow::anyhow!("invalid key"))?;
|
let key = PrivateKeyDer::try_from(key_bytes).map_err(|_| anyhow::anyhow!("invalid key"))?;
|
||||||
|
|
||||||
@@ -76,3 +79,39 @@ fn generate_self_signed_cert(cert_path: &PathBuf, key_path: &PathBuf) -> anyhow:
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Validate a DER-encoded X.509 certificate: bail if expired, warn if expiring
|
||||||
|
/// soon or self-signed.
|
||||||
|
fn validate_certificate(der_bytes: &[u8]) -> anyhow::Result<()> {
|
||||||
|
use x509_parser::prelude::*;
|
||||||
|
|
||||||
|
let (_, cert) = X509Certificate::from_der(der_bytes)
|
||||||
|
.map_err(|e| anyhow::anyhow!("failed to parse X.509 certificate: {e}"))?;
|
||||||
|
|
||||||
|
let validity = cert.validity();
|
||||||
|
let now = ASN1Time::now();
|
||||||
|
|
||||||
|
if !validity.is_valid_at(now) {
|
||||||
|
anyhow::bail!(
|
||||||
|
"TLS certificate expired (not_after: {})",
|
||||||
|
validity.not_after
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn if expiring within 30 days.
|
||||||
|
let thirty_days = std::time::Duration::from_secs(30 * 24 * 60 * 60);
|
||||||
|
let cutoff = now.timestamp() + thirty_days.as_secs() as i64;
|
||||||
|
if validity.not_after.timestamp() < cutoff {
|
||||||
|
tracing::warn!(
|
||||||
|
not_after = %validity.not_after,
|
||||||
|
"TLS certificate expires within 30 days"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn if self-signed (issuer == subject).
|
||||||
|
if cert.issuer() == cert.subject() {
|
||||||
|
tracing::warn!("TLS certificate is self-signed (issuer == subject)");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user