use std::fs;
use std::time::Duration;
use std::time::SystemTime;
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::policy::StandardPolicy;
const P: &StandardPolicy = &StandardPolicy::new();
mod common;
use common::Environment;
#[test]
fn expired_certificate() -> anyhow::Result<()> {
if ! Environment::check_for_faketime()? {
return Ok(());
}
let t0 = SystemTime::now() - Duration::new(80 * 60, 0);
let t1 = t0 + Duration::new(30 * 60, 0);
let t2 = t1 + Duration::new(50 * 60, 0);
let t3 = t2 + Duration::new(70 * 60, 0);
let future = t3 + Duration::new(110 * 60, 0);
let mut e = Environment::at(t0.clone())?;
let p = e.git_state();
let (alice, alice_pgp) = e.gen(
"alice",
t0.clone(),
t2.duration_since(t1.clone()).expect("valid"));
let alice_fpr = &alice.fingerprint().to_string()[..];
e.sq_git(&[
"policy",
"authorize",
"alice",
"--cert-file", &alice_pgp,
"--sign-commit"
])?;
e.git(&["add", "openpgp-policy.toml"])?;
e.git(&[
"commit",
"-m", "Initial commit (@ t0).",
])?;
let root = e.git_current_commit()?;
e.git(&["log"])?;
e.sq_git(&["log", "--trust-root", &root])?;
e.time(t1);
fs::write(p.join("2"), "2.")?;
e.git(&["add", "2"])?;
e.git(&[
"commit",
"-m", "@ t1",
&format!("-S{}", alice_fpr),
])?;
let c2 = e.git_current_commit()?;
e.git(&["log"])?;
e.sq_git(&["log", "--trust-root", &root, &c2])?;
e.time(t3);
fs::write(p.join("3"), "3.")?;
e.git(&["add", "3"])?;
assert!(e.git(&[
"commit",
"-m", "@ t3.",
&format!("-S{}", alice_fpr),
]).is_err());
let (alice2, _) = {
let vc = alice.with_policy(P, e.time.clone()).expect("valid cert");
let mut primary_signer = alice.primary_key().key().clone()
.parts_into_secret()?.into_keypair()?;
let mut packets = Vec::new();
for ka in vc.keys() {
let mut subkey_signer = if ka.for_signing() {
Some(ka.key().clone().parts_into_secret()?.into_keypair()?)
} else {
None
};
let sigs = ka.set_expiration_time(
&mut primary_signer,
if let Some(subkey_signer) = subkey_signer.as_mut() {
Some(subkey_signer)
} else {
None
},
Some(future.clone()))
.expect(&format!("can update expiration of {}", ka.key().fingerprint()));
if ka.key().fingerprint() == alice.fingerprint() {
packets.push(Packet::from(alice.primary_key().key().clone()));
} else {
packets.push(Packet::from(ka.key().clone().role_into_subordinate()));
}
packets.extend(sigs.into_iter().map(|sig| Packet::from(sig)));
}
alice.clone().insert_packets(packets).expect("can insert packets")
};
e.import(&alice2).expect("can import");
assert!(e.git(&[
"commit",
"-m", "@ t3.",
&format!("-S{}", alice_fpr),
]).is_ok());
let c3_1 = e.git_current_commit()?;
e.git(&["log"])?;
assert!(e.sq_git(&["log", "--trust-root", &root, &c3_1]).is_err());
e.git(&["reset", "--hard", &c2])?;
assert_eq!(c2, e.git_current_commit()?);
assert!(e.sq_git(&["policy", "sync", "--disable-keyservers"]).is_ok());
e.git(&["add", "openpgp-policy.toml"])?;
assert!(e.git(&[
"commit",
"-m", "@ t3 (try two).",
&format!("-S{}", alice_fpr),
]).is_ok());
let c3_2 = e.git_current_commit()?;
e.git(&["log"])?;
assert!(e.sq_git(&["log", "--trust-root", &root, &c3_2]).is_ok());
Ok(())
}