From 75d4e6dda12e8b7ae8573227e61e718ede3f2cfc Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Thu, 9 May 2019 15:19:24 +0200 Subject: openpgp: Communicate message structure from the decryptor. - Fixes #100. --- openpgp/examples/decrypt-with.rs | 44 ++++++++++++++++++++++-- openpgp/examples/generate-encrypt-decrypt.rs | 2 +- openpgp/examples/generate-sign-verify.rs | 51 +++++++++++++++++----------- 3 files changed, 74 insertions(+), 23 deletions(-) (limited to 'openpgp/examples') diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs index 908b8650..63582299 100644 --- a/openpgp/examples/decrypt-with.rs +++ b/openpgp/examples/decrypt-with.rs @@ -17,6 +17,8 @@ use openpgp::parse::{ Decryptor, VerificationHelper, VerificationResult, + MessageStructure, + MessageLayer, }, }; @@ -95,7 +97,7 @@ impl DecryptionHelper for Helper { } // XXX: In production code, return the Fingerprint of the // recipient's TPK here - Ok(None) + Ok(None) } } @@ -104,8 +106,46 @@ impl VerificationHelper for Helper { -> failure::Fallible> { Ok(Vec::new()) // Feed the TPKs to the verifier here. } - fn check(&mut self, _sigs: Vec>) + fn check(&mut self, structure: &MessageStructure) -> failure::Fallible<()> { + use self::VerificationResult::*; + for layer in structure.iter() { + match layer { + MessageLayer::Compression { algo } => + eprintln!("Compressed using {}", algo), + MessageLayer::Encryption { sym_algo, aead_algo } => + if let Some(aead_algo) = aead_algo { + eprintln!("Encrypted and protected using {}/{}", + sym_algo, aead_algo); + } else { + eprintln!("Encrypted using {}", sym_algo); + }, + 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); + }, + MissingKey(ref sig) => { + let issuer = sig.issuer() + .expect("missing key checksum has an \ + issuer"); + eprintln!("No key to check signature from {}", + issuer); + }, + BadChecksum(ref sig) => + if let Some(issuer) = sig.issuer() { + eprintln!("Bad signature from {}", issuer); + } else { + eprintln!("Bad signature without issuer \ + information"); + }, + } + } + } + } Ok(()) // Implement your verification policy here. } } diff --git a/openpgp/examples/generate-encrypt-decrypt.rs b/openpgp/examples/generate-encrypt-decrypt.rs index c338f154..4645cb0c 100644 --- a/openpgp/examples/generate-encrypt-decrypt.rs +++ b/openpgp/examples/generate-encrypt-decrypt.rs @@ -93,7 +93,7 @@ impl<'a> VerificationHelper for Helper<'a> { Ok(Vec::new()) } - fn check(&mut self, _sigs: Vec>) + fn check(&mut self, _structure: &MessageStructure) -> openpgp::Result<()> { // Implement your signature verification policy here. Ok(()) diff --git a/openpgp/examples/generate-sign-verify.rs b/openpgp/examples/generate-sign-verify.rs index 0ebb3d1e..70899c81 100644 --- a/openpgp/examples/generate-sign-verify.rs +++ b/openpgp/examples/generate-sign-verify.rs @@ -92,30 +92,41 @@ impl<'a> VerificationHelper for Helper<'a> { Ok(vec![self.tpk.clone()]) } - fn check(&mut self, sigs: Vec>) + fn check(&mut self, structure: &MessageStructure) -> openpgp::Result<()> { // In this function, we implement our signature verification // policy. - // First, we are interested in signatures over the data, - // i.e. level 0 signatures. - let sigs_over_data = sigs.get(0) - .ok_or_else(|| failure::err_msg("No level 0 signatures found"))?; - - // Now, let's see if there is a signature on that level. - let sig_result = sigs_over_data.get(0) - .ok_or_else(|| failure::err_msg("No signature found"))?; - - // Finally, given a VerificationResult, which only says - // whether the signature checks out mathematically, we apply - // our policy. - match sig_result { - VerificationResult::GoodChecksum(..) => - Ok(()), // Good signature - VerificationResult::MissingKey(_) => - Err(failure::err_msg("Missing key to verify signature")), - VerificationResult::BadChecksum(_) => - Err(failure::err_msg("Bad signature")), + let mut good = false; + for (i, layer) in structure.iter().enumerate() { + match (i, layer) { + // First, we are interested in signatures over the + // data, i.e. level 0 signatures. + (0, MessageLayer::SignatureGroup { ref results }) => { + // Finally, given a VerificationResult, which only says + // whether the signature checks out mathematically, we apply + // our policy. + match results.get(0) { + Some(VerificationResult::GoodChecksum(..)) => + good = true, + Some(VerificationResult::MissingKey(_)) => + return Err(failure::err_msg( + "Missing key to verify signature")), + Some(VerificationResult::BadChecksum(_)) => + return Err(failure::err_msg("Bad signature")), + None => + return Err(failure::err_msg("No signature")), + } + }, + _ => return Err(failure::err_msg( + "Unexpected message structure")), + } + } + + if good { + Ok(()) // Good signature. + } else { + Err(failure::err_msg("Signature verification failed")) } } } -- cgit v1.2.3