[−][src]Struct sequoia_openpgp::cert::CertParser
An iterator over a sequence of certificates, i.e., an OpenPGP keyring.
The source of packets is a fallible iterator over Packet
s. In
this way, it is possible to propagate parse errors.
A CertParser
returns each TPK
or TSK
that it encounters.
Its behavior can be modeled using a simple state machine.
In the first and initial state, it looks for the start of a
certificate, a Public Key
packet or a Secret Key
packet.
When it encounters such a packet it buffers it, and transitions to
the second state. Any other packet or an error causes it to emit
an error and stay in the same state. When the source of packets
is exhausted, it enters the End
state.
In the second state, it looks for packets that belong to a
certificate's body. If it encounters a valid body packet, then it
buffers it and stays in the same state. If it encounters the
start of a certificate, then it emits the buffered certificate,
buffers the packet, and stays in the same state. If it encounters
an invalid packet (e.g., a Literal Data
packet), it emits two
items, the buffered certificate, and an error, and then it
transitions back to the initial state. When the source of packets
is exhausted, it emits the buffered certificate and enters the end
state.
In the end state, it emits None
.
Invalid Packet / Error
,------------------------.
v |
Not a +---------+ +---------+
Start .-> | Looking | -------------> | Looking | <-. Cert
of Cert | | for | Start | for | | Body
Packet | | Start | of Cert | Cert | | Packet
/ Error `-- | of Cert | Packet | Body | --'
+---------+ .-> +---------+
| | | |
| `------' |
| Start of Cert Packet |
| |
EOF | +-----+ | EOF
`------> | End | <---------'
+-----+
| ^
`--'
The parser does not recurse into containers, thus when it
encounters a container like a Compressed Data
Packet, it will
return an error even if the container contains a valid
certificate.
The parser considers unknown packets to be valid body packets.
(In a Cert
, these show up as Unknown
components.) The
goal is to provide some future compatibility.
Examples
Print information about all certificates in a keyring:
use sequoia_openpgp as openpgp; use openpgp::parse::Parse; use openpgp::parse::PacketParser; use openpgp::cert::prelude::*; let ppr = PacketParser::from_bytes(&keyring)?; for certo in CertParser::from(ppr) { match certo { Ok(cert) => { println!("Key: {}", cert.fingerprint()); for ua in cert.userids() { println!(" User ID: {}", ua.userid()); } } Err(err) => { eprintln!("Error reading keyring: {}", err); } } }
When an invalid packet is encountered, an error is returned and parsing continues:
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; use openpgp::packet::prelude::*; use openpgp::types::DataFormat; let mut lit = Literal::new(DataFormat::Text); lit.set_body(b"test".to_vec()); let (alice, _) = CertBuilder::general_purpose(None, Some("alice@example.org")) .generate()?; let (bob, _) = CertBuilder::general_purpose(None, Some("bob@example.org")) .generate()?; let mut packets : Vec<Packet> = Vec::new(); packets.extend(alice.clone()); packets.push(lit.clone().into()); packets.push(lit.clone().into()); packets.extend(bob.clone()); let r : Vec<Result<Cert>> = CertParser::from(packets).collect(); assert_eq!(r.len(), 4); assert_eq!(r[0].as_ref().unwrap().fingerprint(), alice.fingerprint()); assert!(r[1].is_err()); assert!(r[2].is_err()); assert_eq!(r[3].as_ref().unwrap().fingerprint(), bob.fingerprint());
Implementations
impl<'a> CertParser<'a>
[src]
pub fn from_iter<I, J>(iter: I) -> Self where
I: 'a + IntoIterator<Item = J>,
J: 'a + Into<Result<Packet>>,
[src]
I: 'a + IntoIterator<Item = J>,
J: 'a + Into<Result<Packet>>,
Creates a CertParser
from a Result<Packet>
iterator.
Note: because we implement From<Packet>
for
Result<Packet>
, it is possible to pass in an iterator over
Packet
s.
Examples
From a Vec<Packet>
:
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; use openpgp::packet::prelude::*; for certo in CertParser::from_iter(packets) { match certo { Ok(cert) => { println!("Key: {}", cert.fingerprint()); for ua in cert.userids() { println!(" User ID: {}", ua.userid()); } } Err(err) => { eprintln!("Error reading keyring: {}", err); } } }
pub fn unvalidated_cert_filter<F: 'a>(self, filter: F) -> Self where
F: Fn(&Cert, bool) -> bool,
[src]
F: Fn(&Cert, bool) -> bool,
Filters the Certs prior to validation.
By default, the CertParser
only returns valdiated Cert
s.
Checking that a certificate's self-signatures are valid,
however, is computationally expensive, and not always
necessary. For example, when looking for a small number of
certificates in a large keyring, most certificates can be
immediately discarded. That is, it is more efficient to
filter, validate, and double check, than to validate and
filter. (It is necessary to double check, because the check
might have been on an invalid part. For example, if searching
for a key with a particular Key ID, a matching key might not
have any self signatures.)
If the CertParser
gave out unvalidated Cert
s, and provided
an interface to validate them, then the caller could implement
this check-validate-double-check pattern. Giving out
unvalidated Cert
s, however, is dangerous: inevitably, a
Cert
will be used without having been validated in a context
where it should have been.
This function avoids this class of bugs while still providing
a mechanism to filter Cert
s prior to validation: the caller
provides a callback that is invoked on the unvalidated
Cert
. If the callback returns true
, then the parser
validates the Cert
, and invokes the callback a second time
to make sure the Cert
is really wanted. If the callback
returns false, then the Cert
is skipped.
Note: calling this function multiple times on a single
CertParser
will not replace the existing filter, but install
multiple filters.
Examples
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; for certr in CertParser::from(ppr) .unvalidated_cert_filter(|cert, _| { for component in cert.keys() { if component.key().keyid() == some_keyid { return true; } } false }) { match certr { Ok(cert) => { // The Cert contains the subkey. } Err(err) => { eprintln!("Error reading keyring: {}", err); } } }
Trait Implementations
impl<'a> Default for CertParser<'a>
[src]
impl<'a> From<PacketParserResult<'a>> for CertParser<'a>
[src]
fn from(ppr: PacketParserResult<'a>) -> Self
[src]
Initializes a CertParser
from a PacketParser
.
impl<'a> From<Vec<Packet>> for CertParser<'a>
[src]
fn from(p: Vec<Packet>) -> CertParser<'a>ⓘNotable traits for CertParser<'a>
impl<'a> Iterator for CertParser<'a> type Item = Result<Cert>;
[src]
Notable traits for CertParser<'a>
impl<'a> Iterator for CertParser<'a> type Item = Result<Cert>;
impl<'a> From<Vec<Result<Packet, Error>>> for CertParser<'a>
[src]
fn from(p: Vec<Result<Packet>>) -> CertParser<'a>ⓘNotable traits for CertParser<'a>
impl<'a> Iterator for CertParser<'a> type Item = Result<Cert>;
[src]
Notable traits for CertParser<'a>
impl<'a> Iterator for CertParser<'a> type Item = Result<Cert>;
impl<'a> Iterator for CertParser<'a>
[src]
type Item = Result<Cert>
The type of the elements being iterated over.
fn next(&mut self) -> Option<Self::Item>
[src]
fn size_hint(&self) -> (usize, Option<usize>)
1.0.0[src]
fn count(self) -> usize
1.0.0[src]
fn last(self) -> Option<Self::Item>
1.0.0[src]
fn advance_by(&mut self, n: usize) -> Result<(), usize>
[src]
fn nth(&mut self, n: usize) -> Option<Self::Item>
1.0.0[src]
fn step_by(self, step: usize) -> StepBy<Self>
1.28.0[src]
fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
U: IntoIterator<Item = Self::Item>,
1.0.0[src]
U: IntoIterator<Item = Self::Item>,
fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
U: IntoIterator,
1.0.0[src]
U: IntoIterator,
fn map<B, F>(self, f: F) -> Map<Self, F> where
F: FnMut(Self::Item) -> B,
1.0.0[src]
F: FnMut(Self::Item) -> B,
fn for_each<F>(self, f: F) where
F: FnMut(Self::Item),
1.21.0[src]
F: FnMut(Self::Item),
fn filter<P>(self, predicate: P) -> Filter<Self, P> where
P: FnMut(&Self::Item) -> bool,
1.0.0[src]
P: FnMut(&Self::Item) -> bool,
fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
F: FnMut(Self::Item) -> Option<B>,
1.0.0[src]
F: FnMut(Self::Item) -> Option<B>,
fn enumerate(self) -> Enumerate<Self>
1.0.0[src]
fn peekable(self) -> Peekable<Self>
1.0.0[src]
fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
P: FnMut(&Self::Item) -> bool,
1.0.0[src]
P: FnMut(&Self::Item) -> bool,
fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
P: FnMut(&Self::Item) -> bool,
1.0.0[src]
P: FnMut(&Self::Item) -> bool,
fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P> where
P: FnMut(Self::Item) -> Option<B>,
[src]
P: FnMut(Self::Item) -> Option<B>,
fn skip(self, n: usize) -> Skip<Self>
1.0.0[src]
fn take(self, n: usize) -> Take<Self>
1.0.0[src]
fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
F: FnMut(&mut St, Self::Item) -> Option<B>,
1.0.0[src]
F: FnMut(&mut St, Self::Item) -> Option<B>,
fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
F: FnMut(Self::Item) -> U,
U: IntoIterator,
1.0.0[src]
F: FnMut(Self::Item) -> U,
U: IntoIterator,
fn flatten(self) -> Flatten<Self> where
Self::Item: IntoIterator,
1.29.0[src]
Self::Item: IntoIterator,
fn fuse(self) -> Fuse<Self>
1.0.0[src]
fn inspect<F>(self, f: F) -> Inspect<Self, F> where
F: FnMut(&Self::Item),
1.0.0[src]
F: FnMut(&Self::Item),
fn by_ref(&mut self) -> &mut Self
1.0.0[src]
#[must_use =
"if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]fn collect<B>(self) -> B where
B: FromIterator<Self::Item>,
1.0.0[src]
B: FromIterator<Self::Item>,
fn partition<B, F>(self, f: F) -> (B, B) where
B: Default + Extend<Self::Item>,
F: FnMut(&Self::Item) -> bool,
1.0.0[src]
B: Default + Extend<Self::Item>,
F: FnMut(&Self::Item) -> bool,
fn partition_in_place<'a, T, P>(self, predicate: P) -> usize where
P: FnMut(&T) -> bool,
Self: DoubleEndedIterator<Item = &'a mut T>,
T: 'a,
[src]
P: FnMut(&T) -> bool,
Self: DoubleEndedIterator<Item = &'a mut T>,
T: 'a,
fn is_partitioned<P>(self, predicate: P) -> bool where
P: FnMut(Self::Item) -> bool,
[src]
P: FnMut(Self::Item) -> bool,
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
1.27.0[src]
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
fn try_for_each<F, R>(&mut self, f: F) -> R where
F: FnMut(Self::Item) -> R,
R: Try<Ok = ()>,
1.27.0[src]
F: FnMut(Self::Item) -> R,
R: Try<Ok = ()>,
fn fold<B, F>(self, init: B, f: F) -> B where
F: FnMut(B, Self::Item) -> B,
1.0.0[src]
F: FnMut(B, Self::Item) -> B,
fn fold_first<F>(self, f: F) -> Option<Self::Item> where
F: FnMut(Self::Item, Self::Item) -> Self::Item,
[src]
F: FnMut(Self::Item, Self::Item) -> Self::Item,
fn all<F>(&mut self, f: F) -> bool where
F: FnMut(Self::Item) -> bool,
1.0.0[src]
F: FnMut(Self::Item) -> bool,
fn any<F>(&mut self, f: F) -> bool where
F: FnMut(Self::Item) -> bool,
1.0.0[src]
F: FnMut(Self::Item) -> bool,
fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
P: FnMut(&Self::Item) -> bool,
1.0.0[src]
P: FnMut(&Self::Item) -> bool,
fn find_map<B, F>(&mut self, f: F) -> Option<B> where
F: FnMut(Self::Item) -> Option<B>,
1.30.0[src]
F: FnMut(Self::Item) -> Option<B>,
fn try_find<F, R>(
&mut self,
f: F
) -> Result<Option<Self::Item>, <R as Try>::Error> where
F: FnMut(&Self::Item) -> R,
R: Try<Ok = bool>,
[src]
&mut self,
f: F
) -> Result<Option<Self::Item>, <R as Try>::Error> where
F: FnMut(&Self::Item) -> R,
R: Try<Ok = bool>,
fn position<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool,
1.0.0[src]
P: FnMut(Self::Item) -> bool,
fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool,
Self: ExactSizeIterator + DoubleEndedIterator,
1.0.0[src]
P: FnMut(Self::Item) -> bool,
Self: ExactSizeIterator + DoubleEndedIterator,
fn max(self) -> Option<Self::Item> where
Self::Item: Ord,
1.0.0[src]
Self::Item: Ord,
fn min(self) -> Option<Self::Item> where
Self::Item: Ord,
1.0.0[src]
Self::Item: Ord,
fn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
B: Ord,
F: FnMut(&Self::Item) -> B,
1.6.0[src]
B: Ord,
F: FnMut(&Self::Item) -> B,
fn max_by<F>(self, compare: F) -> Option<Self::Item> where
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
1.15.0[src]
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
fn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
B: Ord,
F: FnMut(&Self::Item) -> B,
1.6.0[src]
B: Ord,
F: FnMut(&Self::Item) -> B,
fn min_by<F>(self, compare: F) -> Option<Self::Item> where
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
1.15.0[src]
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
fn rev(self) -> Rev<Self> where
Self: DoubleEndedIterator,
1.0.0[src]
Self: DoubleEndedIterator,
fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
FromA: Default + Extend<A>,
FromB: Default + Extend<B>,
Self: Iterator<Item = (A, B)>,
1.0.0[src]
FromA: Default + Extend<A>,
FromB: Default + Extend<B>,
Self: Iterator<Item = (A, B)>,
fn copied<'a, T>(self) -> Copied<Self> where
Self: Iterator<Item = &'a T>,
T: 'a + Copy,
1.36.0[src]
Self: Iterator<Item = &'a T>,
T: 'a + Copy,
fn cloned<'a, T>(self) -> Cloned<Self> where
Self: Iterator<Item = &'a T>,
T: 'a + Clone,
1.0.0[src]
Self: Iterator<Item = &'a T>,
T: 'a + Clone,
fn cycle(self) -> Cycle<Self> where
Self: Clone,
1.0.0[src]
Self: Clone,
fn sum<S>(self) -> S where
S: Sum<Self::Item>,
1.11.0[src]
S: Sum<Self::Item>,
fn product<P>(self) -> P where
P: Product<Self::Item>,
1.11.0[src]
P: Product<Self::Item>,
fn cmp<I>(self, other: I) -> Ordering where
I: IntoIterator<Item = Self::Item>,
Self::Item: Ord,
1.5.0[src]
I: IntoIterator<Item = Self::Item>,
Self::Item: Ord,
fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering where
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
I: IntoIterator,
[src]
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
I: IntoIterator,
fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
1.5.0[src]
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering> where
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
I: IntoIterator,
[src]
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
I: IntoIterator,
fn eq<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
1.5.0[src]
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
fn eq_by<I, F>(self, other: I, eq: F) -> bool where
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
I: IntoIterator,
[src]
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
I: IntoIterator,
fn ne<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
1.5.0[src]
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
fn lt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
1.5.0[src]
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
fn le<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
1.5.0[src]
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
fn gt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
1.5.0[src]
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
fn ge<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
1.5.0[src]
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
fn is_sorted(self) -> bool where
Self::Item: PartialOrd<Self::Item>,
[src]
Self::Item: PartialOrd<Self::Item>,
fn is_sorted_by<F>(self, compare: F) -> bool where
F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
[src]
F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
fn is_sorted_by_key<F, K>(self, f: F) -> bool where
F: FnMut(Self::Item) -> K,
K: PartialOrd<K>,
[src]
F: FnMut(Self::Item) -> K,
K: PartialOrd<K>,
impl<'a> Parse<'a, CertParser<'a>> for CertParser<'a>
[src]
fn from_reader<R: 'a + Read>(reader: R) -> Result<Self>
[src]
Initializes a CertParser
from a Read
er.
fn from_file<P: AsRef<Path>>(path: P) -> Result<Self>
[src]
Initializes a CertParser
from a File
.
fn from_bytes<D: AsRef<[u8]> + ?Sized>(data: &'a D) -> Result<Self>
[src]
Initializes a CertParser
from a byte string.
Auto Trait Implementations
impl<'a> !RefUnwindSafe for CertParser<'a>
impl<'a> !Send for CertParser<'a>
impl<'a> !Sync for CertParser<'a>
impl<'a> Unpin for CertParser<'a>
impl<'a> !UnwindSafe for CertParser<'a>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<I> IntoIterator for I where
I: Iterator,
[src]
I: Iterator,
type Item = <I as Iterator>::Item
The type of the elements being iterated over.
type IntoIter = I
Which kind of iterator are we turning this into?
fn into_iter(self) -> I
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,