summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-11-25 14:04:41 +0100
committerJustus Winter <justus@sequoia-pgp.org>2019-12-09 13:24:56 +0100
commit531e3252b86f6eacf02d7181c280e8c01c4a55f4 (patch)
tree998ac3f660f37e9163f124dcec279749b977a168
parent7f3d55f777f44f9046ac91afe8e398984f1e4ba1 (diff)
openpgp: Return Result from Signature::signature_alive.
- See #371.
-rw-r--r--openpgp-ffi/include/sequoia/openpgp.h9
-rw-r--r--openpgp-ffi/src/packet/signature.rs19
-rw-r--r--openpgp/src/cert/mod.rs12
-rw-r--r--openpgp/src/packet/signature/subpacket.rs36
-rw-r--r--openpgp/src/parse/stream.rs5
-rw-r--r--openpgp/src/serialize/cert_armored.rs2
-rw-r--r--tool/src/commands/inspect.rs9
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,