use std::time::SystemTime;
use pgp::composed::{SignedPublicKey, SignedPublicSubKey};
use pgp::packet::SignatureType;
use pgp::types::KeyDetails;
pub(crate) fn is_key_expired(creation_time: SystemTime, validity_seconds: Option<u64>) -> bool {
if let Some(validity) = validity_seconds {
if validity == 0 {
return false; }
let expiration = creation_time + std::time::Duration::from_secs(validity);
expiration < SystemTime::now()
} else {
false }
}
pub(crate) fn is_subkey_revoked(subkey: &SignedPublicSubKey) -> bool {
subkey.signatures.iter().any(|sig| {
sig.typ() == Some(SignatureType::SubkeyRevocation)
})
}
pub(crate) fn is_subkey_valid(subkey: &SignedPublicSubKey, allow_expired: bool) -> bool {
if is_subkey_revoked(subkey) {
return false;
}
if !allow_expired {
if let Some(sig) = subkey.signatures.last() {
if let Some(validity) = sig.key_expiration_time() {
let creation_time: SystemTime = subkey.key.created_at().into();
if is_key_expired(creation_time, Some(validity.as_secs() as u64)) {
return false;
}
}
}
}
true
}
pub(crate) fn can_primary_sign(key: &SignedPublicKey) -> bool {
for user in &key.details.users {
for sig in &user.signatures {
let flags = sig.key_flags();
if flags.sign() {
return true;
}
}
}
false
}
pub(crate) fn is_primary_key_revoked(key: &SignedPublicKey) -> bool {
key.details.revocation_signatures.iter().any(|sig| {
sig.typ() == Some(SignatureType::KeyRevocation)
})
}
pub(crate) fn is_primary_key_valid_for_verification(key: &SignedPublicKey) -> bool {
!is_primary_key_revoked(key)
}
pub(crate) fn get_key_expiration(key: &SignedPublicKey) -> Option<SystemTime> {
let creation_time: SystemTime = key.primary_key.created_at().into();
let mut newest_created: Option<SystemTime> = None;
let mut newest_expiration = None;
for user in &key.details.users {
for sig in &user.signatures {
if let Some(validity) = sig.key_expiration_time() {
let sig_created: Option<SystemTime> = sig.created().map(|ts| ts.into());
let is_newer = match (&newest_created, &sig_created) {
(Some(prev), Some(cur)) => cur > prev,
(None, Some(_)) => true,
(None, None) => newest_expiration.is_none(),
_ => false,
};
if is_newer {
newest_created = sig_created;
newest_expiration = Some(creation_time + validity.into());
}
}
}
}
newest_expiration
}