diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-01-24 10:25:33 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-01-24 10:43:32 +0100 |
commit | a1df93af96cd8fdaaf0430d891a9a7494e0dca03 (patch) | |
tree | e75c1b2d535bc47fa0248af4ec9ce65bd21e5777 | |
parent | 7300d53e788f740acd1ff70acc18ceba42be9429 (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.rs | 16 | ||||
-rw-r--r-- | openpgp/src/cert/mod.rs | 20 |
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. |