From 258394678f759dee27b8be2dd13f2a317051fc51 Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Sat, 23 Nov 2024 10:55:18 +0100 Subject: [PATCH] Don't use revoked certificates for encryption. - Change `sq encrypt` to not use revoked certificates. --- src/commands/encrypt.rs | 10 ++++++ tests/integration/sq_encrypt.rs | 55 ++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/commands/encrypt.rs b/src/commands/encrypt.rs index 0c412b7a..92a97988 100644 --- a/src/commands/encrypt.rs +++ b/src/commands/encrypt.rs @@ -21,6 +21,7 @@ use openpgp::serialize::stream::Signer; use openpgp::serialize::stream::padding::Padder; use openpgp::types::CompressionAlgorithm; use openpgp::types::KeyFlags; +use openpgp::types::RevocationStatus; use openpgp::types::SignatureType; use crate::cli; @@ -136,6 +137,15 @@ pub fn encrypt<'a, 'b: 'a>( // Build a vector of recipients to hand to Encryptor. let mut recipient_subkeys: Vec = Vec::new(); for cert in recipients.iter() { + if let RevocationStatus::Revoked(_) + = cert.revocation_status(policy, time) + { + return Err(anyhow::anyhow!( + "Can't encrypt to {}, {}: it is revoked", + cert.fingerprint(), + sq.best_userid(&cert, true))); + } + let mut count = 0; for key in cert.keys().with_policy(policy, time).alive().revoked(false) .key_flags(&mode).supported().map(|ka| ka.key()) diff --git a/tests/integration/sq_encrypt.rs b/tests/integration/sq_encrypt.rs index 3119821b..1c9ff044 100644 --- a/tests/integration/sq_encrypt.rs +++ b/tests/integration/sq_encrypt.rs @@ -681,7 +681,7 @@ fn sq_encrypt_expired() -> Result<()> // Try encrypting to a certificate with a revoked subkey. Make sure // it fails. #[test] -fn sq_encrypt_revoked() -> Result<()> +fn sq_encrypt_revoked_subkey() -> Result<()> { let mut sq = Sq::new(); @@ -735,3 +735,56 @@ fn sq_encrypt_revoked() -> Result<()> Ok(()) } + +// Try encrypting to a revoked certificate. Make sure it fails. +#[test] +fn sq_encrypt_revoked() -> Result<()> +{ + let mut sq = Sq::new(); + + // Generate the keys. Alice has an encryption capable subkey, but + // Bob doesn't. + let (alice, alice_pgp, _alice_rev) = sq.key_generate( + &[], + &[""]); + sq.key_import(alice_pgp); + + let alice_enc = alice.keys().with_policy(STANDARD_POLICY, sq.now()) + .for_storage_encryption() + .next() + .expect("have a storage encryption-capable subkey") + .fingerprint(); + + let (bob, bob_pgp, _bob_rev) = sq.key_generate( + &[], + &[""]); + sq.key_import(&bob_pgp); + + sq.tick(1); + + // Revoke. + let bob = sq.key_revoke( + bob.key_handle(), None, + "retired", "retired this key", None, &[], None); + + // Two days pass... + sq.tick(2 * 24 * 60 * 60); + + for (i, (recipients, result)) in [ + (&[ &alice ][..], &[ &alice_enc ][..]), + (&[ &bob ], &[]), + (&[ &alice, &bob ], &[]), + ].into_iter().enumerate() { + eprintln!("Test #{}", i + 1); + + let recipients = recipients.iter().map(|r| r.fingerprint()) + .collect::>(); + let recipients = recipients.iter() + .collect::>(); + + try_encrypt(&sq, &[], result, &recipients, &[], &[]); + } + + Ok(()) +} +