diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-11-26 16:41:58 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-11-27 13:02:12 +0100 |
commit | 0eccc8747c26e4676f2d2f8739e89f03357f87e0 (patch) | |
tree | 20d89933d51472fd2cc7b63b6c62b3446c585e31 | |
parent | c64eb5733fa217f10e51f24dd1d6614703f0d828 (diff) |
openpgp: Make variants of VerificationResult struct-like, add infos.
-rw-r--r-- | guide/src/chapter_01.md | 32 | ||||
-rw-r--r-- | ipc/examples/gpg-agent-decrypt.rs | 33 | ||||
-rw-r--r-- | ipc/tests/gpg-agent.rs | 8 | ||||
-rw-r--r-- | openpgp-ffi/examples/decrypt-with.c | 32 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp.h | 12 | ||||
-rw-r--r-- | openpgp-ffi/src/parse/stream.rs | 71 | ||||
-rw-r--r-- | openpgp/examples/decrypt-with.rs | 30 | ||||
-rw-r--r-- | openpgp/examples/generate-sign-verify.rs | 8 | ||||
-rw-r--r-- | openpgp/src/parse/stream.rs | 154 | ||||
-rw-r--r-- | openpgp/src/serialize/stream.rs | 4 | ||||
-rw-r--r-- | tool/src/commands/mod.rs | 68 |
11 files changed, 227 insertions, 225 deletions
diff --git a/guide/src/chapter_01.md b/guide/src/chapter_01.md index b2b143bb..889e82f1 100644 --- a/guide/src/chapter_01.md +++ b/guide/src/chapter_01.md @@ -118,15 +118,15 @@ fn main() { # // whether the signature checks out mathematically, we apply # // our policy. # match results.get(0) { -# Some(VerificationResult::GoodChecksum(..)) => +# Some(VerificationResult::GoodChecksum { .. }) => # good = true, -# Some(VerificationResult::NotAlive(_)) => +# Some(VerificationResult::NotAlive { .. }) => # return Err(failure::err_msg( # "Good, but not alive signature")), -# Some(VerificationResult::MissingKey(_)) => +# Some(VerificationResult::MissingKey { .. }) => # return Err(failure::err_msg( # "Missing key to verify signature")), -# Some(VerificationResult::BadChecksum(_)) => +# Some(VerificationResult::BadChecksum { .. }) => # return Err(failure::err_msg("Bad signature")), # None => # return Err(failure::err_msg("No signature")), @@ -264,15 +264,15 @@ fn generate() -> openpgp::Result<openpgp::TPK> { # // whether the signature checks out mathematically, we apply # // our policy. # match results.get(0) { -# Some(VerificationResult::GoodChecksum(..)) => +# Some(VerificationResult::GoodChecksum { .. }) => # good = true, -# Some(VerificationResult::NotAlive(_)) => +# Some(VerificationResult::NotAlive { .. }) => # return Err(failure::err_msg( # "Good, but not alive signature")), -# Some(VerificationResult::MissingKey(_)) => +# Some(VerificationResult::MissingKey { .. }) => # return Err(failure::err_msg( # "Missing key to verify signature")), -# Some(VerificationResult::BadChecksum(_)) => +# Some(VerificationResult::BadChecksum { .. }) => # return Err(failure::err_msg("Bad signature")), # None => # return Err(failure::err_msg("No signature")), @@ -410,15 +410,15 @@ fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::TPK) # // whether the signature checks out mathematically, we apply # // our policy. # match results.get(0) { -# Some(VerificationResult::GoodChecksum(..)) => +# Some(VerificationResult::GoodChecksum { .. }) => # good = true, -# Some(VerificationResult::NotAlive(_)) => +# Some(VerificationResult::NotAlive { .. }) => # return Err(failure::err_msg( # "Good, but not alive signature")), -# Some(VerificationResult::MissingKey(_)) => +# Some(VerificationResult::MissingKey { .. }) => # return Err(failure::err_msg( # "Missing key to verify signature")), -# Some(VerificationResult::BadChecksum(_)) => +# Some(VerificationResult::BadChecksum { .. }) => # return Err(failure::err_msg("Bad signature")), # None => # return Err(failure::err_msg("No signature")), @@ -567,15 +567,15 @@ impl<'a> VerificationHelper for Helper<'a> { // whether the signature checks out mathematically, we apply // our policy. match results.get(0) { - Some(VerificationResult::GoodChecksum(..)) => + Some(VerificationResult::GoodChecksum { .. }) => good = true, - Some(VerificationResult::NotAlive(_)) => + Some(VerificationResult::NotAlive { .. }) => return Err(failure::err_msg( "Good, but not alive signature")), - Some(VerificationResult::MissingKey(_)) => + Some(VerificationResult::MissingKey { .. }) => return Err(failure::err_msg( "Missing key to verify signature")), - Some(VerificationResult::BadChecksum(_)) => + Some(VerificationResult::BadChecksum { .. }) => return Err(failure::err_msg("Bad signature")), None => return Err(failure::err_msg("No signature")), diff --git a/ipc/examples/gpg-agent-decrypt.rs b/ipc/examples/gpg-agent-decrypt.rs index 2b8b7049..3eeb140d 100644 --- a/ipc/examples/gpg-agent-decrypt.rs +++ b/ipc/examples/gpg-agent-decrypt.rs @@ -133,32 +133,19 @@ impl<'a> VerificationHelper for Helper<'a> { MessageLayer::SignatureGroup { ref results } => for result in results { match result { - GoodChecksum(ref sig, ..) => { - let issuer = sig.issuer() - .expect("good checksum has an issuer"); - eprintln!("Good signature from {}", issuer); + GoodChecksum { tpk, .. } => { + eprintln!("Good signature from {}", tpk); }, - NotAlive(ref sig) => { - let issuer = sig.issuer() - .expect("Good, but not live signature has an \ - issuer"); - eprintln!("Good, but not live signature from {}", - issuer); + NotAlive { tpk, .. } => { + eprintln!("Good, but not alive signature from {}", + tpk); }, - MissingKey(ref sig) => { - let issuer = sig.issuer() - .expect("missing key checksum has an \ - issuer"); - eprintln!("No key to check signature from {}", - issuer); + MissingKey { .. } => { + eprintln!("No key to check signature"); + }, + BadChecksum { tpk, .. } => { + eprintln!("Bad signature from {}", tpk); }, - BadChecksum(ref sig) => - if let Some(issuer) = sig.issuer() { - eprintln!("Bad signature from {}", issuer); - } else { - eprintln!("Bad signature without issuer \ - information"); - }, } } } diff --git a/ipc/tests/gpg-agent.rs b/ipc/tests/gpg-agent.rs index 69d45afb..5ebdd281 100644 --- a/ipc/tests/gpg-agent.rs +++ b/ipc/tests/gpg-agent.rs @@ -161,15 +161,15 @@ fn sign() { // whether the signature checks out mathematically, we apply // our policy. match results.get(0) { - Some(VerificationResult::GoodChecksum(..)) => + Some(VerificationResult::GoodChecksum { .. }) => good = true, - Some(VerificationResult::NotAlive(_)) => + Some(VerificationResult::NotAlive { .. }) => return Err(failure::err_msg( "Good, but not live signature")), - Some(VerificationResult::MissingKey(_)) => + Some(VerificationResult::MissingKey { .. }) => return Err(failure::err_msg( "Missing key to verify signature")), - Some(VerificationResult::BadChecksum(_)) => + Some(VerificationResult::BadChecksum { .. }) => return Err(failure::err_msg("Bad signature")), None => return Err(failure::err_msg("No signature")), diff --git a/openpgp-ffi/examples/decrypt-with.c b/openpgp-ffi/examples/decrypt-with.c index 8343f34d..ada4dfd7 100644 --- a/openpgp-ffi/examples/decrypt-with.c +++ b/openpgp-ffi/examples/decrypt-with.c @@ -72,19 +72,29 @@ check_cb (void *cookie_opaque, pgp_message_structure_t structure) pgp_verification_result_iter_next (results); result; result = pgp_verification_result_iter_next (results)) { - pgp_signature_t sig; + pgp_signature_t sig = NULL; + pgp_key_t key = NULL; pgp_keyid_t keyid; char *keyid_str = NULL; switch (pgp_verification_result_variant (result)) { case PGP_VERIFICATION_RESULT_GOOD_CHECKSUM: - pgp_verification_result_good_checksum (result, &sig, NULL, - NULL, NULL, NULL); - keyid = pgp_signature_issuer (sig); + pgp_verification_result_good_checksum (result, NULL, NULL, + &key, NULL, NULL); + keyid = pgp_key_keyid (key); keyid_str = pgp_keyid_to_string (keyid); fprintf (stderr, "Good signature from %s\n", keyid_str); break; + case PGP_VERIFICATION_RESULT_NOT_ALIVE: + pgp_verification_result_not_alive (result, NULL, NULL, + &key, NULL, NULL); + keyid = pgp_key_keyid (key); + keyid_str = pgp_keyid_to_string (keyid); + fprintf (stderr, "Good checksum, but not alive signature from %s\n", + keyid_str); + break; + case PGP_VERIFICATION_RESULT_MISSING_KEY: pgp_verification_result_missing_key (result, &sig); keyid = pgp_signature_issuer (sig); @@ -93,14 +103,11 @@ check_cb (void *cookie_opaque, pgp_message_structure_t structure) break; case PGP_VERIFICATION_RESULT_BAD_CHECKSUM: - pgp_verification_result_bad_checksum (result, &sig); - keyid = pgp_signature_issuer (sig); - if (keyid) { - keyid_str = pgp_keyid_to_string (keyid); - fprintf (stderr, "Bad signature from %s\n", keyid_str); - } else { - fprintf (stderr, "Bad signature without issuer information\n"); - } + pgp_verification_result_bad_checksum (result, NULL, NULL, + &key, NULL, NULL); + keyid = pgp_key_keyid (key); + keyid_str = pgp_keyid_to_string (keyid); + fprintf (stderr, "Bad signature from %s\n", keyid_str); break; default: @@ -108,6 +115,7 @@ check_cb (void *cookie_opaque, pgp_message_structure_t structure) } free (keyid_str); pgp_signature_free (sig); + pgp_key_free (key); pgp_verification_result_free (result); } pgp_verification_result_iter_free (results); diff --git a/openpgp-ffi/include/sequoia/openpgp.h b/openpgp-ffi/include/sequoia/openpgp.h index 4339d509..6f7be6d1 100644 --- a/openpgp-ffi/include/sequoia/openpgp.h +++ b/openpgp-ffi/include/sequoia/openpgp.h @@ -1722,11 +1722,19 @@ bool pgp_verification_result_good_checksum (pgp_verification_result_t, pgp_signature_t *, pgp_revocation_status_t *); bool pgp_verification_result_not_alive (pgp_verification_result_t, - pgp_signature_t *); + pgp_signature_t *, + pgp_tpk_t *, + pgp_key_t *, + pgp_signature_t *, + pgp_revocation_status_t *); bool pgp_verification_result_missing_key (pgp_verification_result_t, pgp_signature_t *); bool pgp_verification_result_bad_checksum (pgp_verification_result_t, - pgp_signature_t *); + pgp_signature_t *, + pgp_tpk_t *, + pgp_key_t *, + pgp_signature_t *, + pgp_revocation_status_t *); /*/ /// Decrypts an OpenPGP message. diff --git a/openpgp-ffi/src/parse/stream.rs b/openpgp-ffi/src/parse/stream.rs index 0dbe3408..608c7b85 100644 --- a/openpgp-ffi/src/parse/stream.rs +++ b/openpgp-ffi/src/parse/stream.rs @@ -169,20 +169,17 @@ fn pgp_verification_result_variant(result: *const VerificationResult) { use self::stream::VerificationResult::*; match result.ref_raw() { - GoodChecksum(..) => 1, - MissingKey(_) => 2, - BadChecksum(_) => 3, - NotAlive(_) => 4, + GoodChecksum { .. } => 1, + MissingKey { .. } => 2, + BadChecksum { .. } => 3, + NotAlive { .. } => 4, } } -/// Decomposes a `VerificationResult::GoodChecksum`. -/// -/// Returns `true` iff the given value is a -/// `VerificationResult::GoodChecksum`, and returns the variants members -/// in `sig_r` and the like iff `sig_r != NULL`. +macro_rules! make_decomposition_fn { + ($fn_name:ident, $variant:path) => { #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" -fn pgp_verification_result_good_checksum<'a>( +fn $fn_name<'a>( result: *const VerificationResult<'a>, sig_r: Maybe<*mut Signature>, tpk_r: Maybe<*mut TPK>, @@ -193,9 +190,7 @@ fn pgp_verification_result_good_checksum<'a>( -> bool { use self::stream::VerificationResult::*; - if let GoodChecksum(ref sig, ref tpk, ref key, ref binding, ref revocation) - = result.ref_raw() - { + if let $variant { sig, tpk, key, binding, revoked } = result.ref_raw() { if let Some(mut p) = sig_r { *unsafe { p.as_mut() } = sig.move_into_raw(); } @@ -213,36 +208,29 @@ fn pgp_verification_result_good_checksum<'a>( *unsafe { p.as_mut() } = binding.move_into_raw(); } if let Some(mut p) = revocation_status_r { - *unsafe { p.as_mut() } = revocation.move_into_raw(); + *unsafe { p.as_mut() } = revoked.move_into_raw(); } true } else { false } } + } +} + +/// Decomposes a `VerificationResult::GoodChecksum`. +/// +/// Returns `true` iff the given value is a +/// `VerificationResult::GoodChecksum`, and returns the variants members +/// in `sig_r` and the like iff `sig_r != NULL`. +make_decomposition_fn!(pgp_verification_result_good_checksum, GoodChecksum); /// 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 - } -} +make_decomposition_fn!(pgp_verification_result_not_alive, NotAlive); /// Decomposes a `VerificationResult::MissingKey`. /// @@ -256,8 +244,7 @@ fn pgp_verification_result_missing_key<'a>( -> bool { use self::stream::VerificationResult::*; - if let MissingKey(ref sig) = result.ref_raw() - { + if let MissingKey { sig, .. } = result.ref_raw() { if let Some(mut p) = sig_r { *unsafe { p.as_mut() } = sig.move_into_raw(); } @@ -272,23 +259,7 @@ fn pgp_verification_result_missing_key<'a>( /// Returns `true` iff the given value is a /// `VerificationResult::BadChecksum`, and returns the variants /// 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_bad_checksum<'a>( - result: *const VerificationResult<'a>, - sig_r: Maybe<*mut Signature>) - -> bool -{ - use self::stream::VerificationResult::*; - if let BadChecksum(ref sig) = result.ref_raw() - { - if let Some(mut p) = sig_r { - *unsafe { p.as_mut() } = sig.move_into_raw(); - } - true - } else { - false - } -} +make_decomposition_fn!(pgp_verification_result_bad_checksum, BadChecksum); /// Passed as the first argument to the callbacks used by pgp_verify /// and pgp_decrypt. diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs index e3b861e5..050f54d0 100644 --- a/openpgp/examples/decrypt-with.rs +++ b/openpgp/examples/decrypt-with.rs @@ -126,31 +126,19 @@ impl VerificationHelper for Helper { MessageLayer::SignatureGroup { ref results } => for result in results { match result { - GoodChecksum(ref sig, ..) => { - let issuer = sig.issuer() - .expect("good checksum has an issuer"); - eprintln!("Good signature from {}", issuer); + GoodChecksum { tpk, .. } => { + eprintln!("Good signature from {}", tpk); }, - NotAlive(ref sig) => { - let issuer = sig.issuer() - .expect("not alive has an issuer"); + NotAlive { tpk, .. } => { eprintln!("Good, but not alive signature from {}", - issuer); + tpk); }, - MissingKey(ref sig) => { - let issuer = sig.issuer() - .expect("missing key checksum has an \ - issuer"); - eprintln!("No key to check signature from {}", - issuer); + MissingKey { .. } => { + eprintln!("No key to check signature"); + }, + BadChecksum { tpk, .. } => { + eprintln!("Bad signature from {}", tpk); }, - BadChecksum(ref sig) => - if let Some(issuer) = sig.issuer() { - eprintln!("Bad signature from {}", issuer); - } else { - eprintln!("Bad signature without issuer \ - information"); - }, } } } diff --git a/openpgp/examples/generate-sign-verify.rs b/openpgp/examples/generate-sign-verify.rs index 0ab1c7a5..6c43f25c 100644 --- a/openpgp/examples/generate-sign-verify.rs +++ b/openpgp/examples/generate-sign-verify.rs @@ -106,15 +106,15 @@ impl<'a> VerificationHelper for Helper<'a> { // whether the signature checks out mathematically, we apply // our policy. match results.get(0) { - Some(VerificationResult::GoodChecksum(..)) => + Some(VerificationResult::GoodChecksum { .. }) => good = true, - Some(VerificationResult::NotAlive(..)) => + Some(VerificationResult::NotAlive { .. }) => return Err(failure::err_msg( "Signature good, but not alive")), - Some(VerificationResult::MissingKey(_)) => + Some(VerificationResult::MissingKey { .. }) => return Err(failure::err_msg( "Missing key to verify signature")), - Some(VerificationResult::BadChecksum(_)) => + Some(VerificationResult::BadChecksum { .. }) => return Err(failure::err_msg("Bad signature")), None => return Err(failure::err_msg("No signature")), diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index 66937de1..a23cda9f 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -149,21 +149,68 @@ pub enum VerificationResult<'a> { /// model, such as the [web of trust] (WoT). /// /// [web of trust]: https://en.wikipedia.org/wiki/Web_of_trust - GoodChecksum(Signature, - &'a TPK, - &'a key::UnspecifiedPublic, - Option<&'a Signature>, - RevocationStatus<'a>), + GoodChecksum { + /// The signature. + sig: Signature, + + /// The signature's issuer. + tpk: &'a TPK, + + /// The signing key that made the signature. + key: &'a key::UnspecifiedPublic, + + /// The signing key's binding signature. + binding: Option<&'a Signature>, + + /// The signing key's revocation status + revoked: 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), + NotAlive { + /// The signature. + sig: Signature, + + /// The signature's issuer. + tpk: &'a TPK, + + /// The signing key that made the signature. + key: &'a key::UnspecifiedPublic, + + /// The signing key's binding signature. + binding: Option<&'a Signature>, + + /// The signing key's revocation status + revoked: RevocationStatus<'a>, + }, + /// Unable to verify the signature because the key is missing. - MissingKey(Signature), + MissingKey { + /// The signature. + sig: Signature, + }, + /// The signature is bad. - BadChecksum(Signature), + BadChecksum { + /// The signature. + sig: Signature, + + /// The signature's issuer. + tpk: &'a TPK, + + /// The signing key that made the signature. + key: &'a key::UnspecifiedPublic, + + /// The signing key's binding signature. + binding: Option<&'a Signature>, + + /// The signing key's revocation status + revoked: RevocationStatus<'a>, + }, } impl<'a> VerificationResult<'a> { @@ -171,10 +218,10 @@ impl<'a> VerificationResult<'a> { pub fn level(&self) -> usize { 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(), + GoodChecksum { sig, .. } => sig.level(), + NotAlive { sig, .. } => sig.level(), + MissingKey { sig, .. } => sig.level(), + BadChecksum { sig, .. } => sig.level(), } } } @@ -609,32 +656,37 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { IMessageLayer::SignatureGroup { sigs, .. } => { results.new_signature_group(); for sig in sigs.into_iter() { - let r = if let Some(issuer) = sig.get_issuer() { - if let Some((i, j)) = + if let Some(issuer) = sig.get_issuer() { + let r = if let Some((i, j)) = self.keys.get(&issuer) { let tpk = &self.tpks[*i]; - let (binding, revocation, key) + let (binding, revoked, key) = tpk.keys_all().nth(*j).unwrap(); if sig.verify(key).unwrap_or(false) { if sig.signature_alive(self.time, None) { - VerificationResult::GoodChecksum - (sig, tpk, key, binding, - revocation) + VerificationResult::GoodChecksum { + sig, tpk, key, binding, revoked, + } } else { - VerificationResult::NotAlive(sig) + VerificationResult::NotAlive { + sig, tpk, key, binding, revoked, + } } } else { - VerificationResult::BadChecksum(sig) + VerificationResult::BadChecksum { + sig, tpk, key, binding, revoked, + } } } else { - VerificationResult::MissingKey(sig) - } + VerificationResult::MissingKey { + sig, + } + }; + results.push_verification_result(r); } else { - // No issuer. - VerificationResult::BadChecksum(sig) - }; - results.push_verification_result(r) + // No issuer, ignore malformed signature. |