use coz::Thumbprint;
#[derive(Debug, Clone)]
pub struct Revocation {
pub rvk: i64,
pub by: Option<Thumbprint>,
}
#[derive(Debug, Clone)]
pub struct Key {
pub alg: String,
pub tmb: Thumbprint,
pub pub_key: Vec<u8>,
pub first_seen: i64,
pub last_used: Option<i64>,
pub revocation: Option<Revocation>,
pub tag: Option<String>,
}
impl Key {
pub fn is_active(&self) -> bool {
self.revocation.is_none()
}
pub fn is_active_at(&self, timestamp: i64) -> bool {
self.revocation.as_ref().is_none_or(|r| timestamp < r.rvk)
}
}
#[cfg(test)]
mod tests {
use super::*;
fn make_key(revocation: Option<Revocation>) -> Key {
Key {
alg: "ES256".to_string(),
tmb: Thumbprint::from_bytes(vec![0u8; 32]),
pub_key: vec![0u8; 64],
first_seen: 1000,
last_used: None,
revocation,
tag: None,
}
}
#[test]
fn is_active_no_revocation() {
let key = make_key(None);
assert!(key.is_active());
}
#[test]
fn is_active_with_revocation() {
let key = make_key(Some(Revocation {
rvk: 2000,
by: None,
}));
assert!(!key.is_active());
}
#[test]
fn is_active_at_no_revocation() {
let key = make_key(None);
assert!(key.is_active_at(0));
assert!(key.is_active_at(1000));
assert!(key.is_active_at(i64::MAX));
}
#[test]
fn is_active_at_before_revocation() {
let key = make_key(Some(Revocation {
rvk: 2000,
by: None,
}));
assert!(key.is_active_at(1999));
assert!(key.is_active_at(0));
}
#[test]
fn is_active_at_after_revocation() {
let key = make_key(Some(Revocation {
rvk: 2000,
by: None,
}));
assert!(!key.is_active_at(2000));
assert!(!key.is_active_at(2001));
}
}