diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-06-23 14:34:13 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2023-06-26 13:36:38 +0200 |
commit | 3bec2c5fd1fea91391173d3f6ed39b0b119d32af (patch) | |
tree | ff02b392b58e26bb91708ac4b9796c19eafc1aa1 | |
parent | 4e44e12df045be6ca7ef866e6c5d855d562e4a92 (diff) |
openpgp: Add KeyAmalgamationIter::key_handles2. XXX
-rw-r--r-- | openpgp/src/cert/amalgamation/key/iter.rs | 72 | ||||
-rw-r--r-- | openpgp/src/parse/stream.rs | 22 |
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) { |