summaryrefslogtreecommitdiffstats
path: root/sq/tests
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2022-02-03 10:55:32 +0100
committerNeal H. Walfield <neal@pep.foundation>2022-06-14 14:21:50 +0200
commitd68fba31b8fad07b925d73224289a4ddd34a8f71 (patch)
treefb34b75732de09f347ffd48637c2cf1ef72476b9 /sq/tests
parent36270e24d2761a40e92668ab0d083afae322da4c (diff)
sq: Allow creating a certification with an expired or revoke key
- Add two new options to `sq certify`: `allow-not-alive-certifier` and `allow-revoked-certifier`. - If present, don't fail if the certifying key is not alive or revoked, respectively.
Diffstat (limited to 'sq/tests')
-rw-r--r--sq/tests/sq-certify.rs179
1 files changed, 179 insertions, 0 deletions
diff --git a/sq/tests/sq-certify.rs b/sq/tests/sq-certify.rs
index 4cbd0a9c..b1ed3f3a 100644
--- a/sq/tests/sq-certify.rs
+++ b/sq/tests/sq-certify.rs
@@ -318,3 +318,182 @@ fn sq_certify_creation_time() -> Result<()>
Ok(())
}
+
+#[test]
+fn sq_certify_with_expired_key() -> Result<()>
+{
+ let seconds_in_day = 24 * 60 * 60;
+
+ let validity = time::Duration::new(30 * seconds_in_day, 0);
+ let creation_time = time::SystemTime::now() - 2 * validity;
+
+ let dir = TempDir::new()?;
+
+ // Alice's expired key certifies bob's not expired key.
+
+ let alice = "<alice@example.org>";
+ let alice_key = CertBuilder::new()
+ .add_signing_subkey()
+ .set_creation_time(creation_time)
+ .set_validity_period(validity)
+ .add_userid(alice)
+ .generate()
+ .map(|(key, _rev)| key)?;
+
+ let alice_pgp = dir.path().join("alice.pgp");
+ {
+ let mut file = File::create(&alice_pgp)?;
+ alice_key.as_tsk().serialize(&mut file)?;
+ }
+
+ // Bob's key has the same creation time, but it does not expire.
+ let bob = "<bob@other.org>";
+ let bob_key = CertBuilder::new()
+ .add_signing_subkey()
+ .set_creation_time(creation_time)
+ .add_userid(bob)
+ .generate()
+ .map(|(key, _rev)| key)?;
+
+ let bob_pgp = dir.path().join("bob.pgp");
+ {
+ let mut file = File::create(&bob_pgp)?;
+ bob_key.serialize(&mut file)?;
+ }
+
+ // Make sure using an expired key fails by default.
+ let mut cmd = Command::cargo_bin("sq")?;
+ cmd.args(["certify",
+ &alice_pgp.to_string_lossy(),
+ &bob_pgp.to_string_lossy(), bob ]);
+ cmd.assert().failure();
+
+
+ // Try again.
+ let mut cmd = Command::cargo_bin("sq")?;
+ cmd.args(["certify",
+ "--allow-not-alive-certifier",
+ &alice_pgp.to_string_lossy(),
+ &bob_pgp.to_string_lossy(), bob ]);
+
+ let assertion = cmd.assert().try_success()?;
+ let stdout = String::from_utf8_lossy(&assertion.get_output().stdout);
+
+ let cert = Cert::from_bytes(&*stdout)?;
+
+ let vc = cert.with_policy(P, None)?;
+
+ assert!(
+ creation_time.duration_since(vc.primary_key().creation_time()).unwrap()
+ < time::Duration::new(1, 0));
+
+ let mut userid = None;
+ for u in vc.userids() {
+ if u.userid().value() == bob.as_bytes() {
+ userid = Some(u);
+ break;
+ }
+ }
+
+ if let Some(userid) = userid {
+ let certifications: Vec<_> = userid.certifications().collect();
+ assert_eq!(certifications.len(), 1);
+ let certification = certifications.into_iter().next().unwrap();
+
+ assert_eq!(certification.get_issuers().into_iter().next(),
+ Some(KeyHandle::from(alice_key.fingerprint())));
+ } else {
+ panic!("missing user id");
+ }
+
+ Ok(())
+}
+
+#[test]
+fn sq_certify_with_revoked_key() -> Result<()>
+{
+ let seconds_in_day = 24 * 60 * 60;
+
+ let creation_time =
+ time::SystemTime::now() - time::Duration::new(seconds_in_day, 0);
+
+ let dir = TempDir::new()?;
+
+ // Alice's revoked key certifies bob's not expired key.
+
+ let alice = "<alice@example.org>";
+ let (alice_key, revocation) = CertBuilder::new()
+ .add_signing_subkey()
+ .set_creation_time(creation_time)
+ .add_userid(alice)
+ .generate()?;
+ let alice_key = alice_key.insert_packets(revocation)?;
+
+ let alice_pgp = dir.path().join("alice.pgp");
+ {
+ let mut file = File::create(&alice_pgp)?;
+ alice_key.as_tsk().serialize(&mut file)?;
+ }
+
+ // Bob's key has the same creation time, but it does not expire.
+ let bob = "<bob@other.org>";
+ let bob_key = CertBuilder::new()
+ .add_signing_subkey()
+ .set_creation_time(creation_time)
+ .add_userid(bob)
+ .generate()
+ .map(|(key, _rev)| key)?;
+
+ let bob_pgp = dir.path().join("bob.pgp");
+ {
+ let mut file = File::create(&bob_pgp)?;
+ bob_key.serialize(&mut file)?;
+ }
+
+ // Make sure using an expired key fails by default.
+ let mut cmd = Command::cargo_bin("sq")?;
+ cmd.args(["certify",
+ &alice_pgp.to_string_lossy(),
+ &bob_pgp.to_string_lossy(), bob ]);
+ cmd.assert().failure();
+
+
+ // Try again.
+ let mut cmd = Command::cargo_bin("sq")?;
+ cmd.args(["certify",
+ "--allow-revoked-certifier",
+ &alice_pgp.to_string_lossy(),
+ &bob_pgp.to_string_lossy(), bob ]);
+
+ let assertion = cmd.assert().try_success()?;
+ let stdout = String::from_utf8_lossy(&assertion.get_output().stdout);
+
+ let cert = Cert::from_bytes(&*stdout)?;
+
+ let vc = cert.with_policy(P, None)?;
+
+ assert!(
+ creation_time.duration_since(vc.primary_key().creation_time()).unwrap()
+ < time::Duration::new(1, 0));
+
+ let mut userid = None;
+ for u in vc.userids() {
+ if u.userid().value() == bob.as_bytes() {
+ userid = Some(u);
+ break;
+ }
+ }
+
+ if let Some(userid) = userid {
+ let certifications: Vec<_> = userid.certifications().collect();
+ assert_eq!(certifications.len(), 1);
+ let certification = certifications.into_iter().next().unwrap();
+
+ assert_eq!(certification.get_issuers().into_iter().next(),
+ Some(KeyHandle::from(alice_key.fingerprint())));
+ } else {
+ panic!("missing user id");
+ }
+
+ Ok(())
+}