diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-11-25 14:04:41 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-12-09 13:24:56 +0100 |
commit | 531e3252b86f6eacf02d7181c280e8c01c4a55f4 (patch) | |
tree | 998ac3f660f37e9163f124dcec279749b977a168 | |
parent | 7f3d55f777f44f9046ac91afe8e398984f1e4ba1 (diff) |
openpgp: Return Result from Signature::signature_alive.
- See #371.
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp.h | 9 | ||||
-rw-r--r-- | openpgp-ffi/src/packet/signature.rs | 19 | ||||
-rw-r--r-- | openpgp/src/cert/mod.rs | 12 | ||||
-rw-r--r-- | openpgp/src/packet/signature/subpacket.rs | 36 | ||||
-rw-r--r-- | openpgp/src/parse/stream.rs | 5 | ||||
-rw-r--r-- | openpgp/src/serialize/cert_armored.rs | 2 | ||||
-rw-r--r-- | tool/src/commands/inspect.rs | 9 |
7 files changed, 56 insertions, 36 deletions
diff --git a/openpgp-ffi/include/sequoia/openpgp.h b/openpgp-ffi/include/sequoia/openpgp.h index 2672836b..f35565d3 100644 --- a/openpgp-ffi/include/sequoia/openpgp.h +++ b/openpgp-ffi/include/sequoia/openpgp.h @@ -428,7 +428,8 @@ bool pgp_signature_is_group_key(pgp_signature_t signature); /// /// [Section 5.2.3.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.2.3.4 /*/ -bool pgp_signature_alive(pgp_signature_t signature, time_t when); +pgp_status_t pgp_signature_alive(pgp_error_t *errp, + pgp_signature_t signature, time_t when); /*/ /// Returns whether the signature is alive at the specified time. @@ -480,8 +481,10 @@ bool pgp_signature_alive(pgp_signature_t signature, time_t when); /// /// [Section 5.2.3.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.2.3.4 /*/ -bool pgp_signature_alive_with_tolerance(pgp_signature_t signature, - time_t time, unsigned int tolerance); +pgp_status_t pgp_signature_alive_with_tolerance(pgp_error_t *errp, + pgp_signature_t signature, + time_t time, + unsigned int tolerance); /*/ /// Returns whether the signature is expired at the specified time. diff --git a/openpgp-ffi/src/packet/signature.rs b/openpgp-ffi/src/packet/signature.rs index e3abedb3..abc302b5 100644 --- a/openpgp-ffi/src/packet/signature.rs +++ b/openpgp-ffi/src/packet/signature.rs @@ -16,6 +16,7 @@ use super::super::fingerprint::Fingerprint; use super::super::keyid::KeyID; use super::key::Key; +use crate::error::Status; use crate::Maybe; use crate::MoveFromRaw; use crate::MoveIntoRaw; @@ -166,15 +167,17 @@ fn pgp_signature_is_group_key(sig: *const Signature) -> bool { /// /// [Section 5.2.3.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.2.3.4 #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" -fn pgp_signature_alive(sig: *const Signature, time: time_t) - -> bool +fn pgp_signature_alive(errp: Option<&mut *mut crate::error::Error>, + sig: *const Signature, time: time_t) + -> Status { + ffi_make_fry_from_errp!(errp); let time = if time == 0 { None } else { Some(std::time::UNIX_EPOCH + std::time::Duration::new(time as u64, 0)) }; - sig.ref_raw().signature_alive(time, None) + ffi_try_status!(sig.ref_raw().signature_alive(time, None)) } /// Returns whether the signature is alive at the specified time. @@ -226,17 +229,19 @@ fn pgp_signature_alive(sig: *const Signature, time: time_t) /// /// [Section 5.2.3.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.2.3.4 #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" -fn pgp_signature_alive_with_tolerance(sig: *const Signature, +fn pgp_signature_alive_with_tolerance(errp: Option<&mut *mut crate::error::Error>, + sig: *const Signature, time: time_t, tolerance: c_uint) - -> bool + -> Status { + ffi_make_fry_from_errp!(errp); let time = if time == 0 { None } else { Some(std::time::UNIX_EPOCH + std::time::Duration::new(time as u64, 0)) }; let tolerance = std::time::Duration::new(tolerance as u64, 0); - sig.ref_raw().signature_alive(time, Some(tolerance)) + ffi_try_status!(sig.ref_raw().signature_alive(time, Some(tolerance))) } /// Returns whether the signature is expired at the specified time. @@ -249,7 +254,7 @@ fn pgp_signature_expired(sig: *const Signature, when: time_t) -> bool { } else { Some(std::time::UNIX_EPOCH + std::time::Duration::new(when as u64, 0)) }; - sig.ref_raw().signature_expired(t) + sig.ref_raw().signature_expired(t).is_ok() } /// Returns whether the signature is alive at the specified time. diff --git a/openpgp/src/cert/mod.rs b/openpgp/src/cert/mod.rs index 0fb5d988..efe65cf4 100644 --- a/openpgp/src/cert/mod.rs +++ b/openpgp/src/cert/mod.rs @@ -225,7 +225,7 @@ impl<C> ComponentBinding<C> { }; self.self_signatures[i..].iter().filter(|s| { - s.signature_alive(t, time::Duration::new(0, 0)) + s.signature_alive(t, time::Duration::new(0, 0)).is_ok() }).nth(0) } @@ -292,7 +292,8 @@ impl<C> ComponentBinding<C> { selfsig_creation_time, t); if let Some(selfsig) = selfsig { - assert!(selfsig.signature_alive(t, time::Duration::new(0, 0))); + assert!( + selfsig.signature_alive(t, time::Duration::new(0, 0)).is_ok()); } macro_rules! check { @@ -322,7 +323,10 @@ impl<C> ComponentBinding<C> { rev.signature_creation_time() .unwrap_or_else(time_zero)); None - } else if !rev.signature_alive(t, time::Duration::new(0, 0)) { + } else if + ! rev.signature_alive(t, time::Duration::new(0, 0)) + .is_ok() + { t!(" ignoring revocation that is not alive ({:?} - {:?})", rev.signature_creation_time() .unwrap_or_else(time_zero), @@ -891,7 +895,7 @@ impl Cert { // No binding signature at time `t` => not alive. let selfsig = b.binding_signature(t)?; - if !selfsig.signature_alive(t, time::Duration::new(0, 0)) { + if !selfsig.signature_alive(t, time::Duration::new(0, 0)).is_ok() { return None; } diff --git a/openpgp/src/packet/signature/subpacket.rs b/openpgp/src/packet/signature/subpacket.rs index e732d17e..e125348b 100644 --- a/openpgp/src/packet/signature/subpacket.rs +++ b/openpgp/src/packet/signature/subpacket.rs @@ -2162,7 +2162,7 @@ impl SubpacketAreas { /// /// [Section 5.2.3.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.2.3.4 pub fn signature_alive<T, U>(&self, time: T, clock_skew_tolerance: U) - -> bool + -> Result<()> where T: Into<Option<time::SystemTime>>, U: Into<Option<time::Duration>> { @@ -2180,13 +2180,19 @@ impl SubpacketAreas { (time, tolerance) }; - if let Some(creation_time) = self.signature_creation_time() { + match (self.signature_creation_time(), self.signature_expiration_time()) + { + (None, _) => + Err(Error::MalformedPacket("no signature creation time".into()) + .into()), + (Some(c), Some(e)) if e.as_secs() > 0 && (c + e) < time => + Err(Error::Expired(c + e).into()), // Be careful to avoid underflow. - cmp::max(creation_time, time::UNIX_EPOCH + tolerance) - - tolerance <= time - && ! self.signature_expired(time) - } else { - false + (Some(c), _) if cmp::max(c, time::UNIX_EPOCH + tolerance) + - tolerance > time => + Err(Error::NotYetLive(cmp::max(c, time::UNIX_EPOCH + tolerance) + - tolerance).into()), + _ => Ok(()), } } @@ -2755,10 +2761,10 @@ fn accessors() { assert!(!sig_.signature_expired(now)); assert!(sig_.signature_expired(now + ten_minutes)); - assert!(sig_.signature_alive(None, zero_s)); - assert!(sig_.signature_alive(now, zero_s)); - assert!(!sig_.signature_alive(now - five_minutes, zero_s)); - assert!(!sig_.signature_alive(now + ten_minutes, zero_s)); + assert!(sig_.signature_alive(None, zero_s).is_ok()); + assert!(sig_.signature_alive(now, zero_s).is_ok()); + assert!(!sig_.signature_alive(now - five_minutes, zero_s).is_ok()); + assert!(!sig_.signature_alive(now + ten_minutes, zero_s).is_ok()); sig = sig.set_signature_expiration_time(None).unwrap(); let sig_ = @@ -2768,10 +2774,10 @@ fn accessors() { assert!(!sig_.signature_expired(now)); assert!(!sig_.signature_expired(now + ten_minutes)); - assert!(sig_.signature_alive(None, zero_s)); - assert!(sig_.signature_alive(now, zero_s)); - assert!(!sig_.signature_alive(now - five_minutes, zero_s)); - assert!(sig_.signature_alive(now + ten_minutes, zero_s)); + assert!(sig_.signature_alive(None, zero_s).is_ok()); + assert!(sig_.signature_alive(now, zero_s).is_ok()); + assert!(!sig_.signature_alive(now - five_minutes, zero_s).is_ok()); + assert!(sig_.signature_alive(now + ten_minutes, zero_s).is_ok()); sig = sig.set_exportable_certification(true).unwrap(); let sig_ = diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index 272fc78f..ed8444ef 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -568,7 +568,7 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { if let Some(sig) = sig { sig.key_flags().for_signing() // Check expiry. - && sig.signature_alive(time, tolerance) + && sig.signature_alive(time, tolerance).is_ok() && sig.key_alive(key, time) } else { false @@ -704,6 +704,7 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { if sig.verify(key).unwrap_or(false) { if sig.signature_alive( self.time, self.clock_skew_tolerance) + .is_ok() { VerificationResult::GoodChecksum { sig: sig.clone(), @@ -1440,6 +1441,7 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { sig.key_flags().for_signing() // Check expiry. && sig.signature_alive(time, tolerance) + .is_ok() && sig.key_alive(key, time) } else { false @@ -1595,6 +1597,7 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { if sig.verify(key).unwrap_or(false) && sig.signature_alive( self.time, self.clock_skew_tolerance) + .is_ok() { // Check intended recipients. if let Some(identity) = diff --git a/openpgp/src/serialize/cert_armored.rs b/openpgp/src/serialize/cert_armored.rs index 35171b54..480c232b 100644 --- a/openpgp/src/serialize/cert_armored.rs +++ b/openpgp/src/serialize/cert_armored.rs @@ -40,7 +40,7 @@ impl Cert { // Ignore userids not "alive". }).filter_map(|uidb| { if uidb.binding_signature(None)? - .signature_alive(None, None) + .signature_alive(None, None).is_ok() { Some(uidb) } else { diff --git a/tool/src/commands/inspect.rs b/tool/src/commands/inspect.rs index 42d30530..f2347610 100644 --- a/tool/src/commands/inspect.rs +++ b/tool/src/commands/inspect.rs @@ -151,11 +151,10 @@ fn inspect_cert(output: &mut dyn io::Write, cert: &openpgp::Cert, writeln!(output, " UserID: {}", uidb.userid())?; inspect_revocation(output, "", uidb.revoked(None))?; if let Some(sig) = uidb.binding_signature(None) { - if sig.signature_expired(None) { - writeln!(output, " Expired")?; - } else if ! sig.signature_alive(None, - std::time::Duration::new(0, 0)) { - writeln!(output, " Not yet valid")?; + if let Err(e) = + sig.signature_alive(None, std::time::Duration::new(0, 0)) + { + writeln!(output, " Invalid: {}", e)?; } } inspect_certifications(output, |