summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2020-01-08 10:10:58 +0100
committerNeal H. Walfield <neal@pep.foundation>2020-01-08 10:23:23 +0100
commit5b0b546ce73cc3a2bfed085726c43635d5519924 (patch)
tree4747952e3ee06339f95ec571681e62d21168d3d0
parentf10ceaa4ac04dcafe0bce42eb4fed3832225b594 (diff)
openpgp: Include a reference time in KeyAmalgamation.
- Including the reference time in the KeyAmalgamation structure rather than having the user supply it to the individual methods (like `KeyAmalgamation::alive`) helps ensure that the key is used consistent. For instance, this makes it harder to mistakenly query key's liveness at time t, but then use the current time to determine the key's capabilities.
-rw-r--r--ffi/src/error.rs2
-rw-r--r--openpgp-ffi/src/cert.rs5
-rw-r--r--openpgp-ffi/src/error.rs6
-rw-r--r--openpgp-ffi/src/parse/stream.rs6
-rw-r--r--openpgp/src/cert/builder.rs24
-rw-r--r--openpgp/src/cert/key_amalgamation.rs154
-rw-r--r--openpgp/src/cert/keyiter.rs14
-rw-r--r--openpgp/src/lib.rs4
-rw-r--r--openpgp/src/parse/stream.rs16
-rw-r--r--sqv/src/sqv.rs2
10 files changed, 132 insertions, 101 deletions
diff --git a/ffi/src/error.rs b/ffi/src/error.rs
index 1bcf051c..5b1c6ea0 100644
--- a/ffi/src/error.rs
+++ b/ffi/src/error.rs
@@ -74,6 +74,8 @@ impl<'a> FromSequoiaError<'a> for Status {
Status::Expired,
&openpgp::Error::NotYetLive(_) =>
Status::NotYetLive,
+ &openpgp::Error::NoBindingSignature(_) =>
+ Status::NoBindingSignature,
openpgp::Error::__Nonexhaustive => unreachable!(),
}
}
diff --git a/openpgp-ffi/src/cert.rs b/openpgp-ffi/src/cert.rs
index 2d18ff18..cfa490ac 100644
--- a/openpgp-ffi/src/cert.rs
+++ b/openpgp-ffi/src/cert.rs
@@ -767,9 +767,8 @@ pub extern "C" fn pgp_cert_valid_key_iter_next<'a>(
iter_wrapper.next_called = true;
if let Some(ka) = iter_wrapper.iter.next() {
- // XXX: Shouldn't assume the current time.
- let sig = ka.binding_signature(None);
- let rs = ka.revoked(None);
+ let sig = ka.binding_signature();
+ let rs = ka.revoked();
let key = ka.key();
if let Some(ptr) = sigo {
diff --git a/openpgp-ffi/src/error.rs b/openpgp-ffi/src/error.rs
index 2277d9a2..43b2b63d 100644
--- a/openpgp-ffi/src/error.rs
+++ b/openpgp-ffi/src/error.rs
@@ -153,6 +153,9 @@ pub enum Status {
/// Not yet live.
NotYetLive = -31,
+
+ /// No binding signature.
+ NoBindingSignature = -32,
}
/// Returns the error message.
@@ -195,6 +198,7 @@ pub extern "C" fn pgp_status_to_string(status: Status) -> *const c_char {
UnsupportedCert => "Cert not supported\x00",
Expired => "Expired\x00",
NotYetLive => "Not yet live\x00",
+ NoBindingSignature => "No binding signature\x00",
}.as_bytes().as_ptr() as *const c_char
}
@@ -250,6 +254,8 @@ impl<'a> From<&'a failure::Error> for Status {
Status::Expired,
&openpgp::Error::NotYetLive(_) =>
Status::NotYetLive,
+ &openpgp::Error::NoBindingSignature(_) =>
+ Status::NoBindingSignature,
openpgp::Error::__Nonexhaustive => unreachable!(),
}
}
diff --git a/openpgp-ffi/src/parse/stream.rs b/openpgp-ffi/src/parse/stream.rs
index ae3fde7a..49778ad1 100644
--- a/openpgp-ffi/src/parse/stream.rs
+++ b/openpgp-ffi/src/parse/stream.rs
@@ -190,7 +190,7 @@ fn $fn_name<'a>(
-> bool
{
use self::stream::VerificationResult::*;
- if let $variant { sig, cert, ka, time } = result.ref_raw() {
+ if let $variant { sig, cert, ka } = result.ref_raw() {
if let Some(mut p) = sig_r {
*unsafe { p.as_mut() } = sig.move_into_raw();
}
@@ -207,10 +207,10 @@ fn $fn_name<'a>(
}
if let Some(mut p) = binding_r {
*unsafe { p.as_mut() } =
- ka.binding_signature(*time).move_into_raw();
+ ka.binding_signature().move_into_raw();
}
if let Some(mut p) = revocation_status_r {
- *unsafe { p.as_mut() } = ka.revoked(*time).move_into_raw();
+ *unsafe { p.as_mut() } = ka.revoked().move_into_raw();
}
true
} else {
diff --git a/openpgp/src/cert/builder.rs b/openpgp/src/cert/builder.rs
index c33633da..d870be1f 100644
--- a/openpgp/src/cert/builder.rs
+++ b/openpgp/src/cert/builder.rs
@@ -655,22 +655,18 @@ mod tests {
assert!(sig.key_alive(key, now + 590 * s).is_ok());
assert!(! sig.key_alive(key, now + 610 * s).is_ok());
- let (sig, key) = cert.keys().policy(now).alive().revoked(false)
+ let ka = cert.keys().policy(now).alive().revoked(false)
.for_signing()
- .nth(0).map(|ka| {
- (ka.binding_signature(now).unwrap(), ka.key())
- }).unwrap();
- assert!(sig.key_alive(key, now).is_ok());
- assert!(sig.key_alive(key, now + 290 * s).is_ok());
- assert!(! sig.key_alive(key, now + 310 * s).is_ok());
+ .nth(0).unwrap();
+ assert!(ka.alive().is_ok());
+ assert!(ka.clone().set_time(now + 290 * s).alive().is_ok());
+ assert!(! ka.clone().set_time(now + 310 * s).alive().is_ok());
- let (sig, key) = cert.keys().policy(now).alive().revoked(false)
+ let ka = cert.keys().policy(now).alive().revoked(false)
.for_authentication()
- .nth(0).map(|ka| {
- (ka.binding_signature(now).unwrap(), ka.key())
- }).unwrap();
- assert!(sig.key_alive(key, now).is_ok());
- assert!(sig.key_alive(key, now + 590 * s).is_ok());
- assert!(! sig.key_alive(key, now + 610 * s).is_ok());
+ .nth(0).unwrap();
+ assert!(ka.alive().is_ok());
+ assert!(ka.clone().set_time(now + 590 * s).alive().is_ok());
+ assert!(! ka.clone().set_time(now + 610 * s).alive().is_ok());
}
}
diff --git a/openpgp/src/cert/key_amalgamation.rs b/openpgp/src/cert/key_amalgamation.rs
index 9d0f9ba5..62f846ae 100644
--- a/openpgp/src/cert/key_amalgamation.rs
+++ b/openpgp/src/cert/key_amalgamation.rs
@@ -1,4 +1,5 @@
use std::time;
+use std::time::SystemTime;
use std::convert::TryInto;
use std::convert::TryFrom;
use std::borrow::Borrow;
@@ -6,6 +7,7 @@ use std::borrow::Borrow;
use crate::{
Cert,
cert::KeyBinding,
+ Error,
packet::key,
packet::key::SecretKeyMaterial,
packet::Key,
@@ -16,17 +18,19 @@ use crate::{
};
/// A variant of `KeyAmalgamation` for primary keys.
-#[derive(Debug)]
+#[derive(Debug, Clone)]
struct PrimaryKeyAmalgamation<'a, P: key::KeyParts> {
cert: &'a Cert,
binding: &'a KeyBinding<P, key::PrimaryRole>,
+ time: SystemTime,
}
/// A variant of `KeyAmalgamation` for subkeys.
-#[derive(Debug)]
+#[derive(Debug, Clone)]
struct SubordinateKeyAmalgamation<'a, P: key::KeyParts> {
cert: &'a Cert,
binding: &'a KeyBinding<P, key::SubordinateRole>,
+ time: SystemTime,
}
/// The underlying `KeyAmalgamation` type.
@@ -34,36 +38,38 @@ struct SubordinateKeyAmalgamation<'a, P: key::KeyParts> {
/// We don't make this type public, because an enum's variant types
/// must also all be public, and we don't want that here. Wrapping
/// this in a struct means that we can hide that.
-#[derive(Debug)]
+#[derive(Debug, Clone)]
enum KeyAmalgamation0<'a, P: key::KeyParts> {
Primary(PrimaryKeyAmalgamation<'a, P>),
Subordinate(SubordinateKeyAmalgamation<'a, P>),
}
/// A `Key` and its associated data.
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct KeyAmalgamation<'a, P: key::KeyParts>(KeyAmalgamation0<'a, P>);
-impl<'a, P> From<(&'a Cert, &'a KeyBinding<P, key::PrimaryRole>)>
+impl<'a, P> From<(&'a Cert, &'a KeyBinding<P, key::PrimaryRole>, SystemTime)>
for KeyAmalgamation<'a, P>
where P: key::KeyParts
{
- fn from(x: (&'a Cert, &'a KeyBinding<P, key::PrimaryRole>)) -> Self {
+ fn from(x: (&'a Cert, &'a KeyBinding<P, key::PrimaryRole>, SystemTime)) -> Self {
KeyAmalgamation(KeyAmalgamation0::Primary(PrimaryKeyAmalgamation {
cert: x.0,
binding: x.1,
+ time: x.2,
}))
}
}
-impl<'a, P> From<(&'a Cert, &'a KeyBinding<P, key::SubordinateRole>)>
+impl<'a, P> From<(&'a Cert, &'a KeyBinding<P, key::SubordinateRole>, SystemTime)>
for KeyAmalgamation<'a, P>
where P: key::KeyParts
{
- fn from(x: (&'a Cert, &'a KeyBinding<P, key::SubordinateRole>)) -> Self {
+ fn from(x: (&'a Cert, &'a KeyBinding<P, key::SubordinateRole>, SystemTime)) -> Self {
KeyAmalgamation(KeyAmalgamation0::Subordinate(SubordinateKeyAmalgamation {
cert: x.0,
binding: x.1,
+ time: x.2,
}))
}
}
@@ -80,6 +86,7 @@ impl<'a> From<KeyAmalgamation<'a, key::PublicParts>>
PrimaryKeyAmalgamation {
cert: ka.cert,
binding: ka.binding.into(),
+ time: ka.time,
})
)
}
@@ -88,6 +95,7 @@ impl<'a> From<KeyAmalgamation<'a, key::PublicParts>>
SubordinateKeyAmalgamation {
cert: ka.cert,
binding: ka.binding.into(),
+ time: ka.time,
})
)
}
@@ -105,6 +113,7 @@ impl<'a> From<KeyAmalgamation<'a, key::SecretParts>>
PrimaryKeyAmalgamation {
cert: ka.cert,
binding: ka.binding.into(),
+ time: ka.time,
})
)
}
@@ -113,6 +122,7 @@ impl<'a> From<KeyAmalgamation<'a, key::SecretParts>>
SubordinateKeyAmalgamation {
cert: ka.cert,
binding: ka.binding.into(),
+ time: ka.time,
})
)
}
@@ -132,6 +142,7 @@ impl<'a> TryFrom<KeyAmalgamation<'a, key::PublicParts>>
PrimaryKeyAmalgamation {
cert: ka.cert,
binding: ka.binding.try_into()?,
+ time: ka.time,
})
)
}
@@ -140,6 +151,7 @@ impl<'a> TryFrom<KeyAmalgamation<'a, key::PublicParts>>
SubordinateKeyAmalgamation {
cert: ka.cert,
binding: ka.binding.try_into()?,
+ time: ka.time,
})
)
}
@@ -160,44 +172,76 @@ impl<'a, P: 'a + key::KeyParts> KeyAmalgamation<'a, P> {
}
}
- /// Returns the key's binding signature at time `t`, if any.
- pub fn binding_signature<T>(&self, t: T) -> Option<&'a Signature>
+ /// Returns the amalgamation's reference time.
+ ///
+ /// For queries that are with respect to a point in time, this
+ /// determines that point in time. For instance, if a key is
+ /// created at `t_c` and expires at `t_e`, then
+ /// `KeyAmalgamation::alive` will return true if the reference
+ /// time is greater than or equal to `t_c` and less than `t_e`.
+ pub fn time(&self) -> SystemTime {
+ match self {
+ KeyAmalgamation(KeyAmalgamation0::Primary(ref h)) =>
+ h.time,
+ KeyAmalgamation(KeyAmalgamation0::Subordinate(ref h)) =>
+ h.time,
+ }
+ }
+
+ /// Changes the amalgamation's reference time.
+ ///
+ /// If `time` is `None`, the current time is used.
+ pub fn set_time<T>(mut self, time: T) -> Self
where T: Into<Option<time::SystemTime>>
{
+ let time = time.into().unwrap_or_else(SystemTime::now);
+ match self {
+ KeyAmalgamation(KeyAmalgamation0::Primary(ref mut h)) =>
+ h.time = time,
+ KeyAmalgamation(KeyAmalgamation0::Subordinate(ref mut h)) =>
+ h.time = time,
+ }
+
+ self
+ }
+
+ /// Returns the key's binding signature as of the reference time,
+ /// if any.
+ pub fn binding_signature(&self) -> Option<&'a Signature>
+ {
match self {
KeyAmalgamation(KeyAmalgamation0::Primary(ref h)) =>
- h.cert.primary_key_signature(t),
+ h.cert.primary_key_signature(self.time()),
KeyAmalgamation(KeyAmalgamation0::Subordinate(ref h)) =>
- h.binding.binding_signature(t),
+ h.binding.binding_signature(self.time()),
}
}
- /// Returns the key's revocation status at time `t`.
- pub fn revoked<T>(&self, t: T) -> RevocationStatus<'a>
- where T: Into<Option<time::SystemTime>>
+ /// Returns the key's revocation status as of the amalgamtion's
+ /// reference time.
+ pub fn revoked(&self) -> RevocationStatus<'a>
{
match self {
KeyAmalgamation(KeyAmalgamation0::Primary(ref h)) =>
- h.cert.revoked(t),
+ h.cert.revoked(self.time()),
KeyAmalgamation(KeyAmalgamation0::Subordinate(ref h)) =>
- h.binding.revoked(t),
+ h.binding.revoked(self.time()),
}
}
- /// Returns the key's key flags at time `time`.
- pub fn key_flags<T>(&self, time: T) -> Option<KeyFlags>
- where T: Into<Option<time::SystemTime>>
+ /// Returns the key's key flags as of the amalgamtion's
+ /// reference time.
+ pub fn key_flags(&self) -> Option<KeyFlags>
{
- self.binding_signature(time).map(|sig| sig.key_flags())
+ self.binding_signature().map(|sig| sig.key_flags())
}
/// Returns whether the key has at least one of the specified key
- /// flags at time `time`.
- pub fn has_any_key_flag<T, F>(&self, time: T, flags: F) -> bool
- where T: Into<Option<time::SystemTime>>,
- F: Borrow<KeyFlags>
+ /// flags as of the amalgamtion's reference time.
+ pub fn has_any_key_flag<F>(&self, flags: F) -> bool
+ where F: Borrow<KeyFlags>
{
- if let Some(our_flags) = self.key_flags(time) {
+ if let Some(our_flags) = self.key_flags() {
!(&our_flags & flags.borrow()).is_empty()
} else {
// We have no key flags.
@@ -205,52 +249,48 @@ impl<'a, P: 'a + key::KeyParts> KeyAmalgamation<'a, P> {
}
}
- /// Returns whether key is certification capable at time `time`.
- pub fn for_certification<T>(&self, time: T) -> bool
- where T: Into<Option<time::SystemTime>>
- {
- self.has_any_key_flag(time, KeyFlags::empty().set_certification(true))
+ /// Returns whether key is certification capable as of the
+ /// amalgamtion's reference time.
+ pub fn for_certification(&self) -> bool {
+ self.has_any_key_flag(KeyFlags::empty().set_certification(true))
}
- /// Returns whether key is signing capable at time `time`.
- pub fn for_signing<T>(&self, time: T) -> bool
- where T: Into<Option<time::SystemTime>>
- {
- self.has_any_key_flag(time, KeyFlags::empty().set_signing(true))
+ /// Returns whether key is signing capable as of the amalgamtion's
+ /// reference time.
+ pub fn for_signing(&self) -> bool {
+ self.has_any_key_flag(KeyFlags::empty().set_signing(true))
}
- /// Returns whether key is authentication capable at time `time`.
- pub fn for_authentication<T>(&self, time: T) -> bool
- where T: Into<Option<time::SystemTime>>
+ /// Returns whether key is authentication capable as of the
+ /// amalgamtion's reference time.
+ pub fn for_authentication(&self) -> bool
{
- self.has_any_key_flag(time, KeyFlags::empty().set_authentication(true))
+ self.has_any_key_flag(KeyFlags::empty().set_authentication(true))
}
- /// Returns whether key is intended for storage encryption at time
- /// `time`.
- pub fn for_storage_encryption<T>(&self, time: T) -> bool
- where T: Into<Option<std::time::SystemTime>>
+ /// Returns whether key is intended for storage encryption as of
+ /// the amalgamtion's reference time.
+ pub fn for_storage_encryption(&self) -> bool
{
- self.has_any_key_flag(time, KeyFlags::empty().set_storage_encryption(true))
+ self.has_any_key_flag(KeyFlags::empty().set_storage_encryption(true))
}
- /// Returns whether key is intended for transport encryption at
- /// time `time`.
- pub fn for_transport_encryption<T>(&self, time: T) -> bool
- where T: Into<Option<std::time::SystemTime>>
+ /// Returns whether key is intended for transport encryption as of the
+ /// amalgamtion's reference time.
+ pub fn for_transport_encryption(&self) -> bool
{
- self.has_any_key_flag(time, KeyFlags::empty().set_transport_encryption(true))
+ self.has_any_key_flag(KeyFlags::empty().set_transport_encryption(true))
}
- /// Returns whether the key is alive at time `time`.
- pub fn alive<T>(&self, time: T) -> bool
- where T: Into<Option<std::time::SystemTime>>,
- &'a Key<P, key::UnspecifiedRole>: From<&'a key::PublicKey>
+ /// Returns whether the key is alive as of the amalgamtion's
+ /// reference time.
+ pub fn alive(&self) -> Result<()>
+ where &'a Key<P, key::UnspecifiedRole>: From<&'a key::PublicKey>
{
- if let Some(sig) = self.binding_signature(None) {
- sig.key_alive(self.key(), time).is_ok()
+ if let Some(sig) = self.binding_signature() {
+ sig.key_alive(self.key(), self.time())
} else {
- false
+ Err(Error::NoBindingSignature(self.time()).into())
}
}
diff --git a/openpgp/src/cert/keyiter.rs b/openpgp/src/cert/keyiter.rs
index f235ec89..752c457f 100644
--- a/openpgp/src/cert/keyiter.rs
+++ b/openpgp/src/cert/keyiter.rs
@@ -351,16 +351,16 @@ impl<'a, P: 'a + key::KeyParts, R: 'a + key::KeyRole> ValidKeyIter<'a, P, R> {
loop {
let ka : KeyAmalgamation<'a, key::PublicParts> = if ! self.primary {
self.primary = true;
- (cert, &cert.primary).into()
+ (cert, &cert.primary, self.time).into()
} else {
- (cert, self.subkey_iter.next()?).into()
+ (cert, self.subkey_iter.next()?, self.time).into()
};
let key = ka.key();
t!("Considering key: {:?}", key);
let binding_signature
- = if let Some(binding_signature) = ka.binding_signature(self.time) {
+ = if let Some(binding_signature) = ka.binding_signature() {
binding_signature
} else {
t!("No self-signature at time {:?}", self.time);
@@ -368,7 +368,7 @@ impl<'a, P: 'a + key::KeyParts, R: 'a + key::KeyRole> ValidKeyIter<'a, P, R> {
};
if let Some(flags) = self.flags.as_ref() {
- if (&binding_signature.key_flags() & &flags).is_empty() {
+ if !ka.has_any_key_flag(flags) {
t!("Have flags: {:?}, want flags: {:?}... skipping.",
binding_signature.key_flags(), flags);
continue;
@@ -376,14 +376,14 @@ impl<'a, P: 'a + key::KeyParts, R: 'a + key::KeyRole> ValidKeyIter<'a, P, R> {
}
if let Some(()) = self.alive {
- if let Err(err) = binding_signature.key_alive(key, self.time) {
+ if let Err(err) = ka.alive() {
t!("Key not alive: {:?}", err);
continue;
}
}
if let Some(want_revoked) = self.revoked {
- if let RevocationStatus::Revoked(_) = ka.revoked(self.time) {
+ if let RevocationStatus::Revoked(_) = ka.revoked() {
// The key is definitely revoked.
if ! want_revoked {
t!("Key revoked... skipping.");
@@ -534,7 +534,7 @@ impl<'a, P: 'a + key::KeyParts, R: 'a + key::KeyRole> ValidKeyIter<'a, P, R>
/// .keys()
/// .policy(None)
/// .filter(|ka| {
- /// match ka.revoked(None) {
+ /// match ka.revoked() {
/// RevocationStatus::Revoked(_) =>
/// // It's definitely revoked, skip it.
/// false,
diff --git a/openpgp/src/lib.rs b/openpgp/src/lib.rs
index 56d88528..c436d3b5 100644
--- a/openpgp/src/lib.rs
+++ b/openpgp/src/lib.rs
@@ -272,6 +272,10 @@ pub enum Error {
#[fail(display = "Not live until {:?}", _0)]
NotYetLive(std::time::SystemTime),
+ /// No binding signature.
+ #[fail(display = "No binding signature at time {:?}", _0)]
+ NoBindingSignature(std::time::SystemTime),
+
/// This marks this enum as non-exhaustive. Do not use this
/// variant.
#[doc(hidden)] #[fail(display = "__Nonexhaustive")] __Nonexhaustive,
diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs
index fda80f62..3926299f 100644
--- a/openpgp/src/parse/stream.rs
+++ b/openpgp/src/parse/stream.rs
@@ -178,9 +178,6 @@ pub enum VerificationResult<'a> {
/// The signing key that made the signature.
ka: KeyAmalgamation<'a, key::PublicParts>,
-
- /// The time at which the signature is evaluated.
- time: time::SystemTime,
},
/// The signature is good, but it is not alive at the specified
@@ -197,9 +194,6 @@ pub enum VerificationResult<'a> {
/// The signing key that made the signature.
ka: KeyAmalgamation<'a, key::PublicParts>,
-
- /// The time at which the signature is evaluated.
- time: time::SystemTime,
},
/// Unable to verify the signature because the key is missing.
@@ -218,9 +212,6 @@ pub enum VerificationResult<'a> {
/// The signing key that made the signature.
ka: KeyAmalgamation<'a, key::PublicParts>,
-
- /// The time at which the signature is evaluated.
- time: time::SystemTime,
},
}
@@ -699,20 +690,17 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> {
VerificationResult::GoodChecksum {
sig: sig.clone(),
cert, ka,
- time: self.time,
}
} else {
VerificationResult::NotAlive {
sig: sig.clone(),
cert, ka,
- time: self.time,
}
}
} else {
VerificationResult::BadChecksum {
sig: sig.clone(),
cert, ka,
- time: self.time,
}
}
);
@@ -1609,14 +1597,12 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
{
sig: sig.clone(),
cert, ka,
- time: self.time,
}
} else {
VerificationResult::GoodChecksum
{
sig: sig.clone(),
cert, ka,
- time: self.time,
}
}
} else {
@@ -1624,14 +1610,12 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
VerificationResult::GoodChecksum {
sig: sig.clone(),
cert, ka,
- time: self.time,
}
}
} else {
VerificationResult::BadChecksum {
sig: sig.clone(),
cert, ka,
- time: self.time,
}
}
);
diff --git a/sqv/src/sqv.rs b/sqv/src/sqv.rs
index e1859132..fec3e1ff 100644
--- a/sqv/src/sqv.rs
+++ b/sqv/src/sqv.rs
@@ -235,7 +235,7 @@ fn real_main() -> Result<(), failure::Error> {
// Find the right key.
for ka in cert.keys().policy(None) {
// Use the current binding signature.
- let binding = match ka.binding_signature(None) {
+ let binding = match ka.binding_signature() {
Some(b) => b,
None => continue,
};