summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-01-24 10:25:33 +0100
committerJustus Winter <justus@sequoia-pgp.org>2020-01-24 10:43:32 +0100
commita1df93af96cd8fdaaf0430d891a9a7494e0dca03 (patch)
treee75c1b2d535bc47fa0248af4ec9ce65bd21e5777
parent7300d53e788f740acd1ff70acc18ceba42be9429 (diff)
openpgp: Remove last user of Cert::primary_key_signature.
- This also changes semantics. First, we will no longer be using the policy currently implemented by Cert::primary_key_signature. Instead, we always consider two signatures related to keys: the most recent binding signature (primary userid binding signature in case of the primary key) and the most recent direct key signature. - Second, in cases where there are no userids, we use the direct key signature as a keys binding signature, if any. This makes sure that Cert::primary_key().policy(t) works for userid-less keys. This is useful for keys stripped by Hagrid, and to support 4880bis-style certificates. This means that for the primary key, vka.binding_signature() and vka.direct_key_signature() may return the same signature. That, however, should not impact any policy computed over the two signatures. - This also makes Cert::revoked the source of truth for the primary key revocation status.
-rw-r--r--openpgp/src/cert/key_amalgamation.rs16
-rw-r--r--openpgp/src/cert/mod.rs20
2 files changed, 25 insertions, 11 deletions
diff --git a/openpgp/src/cert/key_amalgamation.rs b/openpgp/src/cert/key_amalgamation.rs
index cf2d74b6..799873aa 100644
--- a/openpgp/src/cert/key_amalgamation.rs
+++ b/openpgp/src/cert/key_amalgamation.rs
@@ -224,8 +224,11 @@ impl<'a, P: 'a + key::KeyParts> KeyAmalgamation<'a, P> {
KeyAmalgamation {
binding: KeyAmalgamationBinding::Primary(),
..
- } =>
- self.cert.primary_key_signature(time),
+ } => {
+ self.cert.primary_userid(time).map(|u| u.binding_signature())
+ .or_else(|| self.cert.primary_key().binding()
+ .binding_signature(time))
+ },
KeyAmalgamation {
binding: KeyAmalgamationBinding::Subordinate(ref binding),
..
@@ -445,11 +448,10 @@ impl<'a, P: 'a + key::KeyParts> ValidKeyAmalgamation<'a, P> {
/// revoked.
pub fn revoked(&self) -> RevocationStatus<'a>
{
- match self.a {
- KeyAmalgamation { binding: KeyAmalgamationBinding::Primary(), .. } =>
- self.cert.primary._revoked(true, Some(self.binding_signature()),
- self.time()),
- KeyAmalgamation { binding: KeyAmalgamationBinding::Subordinate(ref binding), .. } =>
+ match self.a.binding {
+ KeyAmalgamationBinding::Primary() =>
+ self.cert.revoked(self.time()),
+ KeyAmalgamationBinding::Subordinate(ref binding) =>
binding.revoked(self.time()),
}
}
diff --git a/openpgp/src/cert/mod.rs b/openpgp/src/cert/mod.rs
index 24ba7735..bad5a0f8 100644
--- a/openpgp/src/cert/mod.rs
+++ b/openpgp/src/cert/mod.rs
@@ -499,10 +499,22 @@ impl Cert {
where T: Into<Option<time::SystemTime>>
{
let t = t.into();
- self.primary._revoked(
- true,
- self.primary_key().policy(t).ok().map(|ka| ka.binding_signature()),
- t)
+ // Both a primary key signature and the primary userid's
+ // binding signature can override a soft revocation. Compute
+ // the most recent one.
+ let vkao = self.primary_key().policy(t).ok();
+ let mut sig = vkao.as_ref().map(|vka| vka.binding_signature());
+ if let Some(direct) = vkao.as_ref()
+ .and_then(|vka| vka.direct_key_signature())
+ {
+ match (direct.signature_creation_time(),
+ sig.and_then(|s| s.signature_creation_time())) {
+ (Some(ds), Some(bs)) if ds > bs =>
+ sig = Some(direct),
+ _ => ()
+ }
+ }
+ self.primary_key().binding()._revoked(true, sig, t)
}
/// Revokes the Cert in place.