0
0
Fork 0
mirror of https://git.verdigado.com/NB-Public/simple-wkd.git synced 2024-10-30 11:05:53 +01:00

Add optional verification of maximum allowed key validity period

This commit is contained in:
RisingOpsNinja 2024-09-04 11:37:31 +02:00
parent 711d626aa9
commit 850868e60a
3 changed files with 37 additions and 2 deletions

View file

@ -56,6 +56,10 @@ pub enum SpecialErrors {
MissingFile, MissingFile,
#[error("User email rejected: domain not allowed")] #[error("User email rejected: domain not allowed")]
UnallowedDomain, UnallowedDomain,
#[error("The primary key or a subkey does not expire")]
KeyNonExpiring,
#[error("The primary keys or a subkeys validity is too long")]
KeyValidityTooLong,
} }
#[derive(Debug)] #[derive(Debug)]
@ -104,6 +108,8 @@ impl ResponseError for CompatErr {
SpecialErrors::MalformedEmail => StatusCode::BAD_REQUEST, SpecialErrors::MalformedEmail => StatusCode::BAD_REQUEST,
SpecialErrors::MissingFile => StatusCode::NOT_FOUND, SpecialErrors::MissingFile => StatusCode::NOT_FOUND,
SpecialErrors::UnallowedDomain => StatusCode::UNAUTHORIZED, SpecialErrors::UnallowedDomain => StatusCode::UNAUTHORIZED,
SpecialErrors::KeyNonExpiring => StatusCode::BAD_REQUEST,
SpecialErrors::KeyValidityTooLong => StatusCode::BAD_REQUEST,
}, },
} }
} }

View file

@ -18,6 +18,7 @@ pub struct Settings {
pub bind_host: String, pub bind_host: String,
pub external_url: Url, pub external_url: Url,
pub mail_settings: MailSettings, pub mail_settings: MailSettings,
pub policy: Option<Policy>,
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
@ -31,6 +32,11 @@ pub struct MailSettings {
pub mail_subject: String, pub mail_subject: String,
} }
#[derive(Serialize, Deserialize, Debug)]
pub struct Policy {
pub key_max_validity: Option<u64>,
}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub enum Variant { pub enum Variant {
Advanced, Advanced,

View file

@ -22,14 +22,37 @@ use sequoia_openpgp::{parse::Parse, Cert};
use std::{ use std::{
fs, fs,
path::{Path, PathBuf}, path::{Path, PathBuf},
time::Duration,
}; };
pub fn validate_cert(cert: &Cert) -> Result<ValidCert> { pub fn validate_cert(cert: &Cert) -> Result<ValidCert> {
match log_err!(cert.with_policy(crate::settings::POLICY, None), debug) { let validcert = match log_err!(cert.with_policy(crate::settings::POLICY, None), debug) {
Ok(validcert) => Ok(validcert), Ok(validcert) => validcert,
Err(_) => Err(SpecialErrors::InvalidCert)?, Err(_) => Err(SpecialErrors::InvalidCert)?,
};
if let Some(policy_settings) = &SETTINGS.policy {
if let Some(max_validity_setting) = policy_settings.key_max_validity {
let max_validity = Duration::from_secs(max_validity_setting);
if !max_validity.is_zero() {
for key in validcert.keys() {
let validity = key.key_validity_period();
if validity.is_none() {
debug!("Certificate was rejected: The primary key or a subkey has validity period of zero");
return Err(SpecialErrors::KeyNonExpiring)?
} else if validity > Some(max_validity) {
debug!("Certificate was rejected: The primary key or a subkey has a validity period greater than {max_validity_setting} seconds");
return Err(SpecialErrors::KeyValidityTooLong)?
} }
} }
}
}
}
Ok(validcert)
}
pub fn encode_local(local: &str) -> String { pub fn encode_local(local: &str) -> String {
let mut digest = vec![0; 20]; let mut digest = vec![0; 20];