summaryrefslogtreecommitdiffstats
path: root/openpgp
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp')
-rw-r--r--openpgp/examples/decrypt-with.rs19
-rw-r--r--openpgp/examples/generate-sign-verify.rs12
-rw-r--r--openpgp/src/parse/stream.rs265
-rw-r--r--openpgp/src/policy.rs12
-rw-r--r--openpgp/src/serialize/stream.rs10
5 files changed, 152 insertions, 166 deletions
diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs
index c4b9f56a..ca84a918 100644
--- a/openpgp/examples/decrypt-with.rs
+++ b/openpgp/examples/decrypt-with.rs
@@ -16,7 +16,7 @@ use crate::openpgp::parse::{
DecryptionHelper,
Decryptor,
VerificationHelper,
- VerificationResult,
+ GoodChecksum,
MessageStructure,
MessageLayer,
},
@@ -108,7 +108,6 @@ impl VerificationHelper for Helper {
}
fn check(&mut self, structure: MessageStructure)
-> failure::Fallible<()> {
- use self::VerificationResult::*;
for layer in structure.iter() {
match layer {
MessageLayer::Compression { algo } =>
@@ -123,19 +122,11 @@ impl VerificationHelper for Helper {
MessageLayer::SignatureGroup { ref results } =>
for result in results {
match result {
- GoodChecksum { cert, .. } => {
- eprintln!("Good signature from {}", cert);
- },
- NotAlive { sig, .. } => {
- eprintln!("Good, but not alive signature from {:?}",
- sig.get_issuers());
- },
- MissingKey { .. } => {
- eprintln!("No key to check signature");
- },
- Error { error, .. } => {
- eprintln!("Error: {}", error);
+ Ok(GoodChecksum { ka, .. }) => {
+ eprintln!("Good signature from {}", ka.cert());
},
+ Err(e) =>
+ eprintln!("Error: {:?}", e),
}
}
}
diff --git a/openpgp/examples/generate-sign-verify.rs b/openpgp/examples/generate-sign-verify.rs
index d371a812..e5f21505 100644
--- a/openpgp/examples/generate-sign-verify.rs
+++ b/openpgp/examples/generate-sign-verify.rs
@@ -113,16 +113,10 @@ impl<'a> VerificationHelper for Helper<'a> {
// whether the signature checks out mathematically, we apply
// our policy.
match results.into_iter().next() {
- Some(VerificationResult::GoodChecksum { .. }) =>
+ Some(Ok(_)) =>
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")),
- Some(VerificationResult::Error { error, .. }) =>
- return Err(error),
+ Some(Err(e)) =>
+ return Err(openpgp::Error::from(e).into()),
None =>
return Err(failure::err_msg("No signature")),
}
diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs
index 891a88ef..c458ed7b 100644
--- a/openpgp/src/parse/stream.rs
+++ b/openpgp/src/parse/stream.rs
@@ -64,90 +64,113 @@ const TRACE : bool = false;
/// How much data to buffer before giving it to the caller.
const BUFFER_SIZE: usize = 25 * 1024 * 1024;
-/// Contains the result of a signature verification.
+/// The result of a signature verification.
+pub type VerificationResult<'a> =
+ std::result::Result<GoodChecksum<'a>, VerificationError<'a>>;
+
+/// The signature is good.
+///
+/// A signature is considered good if:
+///
+/// - The signature has a Signature Creation Time subpacket.
+///
+/// - The signature is alive at the specified time (the time
+/// parameter passed to, e.g., `Verifier::from_reader`).
+///
+/// - The certificate is alive and not revoked as of the signature's
+/// creation time.
+///
+/// - The signing key is alive, not revoked, and signing capable as
+/// of the signature's creation time.
+///
+/// - The signature was generated by the signing key.
+///
+/// Note: This doesn't mean that the key that generated the
+/// signature is in anyway trustworthy in the sense that it
+/// belongs to the person or entity that the user thinks it
+/// belongs to. This property can only be evaluated within a
+/// trust model, such as the [web of trust] (WoT). This policy is
+/// normally implemented in the `VerificationHelper::check`
+/// method.
+///
+/// [web of trust]: https://en.wikipedia.org/wiki/Web_of_trust
#[derive(Debug)]
-pub enum VerificationResult<'a> {
- /// The signature is good.
- ///
- /// A signature is considered good if:
- ///
- /// - The signature has a Signature Creation Time subpacket.
- ///
- /// - The signature is alive at the specified time (the time
- /// parameter passed to, e.g., `Verifier::from_reader`).
- ///
- /// - The certificate is alive and not revoked as of the
- /// signature's creation time.
- ///
- /// - The signing key is alive, not revoked, and signing
- /// capable as of the signature's creation time.
- ///
- /// - The signature was generated by the signing key.
- ///
- /// Note: This doesn't mean that the key that generated the
- /// signature is in anyway trustworthy in the sense that it
- /// belongs to the person or entity that the user thinks it
- /// belongs to. This property can only be evaluated within a
- /// trust model, such as the [web of trust] (WoT). This
- /// policy is normally implemented in the
- /// `VerificationHelper::check` method.
- ///
- /// [web of trust]: https://en.wikipedia.org/wiki/Web_of_trust
- GoodChecksum {
+pub struct GoodChecksum<'a> {
+ /// The signature.
+ pub sig: Signature,
+
+ /// The signing key that made the signature.
+ pub ka: ValidKeyAmalgamation<'a, key::PublicParts>,
+}
+
+/// Possible errors during signature verifications.
+#[derive(Debug)]
+pub enum VerificationError<'a> {
+ /// Malformed signature (no signature creation subpacket, etc.)
+ MalformedSignature {
/// The signature.
sig: Signature,
- /// The signature's issuer.
- cert: &'a Cert,
-
- /// The signing key that made the signature.
- ka: ValidKeyAmalgamation<'a, key::PublicParts>,
+ /// The reason why the signature is malformed.
+ error: failure::Error,
},
-
- /// The signature is good, but it is not alive at the specified
- /// time.
- ///
- /// See `SubpacketAreas::signature_alive` for a definition of
- /// liveness.
- NotAlive {
+ /// Missing Key
+ MissingKey {
/// The signature.
sig: Signature,
},
-
- /// Unable to verify the signature because the key is missing.
- MissingKey {
+ /// Unbound key.
+ ///
+ /// There is no valid binding signature at the time the signature
+ /// was created under the given policy.
+ UnboundKey {
/// The signature.
sig: Signature,
+
+ /// The certificate that made the signature.
+ cert: &'a Cert,
+
+ /// The reason why the key is bad.
+ error: failure::Error,
},
+ /// Bad key (have a key, but it is not alive, etc.)
+ BadKey {
+ /// The signature.
+ sig: Signature,
- /// An error occurred while verifying the signature.
- ///
- /// This could occur if the signature is invalid (e.g., no
- /// Signature Creation Time packet), the key is invalid (e.g., the
- /// key is not alive, the key is revoked, the key is not signing
- /// capable), etc.
- Error {
+ /// The signing key that made the signature.
+ ka: ValidKeyAmalgamation<'a, key::PublicParts>,
+
+ /// The reason why the key is bad.
+ error: failure::Error,
+ },
+ /// Bad signature (have a valid key, but the signature didn't check out)
+ BadSignature {
/// The signature.
sig: Signature,
- /// The reason.
+ /// The signing key that made the signature.
+ ka: ValidKeyAmalgamation<'a, key::PublicParts>,
+
+ /// The reason why the signature is bad.
error: failure::Error,
},
}
-impl<'a> VerificationResult<'a> {
- /// Gets the signature level.
- ///
- /// A level of 0 indicates that the signature is directly over the
- /// data, a level of 1 means that the signature is a notarization
- /// over all level 0 signatures and the data, and so on.
- pub fn level(&self) -> usize {
- use self::VerificationResult::*;
- match self {
- GoodChecksum { sig, .. } => sig.level(),
- NotAlive { sig, .. } => sig.level(),
- MissingKey { sig, .. } => sig.level(),
- Error { sig, .. } => sig.level(),
+impl<'a> From<VerificationError<'a>> for Error {
+ fn from(e: VerificationError<'a>) -> Self {
+ use self::VerificationError::*;
+ match e {
+ MalformedSignature { error, .. } =>
+ Error::MalformedPacket(error.to_string()),
+ MissingKey { .. } =>
+ Error::InvalidKey("Could not locate signing key".into()),
+ UnboundKey { error, .. } =>
+ Error::InvalidKey(error.to_string()),
+ BadKey { error, .. } =>
+ Error::InvalidKey(error.to_string()),
+ BadSignature { error, .. } =>
+ Error::BadSignature(error.to_string()),
}
}
}
@@ -1449,32 +1472,19 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
} else {
// Invalid signature.
results.push_verification_result(
- VerificationResult::Error {
+ Err(VerificationError::MalformedSignature {
sig,
error: Error::MalformedPacket(
"missing a Signature Creation Time \
subpacket"
- .into()).into()
- });
+ .into()).into(),
+ }));
t!("{:02X}{:02X}: Missing a signature creation time subpacket",
sigid[0], sigid[1]);
continue;
};
- if let Err(err) = sig.signature_alive(
- self.time, self.clock_skew_tolerance)
- {
- // Invalid signature.
- results.push_verification_result(
- VerificationResult::NotAlive {
- sig: sig.clone(),
- });
- t!("{:02X}{:02X}: Signature not alive: {}",
- sigid[0], sigid[1], err);
- continue;
- }
-
- let mut err = VerificationResult::MissingKey {
+ let mut err = VerificationError::MissingKey {
sig: sig.clone(),
};
@@ -1484,13 +1494,15 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
cert.keys().key_handles(issuers.iter())
})
{
+ let cert = ka.cert();
let fingerprint = ka.fingerprint();
let ka = match ka.with_policy(self.policy, sig_time) {
Err(policy_err) => {
t!("{:02X}{:02X}: key {} rejected by policy: {}",
sigid[0], sigid[1], fingerprint, policy_err);
- err = VerificationResult::Error {
+ err = VerificationError::UnboundKey {
sig: sig.clone(),
+ cert,
error: policy_err,
};
continue;
@@ -1505,15 +1517,17 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
err = if let Err(err) = ka.cert_alive() {
t!("{:02X}{:02X}: cert {} not alive: {}",
sigid[0], sigid[1], ka.cert().fingerprint(), err);
- VerificationResult::Error {
+ VerificationError::BadKey {
sig: sig.clone(),
+ ka,
error: err,
}
} else if let Err(err) = ka.alive() {
t!("{:02X}{:02X}: key {} not alive: {}",
sigid[0], sigid[1], ka.fingerprint(), err);
- VerificationResult::Error {
+ VerificationError::BadKey {
sig: sig.clone(),
+ ka,
error: err,
}
} else if let
@@ -1521,8 +1535,9 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
{
t!("{:02X}{:02X}: cert {} revoked: {:?}",
sigid[0], sigid[1], ka.cert().fingerprint(), rev);
- VerificationResult::Error {
+ VerificationError::BadKey {
sig: sig.clone(),
+ ka,
error: Error::InvalidKey(
"certificate is revoked".into())
.into(),
@@ -1532,8 +1547,9 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
{
t!("{:02X}{:02X}: key {} revoked: {:?}",
sigid[0], sigid[1], ka.fingerprint(), rev);
- VerificationResult::Error {
+ VerificationError::BadKey {
sig: sig.clone(),
+ ka,
error: Error::InvalidKey(
"signing key is revoked".into())
.into(),
@@ -1541,12 +1557,23 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
} else if ! ka.for_signing() {
t!("{:02X}{:02X}: key {} not signing capable",
sigid[0], sigid[1], ka.fingerprint());
- VerificationResult::Error {
+ VerificationError::BadKey {
sig: sig.clone(),
+ ka,
error: Error::InvalidKey(
"key is not signing capable".into())
.into(),
}
+ } else if let Err(err) = sig.signature_alive(
+ self.time, self.clock_skew_tolerance)
+ {
+ t!("{:02X}{:02X}: Signature not alive: {}",
+ sigid[0], sigid[1], err);
+ VerificationError::BadSignature {
+ sig: sig.clone(),
+ ka,
+ error: err,
+ }
} else if self.identity.as_ref().map(|identity| {
let ir = sig.intended_recipients();
! ir.is_empty() && ! ir.contains(identity)
@@ -1556,8 +1583,9 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
// Treat the signature as bad.
t!("{:02X}{:02X}: not an intended recipient",
sigid[0], sigid[1]);
- VerificationResult::Error {
+ VerificationError::BadSignature {
sig: sig.clone(),
+ ka,
error: Error::BadSignature(
"Not an intended recipient".into())
.into(),
@@ -1568,19 +1596,19 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
if let Err(err) = self.policy.signature(&sig) {
t!("{:02X}{:02X}: signature rejected by policy: {}",
sigid[0], sigid[1], err);
- VerificationResult::Error {
+ VerificationError::BadSignature {
sig: sig.clone(),
+ ka,
error: err,
}
} else {
t!("{:02X}{:02X}: good checksum using {}",
sigid[0], sigid[1], ka.fingerprint());
results.push_verification_result(
- VerificationResult::GoodChecksum {
+ Ok(GoodChecksum {
sig: sig,
- cert: ka.cert(),
ka,
- });
+ }));
// Continue to the next sig.
continue 'sigs;
}
@@ -1588,8 +1616,9 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
Err(err) => {
t!("{:02X}{:02X} using {}: error: {}",
sigid[0], sigid[1], ka.fingerprint(), err);
- VerificationResult::Error {
+ VerificationError::BadSignature {
sig: sig.clone(),
+ ka,
error: err,
}
}
@@ -1597,34 +1626,8 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
}
}
- // Hmm, we didn't consider any keys. Iterate
- // over the keys again, but this time, don't
- // use a policy. If we find something now,
- // the policy must have rejected it. Turn
- // that information into a more useful (and
- // less misleading) error message than
- // `VerificationResult::MissingKey`.
- if let VerificationResult::MissingKey { .. } = err {
- if let Some(ka) = self.certs.iter()
- .flat_map(|cert| {
- cert.keys().key_handles(issuers.iter())
- })
- .next()
- {
- err = VerificationResult::Error {
- sig: sig.clone(),
- error: Error::InvalidKey(
- format!(
- "Signing key ({}) not valid \
- when signature was created",
- ka.fingerprint()))
- .into(),
- }
- }
- }
-
t!("{:02X}{:02X}: returning: {:?}", sigid[0], sigid[1], err);
- results.push_verification_result(err);
+ results.push_verification_result(Err(err));
}
}
}
@@ -1746,16 +1749,18 @@ mod test {
}
fn check(&mut self, structure: MessageStructure) -> Result<()> {
- use self::VerificationResult::*;
+ use self::VerificationError::*;
for layer in structure.iter() {
match layer {
MessageLayer::SignatureGroup { ref results } =>
for result in results {
match result {
- GoodChecksum { .. } => self.good += 1,
- MissingKey { .. } => self.unknown += 1,
- NotAlive { .. } => self.bad += 1,
- Error { error, .. } => {
+ Ok(_) => self.good += 1,
+ Err(MissingKey { .. }) => self.unknown += 1,
+ Err(UnboundKey { .. }) => self.unknown += 1,
+ Err(MalformedSignature { .. }) => self.bad += 1,
+ Err(BadKey { .. }) => self.bad += 1,
+ Err(BadSignature { error, .. }) => {
eprintln!("error: {}", error);
self.bad += 1;
},
@@ -1883,9 +1888,9 @@ mod test {
match layer {
MessageLayer::SignatureGroup { results } => {
assert_eq!(results.len(), 1);
- if let VerificationResult::MissingKey { sig, .. } =
- &results[0]
- {
+ if let Err(VerificationError::MissingKey {
+ sig, ..
+ }) = &results[0] {
assert_eq!(
&sig.issuer_fingerprint().unwrap()
.to_string(),
@@ -1895,6 +1900,8 @@ mod test {
_ => unreachable!(),
}
);
+ } else {
+ unreachable!()
}
},
_ => unreachable!(),
diff --git a/openpgp/src/policy.rs b/openpgp/src/policy.rs
index 2e31fb24..890513d5 100644
--- a/openpgp/src/policy.rs
+++ b/openpgp/src/policy.rs
@@ -566,16 +566,14 @@ mod test {
fn check(&mut self, structure: MessageStructure) -> Result<()>
{
- use crate::parse::stream::VerificationResult::*;
for layer in structure.iter() {
match layer {
MessageLayer::SignatureGroup { ref results } =>
for result in results {
eprintln!("result: {:?}", result);
match result {
- GoodChecksum { .. } => self.good += 1,
- Error { .. } => self.errors += 1,
- _ => (),
+ Ok(_) => self.good += 1,
+ Err(_) => self.errors += 1,
}
}
MessageLayer::Compression { .. } => (),
@@ -1033,15 +1031,13 @@ mod test {
fn check(&mut self, structure: MessageStructure) -> Result<()>
{
- use crate::parse::stream::VerificationResult::*;
for layer in structure.iter() {
match layer {
MessageLayer::SignatureGroup { ref results } =>
for result in results {
match result {
- GoodChecksum { .. } => self.good += 1,
- Error { .. } => self.errors += 1,
- _ => (),
+ Ok(_) => self.good += 1,
+ Err(_) => self.errors += 1,
}
}
MessageLayer::Compression { .. } => (),
diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs
index 7e30dc88..6769a17c 100644
--- a/openpgp/src/serialize/stream.rs
+++ b/openpgp/src/serialize/stream.rs
@@ -263,9 +263,8 @@ impl<'a> Signer<'a> {
/// if let MessageLayer::SignatureGroup { ref results } =
/// structure.iter().nth(0).unwrap()
/// {
- /// if let VerificationResult::GoodChecksum { .. } =
- /// results.get(0).unwrap()
- /// { Ok(()) /* good */ } else { panic!() }
+ /// results.get(0).unwrap().as_ref().unwrap();
+ /// Ok(())
/// } else { panic!() }
/// }
/// }
@@ -375,9 +374,8 @@ impl<'a> Signer<'a> {
/// if let MessageLayer::SignatureGroup { ref results } =
/// structure.iter().nth(0).unwrap()
/// {
- /// if let VerificationResult::GoodChecksum { .. } =
- /// results.get(0).unwrap()
- /// { Ok(()) /* good */ } else { panic!() }
+ /// results.get(0).unwrap().as_ref().unwrap();
+ /// Ok(())
/// } else { panic!() }
/// }
/// }