diff options
author | Neal H. Walfield <neal@pep.foundation> | 2019-11-09 23:55:02 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2019-11-10 00:05:23 +0100 |
commit | b8e5ef908ee211daee84a0782a115ae7fc003ec0 (patch) | |
tree | 360698ced26dc36aad015e11b89137d613b89208 | |
parent | 365862ed513057900c0d6c106ec51dff0a09693e (diff) |
openpgp: Distinguish bad signatures from those that are not alive.
- Return a different `VerificationResult` for signatures that are
not alive (BadSignature) from signatures that are actually
bad (BadCheck).
-rw-r--r-- | guide/src/chapter_01.md | 12 | ||||
-rw-r--r-- | ipc/examples/gpg-agent-decrypt.rs | 7 | ||||
-rw-r--r-- | ipc/tests/gpg-agent.rs | 3 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp.h | 2 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp/types.h | 1 | ||||
-rw-r--r-- | openpgp-ffi/src/parse/stream.rs | 24 | ||||
-rw-r--r-- | openpgp/examples/decrypt-with.rs | 6 | ||||
-rw-r--r-- | openpgp/examples/generate-sign-verify.rs | 3 | ||||
-rw-r--r-- | openpgp/src/parse/stream.rs | 45 | ||||
-rw-r--r-- | tool/src/commands/mod.rs | 18 |
10 files changed, 103 insertions, 18 deletions
diff --git a/guide/src/chapter_01.md b/guide/src/chapter_01.md index 76fee1a9..fad70067 100644 --- a/guide/src/chapter_01.md +++ b/guide/src/chapter_01.md @@ -119,6 +119,9 @@ fn main() { # match results.get(0) { # Some(VerificationResult::GoodChecksum(..)) => # good = true, +# Some(VerificationResult::NotAlive(_)) => +# return Err(failure::err_msg( +# "Good, but not alive signature")), # Some(VerificationResult::MissingKey(_)) => # return Err(failure::err_msg( # "Missing key to verify signature")), @@ -261,6 +264,9 @@ fn generate() -> openpgp::Result<openpgp::TPK> { # match results.get(0) { # Some(VerificationResult::GoodChecksum(..)) => # good = true, +# Some(VerificationResult::NotAlive(_)) => +# return Err(failure::err_msg( +# "Good, but not alive signature")), # Some(VerificationResult::MissingKey(_)) => # return Err(failure::err_msg( # "Missing key to verify signature")), @@ -403,6 +409,9 @@ fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::TPK) # match results.get(0) { # Some(VerificationResult::GoodChecksum(..)) => # good = true, +# Some(VerificationResult::NotAlive(_)) => +# return Err(failure::err_msg( +# "Good, but not alive signature")), # Some(VerificationResult::MissingKey(_)) => # return Err(failure::err_msg( # "Missing key to verify signature")), @@ -556,6 +565,9 @@ impl<'a> VerificationHelper for Helper<'a> { match results.get(0) { Some(VerificationResult::GoodChecksum(..)) => good = true, + Some(VerificationResult::NotAlive(_)) => + return Err(failure::err_msg( + "Good, but not alive signature")), Some(VerificationResult::MissingKey(_)) => return Err(failure::err_msg( "Missing key to verify signature")), diff --git a/ipc/examples/gpg-agent-decrypt.rs b/ipc/examples/gpg-agent-decrypt.rs index 0faa57a3..e9874726 100644 --- a/ipc/examples/gpg-agent-decrypt.rs +++ b/ipc/examples/gpg-agent-decrypt.rs @@ -138,6 +138,13 @@ impl<'a> VerificationHelper for Helper<'a> { .expect("good checksum has an issuer"); eprintln!("Good signature from {}", issuer); }, + NotAlive(ref sig) => { + let issuer = sig.issuer() + .expect("Good, but not live signature has an \ + issuer"); + eprintln!("Good, but not live signature from {}", + issuer); + }, MissingKey(ref sig) => { let issuer = sig.issuer() .expect("missing key checksum has an \ diff --git a/ipc/tests/gpg-agent.rs b/ipc/tests/gpg-agent.rs index 3a7b44b5..d707b7b0 100644 --- a/ipc/tests/gpg-agent.rs +++ b/ipc/tests/gpg-agent.rs @@ -162,6 +162,9 @@ fn sign() { match results.get(0) { Some(VerificationResult::GoodChecksum(..)) => good = true, + Some(VerificationResult::NotAlive(_)) => + return Err(failure::err_msg( + "Good, but not live signature")), Some(VerificationResult::MissingKey(_)) => return Err(failure::err_msg( "Missing key to verify signature")), diff --git a/openpgp-ffi/include/sequoia/openpgp.h b/openpgp-ffi/include/sequoia/openpgp.h index 66309c03..9eaa2d07 100644 --- a/openpgp-ffi/include/sequoia/openpgp.h +++ b/openpgp-ffi/include/sequoia/openpgp.h @@ -1609,6 +1609,8 @@ bool pgp_verification_result_good_checksum (pgp_verification_result_t, pgp_key_t *, pgp_signature_t *, pgp_revocation_status_t *); +bool pgp_verification_result_not_alive (pgp_verification_result_t, + pgp_signature_t *); bool pgp_verification_result_missing_key (pgp_verification_result_t, pgp_signature_t *); bool pgp_verification_result_bad_checksum (pgp_verification_result_t, diff --git a/openpgp-ffi/include/sequoia/openpgp/types.h b/openpgp-ffi/include/sequoia/openpgp/types.h index d7a8271e..8dbd890b 100644 --- a/openpgp-ffi/include/sequoia/openpgp/types.h +++ b/openpgp-ffi/include/sequoia/openpgp/types.h @@ -480,6 +480,7 @@ typedef enum pgp_verification_result_variant { PGP_VERIFICATION_RESULT_GOOD_CHECKSUM = 1, PGP_VERIFICATION_RESULT_MISSING_KEY = 2, PGP_VERIFICATION_RESULT_BAD_CHECKSUM = 3, + PGP_VERIFICATION_RESULT_NOT_ALIVE = 4, /* Dummy value to make sure the enumeration has a defined size. Do not use this value. */ diff --git a/openpgp-ffi/src/parse/stream.rs b/openpgp-ffi/src/parse/stream.rs index 9148b79c..d46f9042 100644 --- a/openpgp-ffi/src/parse/stream.rs +++ b/openpgp-ffi/src/parse/stream.rs @@ -172,6 +172,7 @@ fn pgp_verification_result_variant(result: *const VerificationResult) GoodChecksum(..) => 1, MissingKey(_) => 2, BadChecksum(_) => 3, + NotAlive(_) => 4, } } @@ -220,6 +221,29 @@ fn pgp_verification_result_good_checksum<'a>( } } +/// Decomposes a `VerificationResult::NotAlive`. +/// +/// Returns `true` iff the given value is a +/// `VerificationResult::NotAlive`, and returns the variant's members +/// in `sig_r` and the like iff `sig_r != NULL`. +#[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" +fn pgp_verification_result_not_alive<'a>( + result: *const VerificationResult<'a>, + sig_r: Maybe<*mut Signature>) + -> bool +{ + use self::stream::VerificationResult::*; + if let NotAlive(ref sig) = result.ref_raw() + { + if let Some(mut p) = sig_r { + *unsafe { p.as_mut() } = sig.move_into_raw(); + } + true + } else { + false + } +} + /// Decomposes a `VerificationResult::MissingKey`. /// /// Returns `true` iff the given value is a diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs index ad8920c0..4b5d231a 100644 --- a/openpgp/examples/decrypt-with.rs +++ b/openpgp/examples/decrypt-with.rs @@ -131,6 +131,12 @@ impl VerificationHelper for Helper { .expect("good checksum has an issuer"); eprintln!("Good signature from {}", issuer); }, + NotAlive(ref sig) => { + let issuer = sig.issuer() + .expect("not alive has an issuer"); + eprintln!("Good, but not alive signature from {}", + issuer); + }, MissingKey(ref sig) => { let issuer = sig.issuer() .expect("missing key checksum has an \ diff --git a/openpgp/examples/generate-sign-verify.rs b/openpgp/examples/generate-sign-verify.rs index 8dae191c..bddacc71 100644 --- a/openpgp/examples/generate-sign-verify.rs +++ b/openpgp/examples/generate-sign-verify.rs @@ -108,6 +108,9 @@ impl<'a> VerificationHelper for Helper<'a> { match results.get(0) { Some(VerificationResult::GoodChecksum(..)) => good = true, + Some(VerificationResult::NotAlive(..)) => + return Err(failure::err_msg( + "Signature good, but not alive")), Some(VerificationResult::MissingKey(_)) => return Err(failure::err_msg( "Missing key to verify signature")), diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index 29e3e85e..4d07b483 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -152,6 +152,12 @@ pub enum VerificationResult<'a> { &'a key::UnspecifiedPublic, Option<&'a Signature>, RevocationStatus<'a>), + /// The signature is good, but it is not alive at the specified + /// time. + /// + /// See `SubpacketAreas::signature_alive` for a definition of + /// liveness. + NotAlive(Signature), /// Unable to verify the signature because the key is missing. MissingKey(Signature), /// The signature is bad. @@ -164,6 +170,7 @@ impl<'a> VerificationResult<'a> { use self::VerificationResult::*; match self { &GoodChecksum(ref sig, ..) => sig.level(), + &NotAlive(ref sig, ..) => sig.level(), &MissingKey(ref sig) => sig.level(), &BadChecksum(ref sig) => sig.level(), } @@ -597,33 +604,34 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { IMessageLayer::SignatureGroup { sigs, .. } => { results.new_signature_group(); for sig in sigs.into_iter() { - results.push_verification_result( - if let Some(issuer) = sig.get_issuer() { - if let Some((i, j)) = - self.keys.get(&issuer) - { - let tpk = &self.tpks[*i]; - let (binding, revocation, key) - = tpk.keys_all().nth(*j) - .unwrap(); - if sig.verify(key).unwrap_or(false) - && sig.signature_alive(self.time) - { + let r = if let Some(issuer) = sig.get_issuer() { + if let Some((i, j)) = + self.keys.get(&issuer) + { + let tpk = &self.tpks[*i]; + let (binding, revocation, key) + = tpk.keys_all().nth(*j).unwrap(); + if sig.verify(key).unwrap_or(false) { + if sig.signature_alive(self.time) { VerificationResult::GoodChecksum (sig, tpk, key, binding, revocation) + } else if !sig.signature_alive(self.time) { + VerificationResult::NotAlive(sig) } else { - VerificationResult::BadChecksum - (sig) + VerificationResult::BadChecksum(sig) } } else { - VerificationResult::MissingKey(sig) + VerificationResult::BadChecksum(sig) } } else { - // No issuer. - VerificationResult::BadChecksum(sig) + VerificationResult::MissingKey(sig) } - ) + } else { + // No issuer. + VerificationResult::BadChecksum(sig) + }; + results.push_verification_result(r) } }, } @@ -1614,6 +1622,7 @@ mod test { match result { GoodChecksum(..) => self.good += 1, MissingKey(_) => self.unknown += 1, + NotAlive(_) => self.bad += 1, BadChecksum(_) => self.bad += 1, } } diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs index c637da4a..21521e90 100644 --- a/tool/src/commands/mod.rs +++ b/tool/src/commands/mod.rs @@ -229,6 +229,7 @@ impl<'a> VHelper<'a> { for result in results { let (issuer, level) = match result { GoodChecksum(ref sig, ..) => (sig.get_issuer(), sig.level()), + NotAlive(ref sig) => (sig.get_issuer(), sig.level()), MissingKey(ref sig) => (sig.get_issuer(), sig.level()), BadChecksum(ref sig) => (sig.get_issuer(), sig.level()), }; @@ -258,6 +259,23 @@ impl<'a> VHelper<'a> { self.good_checksums += 1; } }, + NotAlive(_) => { + if let Some(issuer) = issuer { + let issuer_str = format!("{}", issuer); + eprintln!("Good, but not alive {} from {}", what, + self.labels.get(&issuer).unwrap_or( + &issuer_str)); + } else { + eprintln!("Good, but not alive signature from {} \ + without issuer information", + what); + } + if trusted { + self.bad_signatures += 1; + } else { + self.bad_checksums += 1; + } + }, MissingKey(_) => { let issuer = issuer .expect("missing key checksum has an issuer"); |