summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-06-23 14:34:13 +0200
committerJustus Winter <justus@sequoia-pgp.org>2023-06-26 13:36:38 +0200
commit3bec2c5fd1fea91391173d3f6ed39b0b119d32af (patch)
treeff02b392b58e26bb91708ac4b9796c19eafc1aa1
parent4e44e12df045be6ca7ef866e6c5d855d562e4a92 (diff)
openpgp: Add KeyAmalgamationIter::key_handles2. XXX
-rw-r--r--openpgp/src/cert/amalgamation/key/iter.rs72
-rw-r--r--openpgp/src/parse/stream.rs22
2 files changed, 83 insertions, 11 deletions
diff --git a/openpgp/src/cert/amalgamation/key/iter.rs b/openpgp/src/cert/amalgamation/key/iter.rs
index 2e1bb9ac..55b2e6e2 100644
--- a/openpgp/src/cert/amalgamation/key/iter.rs
+++ b/openpgp/src/cert/amalgamation/key/iter.rs
@@ -358,6 +358,9 @@ impl<'a, P, R> KeyAmalgamationIter<'a, P, R>
/// Changes the iterator to only return a key if it matches one of
/// the specified `KeyHandle`s.
///
+ /// If the given `handles` iterator is empty, the set of returned
+ /// keys is not constrained.
+ ///
/// This function is cumulative. If you call this function (or
/// [`key_handle`]) multiple times, then the iterator returns a key
/// if it matches *any* of the specified [`KeyHandle`s].
@@ -377,7 +380,7 @@ impl<'a, P, R> KeyAmalgamationIter<'a, P, R>
/// # .generate()?;
/// # let key_handles = &[cert.primary_key().key_handle()][..];
/// # let mut i = 0;
- /// for ka in cert.keys().key_handles(key_handles.iter()) {
+ /// for ka in cert.keys().key_handles2(key_handles) {
/// // Use it.
/// # i += 1;
/// }
@@ -389,6 +392,37 @@ impl<'a, P, R> KeyAmalgamationIter<'a, P, R>
/// [`KeyHandle`s]: super::super::super::KeyHandle
/// [`key_handle`]: KeyAmalgamationIter::key_handle()
/// [`KeyHandle::aliases`]: super::super::super::KeyHandle::aliases()
+ pub fn key_handles2<H>(mut self, handles: H) -> Self
+ where
+ H: IntoIterator<Item=KeyHandle>,
+ {
+ let mut handles = handles.into_iter().collect::<Vec<_>>();
+
+ if ! handles.is_empty() {
+ if self.key_handles.is_none() {
+ self.key_handles = Some(handles);
+ } else {
+ self.key_handles.as_mut().unwrap().append(&mut handles);
+ }
+ }
+
+ self
+ }
+
+ /// Changes the iterator to only return a key if it matches one of
+ /// the specified `KeyHandle`s.
+ ///
+ /// This function is cumulative. If you call this function (or
+ /// [`key_handle`]) multiple times, then the iterator returns a key
+ /// if it matches *any* of the specified [`KeyHandle`s].
+ ///
+ /// This function uses [`KeyHandle::aliases`] to compare key
+ /// handles.
+ ///
+ /// [`KeyHandle`s]: super::super::super::KeyHandle
+ /// [`key_handle`]: KeyAmalgamationIter::key_handle()
+ /// [`KeyHandle::aliases`]: super::super::super::KeyHandle::aliases()
+ #[deprecated(note = "Use key_handles2 instead")]
pub fn key_handles<'b>(mut self, h: impl Iterator<Item=&'b KeyHandle>)
-> Self
where 'a: 'b
@@ -1456,6 +1490,9 @@ impl<'a, P, R> ValidKeyAmalgamationIter<'a, P, R>
/// Changes the iterator to only return a key if it matches one of
/// the specified `KeyHandle`s.
///
+ /// If the given `handles` iterator is empty, the set of returned
+ /// keys is not constrained.
+ ///
/// This function is cumulative. If you call this function (or
/// [`key_handle`]) multiple times, then the iterator returns a key
/// if it matches *any* of the specified [`KeyHandle`s].
@@ -1479,7 +1516,7 @@ impl<'a, P, R> ValidKeyAmalgamationIter<'a, P, R>
/// # .generate()?;
/// # let key_handles = &[cert.primary_key().key_handle()][..];
/// # let mut i = 0;
- /// for ka in cert.keys().with_policy(p, None).key_handles(key_handles.iter()) {
+ /// for ka in cert.keys().with_policy(p, None).key_handles2(key_handles) {
/// // Use it.
/// # i += 1;
/// }
@@ -1489,8 +1526,39 @@ impl<'a, P, R> ValidKeyAmalgamationIter<'a, P, R>
/// ```
///
/// [`KeyHandle`s]: super::super::super::KeyHandle
+ /// [`key_handle`]: KeyAmalgamationIter::key_handle()
+ /// [`KeyHandle::aliases`]: super::super::super::KeyHandle::aliases()
+ pub fn key_handles2<H>(mut self, handles: H) -> Self
+ where
+ H: IntoIterator<Item=KeyHandle>,
+ {
+ let mut handles = handles.into_iter().collect::<Vec<_>>();
+
+ if ! handles.is_empty() {
+ if self.key_handles.is_none() {
+ self.key_handles = Some(handles);
+ } else {
+ self.key_handles.as_mut().unwrap().append(&mut handles);
+ }
+ }
+
+ self
+ }
+
+ /// Changes the iterator to only return a key if it matches one of
+ /// the specified `KeyHandle`s.
+ ///
+ /// This function is cumulative. If you call this function (or
+ /// [`key_handle`]) multiple times, then the iterator returns a key
+ /// if it matches *any* of the specified [`KeyHandle`s].
+ ///
+ /// This function uses [`KeyHandle::aliases`] to compare key
+ /// handles.
+ ///
+ /// [`KeyHandle`s]: super::super::super::KeyHandle
/// [`key_handle`]: ValidKeyAmalgamationIter::key_handle()
/// [`KeyHandle::aliases`]: super::super::super::KeyHandle::aliases()
+ #[deprecated(note = "Use key_handles2 instead")]
pub fn key_handles<'b>(mut self, h: impl Iterator<Item=&'b KeyHandle>)
-> Self
where 'a: 'b
diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs
index 291cde35..9641ed4f 100644
--- a/openpgp/src/parse/stream.rs
+++ b/openpgp/src/parse/stream.rs
@@ -2759,16 +2759,20 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
// encryption. Furthermore, no other OpenPGP
// implementation seems to support this kind
// of wildcard signatures.
- //
- // If there are no issuers, this iterator will
- // not yield any keys, hence this verification
- // will fail with the default error,
- // `VerificationError::MissingKey`.
- for ka in self.certs.iter()
- .flat_map(|cert| {
- cert.keys().key_handles(issuers.iter())
- })
+ let no_issuers = issuers.is_empty();
+
+ for ka in self.certs.iter().flat_map(
+ |c| c.keys().key_handles2(issuers.clone()))
{
+ if no_issuers {
+ // Slightly awkward control flow
+ // change. Below this loop, we still
+ // have to add this signature to the
+ // results with the default error,
+ // `VerificationError::MissingKey`.
+ break;
+ }
+
let cert = ka.cert();
let fingerprint = ka.fingerprint();
let ka = match ka.with_policy(self.policy, sig_time) {