From 5dcd7da9f497f53a8271f2dbd923b52f230cec31 Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Fri, 3 Apr 2020 11:47:05 +0200 Subject: openpgp: Keep the error from the most recent binding signature. - Change ComponentBundle::binding_signature to return the error from the most recent binding signature that wasn't created after `t`, rather than the error from the oldest binding signature. - Imagine we have two binding signatures: the more recent one is not expired, but rejected by the policy, and the older one is expired. The error from the more recent binding signature is probably more relevant. --- openpgp/src/cert/bundle.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/openpgp/src/cert/bundle.rs b/openpgp/src/cert/bundle.rs index e3ce02d7..85a36b0e 100644 --- a/openpgp/src/cert/bundle.rs +++ b/openpgp/src/cert/bundle.rs @@ -4,6 +4,7 @@ use std::time; use std::ops::Deref; use crate::{ + Error, packet::Signature, packet::Key, packet::key, @@ -163,15 +164,27 @@ impl ComponentBundle { }; let mut sig = None; - let mut error = crate::Error::NoBindingSignature(t).into(); + + // Prefer the first error, which is the error arising from the + // most recent binding signature that wasn't created after + // `t`. + let mut error = None; + for s in self.self_signatures[i..].iter() { if let Err(e) = s.signature_alive(t, time::Duration::new(0, 0)) { - error = e; + // We know that t >= signature's creation time. So, + // it is expired. But an older signature might not + // be. So, keep trying. + if error.is_none() { + error = Some(e); + } continue; } if let Err(e) = policy.signature(s) { - error = e; + if error.is_none() { + error = Some(e); + } continue; } @@ -179,7 +192,13 @@ impl ComponentBundle { break; } - sig.ok_or(error) + if let Some(sig) = sig { + Ok(sig) + } else if let Some(err) = error { + Err(err) + } else { + Err(Error::NoBindingSignature(t).into()) + } } /// The self-signatures. -- cgit v1.2.3