sequoia_openpgp/cert/
raw.rs

1//! Functionality for dealing with mostly unparsed certificates.
2//!
3//! Parsing a certificate is not cheap.  When reading a keyring, most
4//! certificates are discarded or never used as they are not relevant.
5//! This module provides the [`RawCertParser`] and [`RawCert`] data
6//! structures that can help reduce the amount of unnecessary
7//! computation.
8//!
9//! [`RawCertParser`] splits a keyring into [`RawCert`]s by looking
10//! primarily at the packet framing and the packet headers.  This is
11//! much faster than parsing the packets' contents, as the
12//! [`CertParser`] does.
13//!
14//! [`CertParser`]: crate::cert::CertParser
15//!
16//! [`RawCert`] exposes just enough functionality to allow the user to
17//! quickly check if a certificate is not relevant.  Note: to check if
18//! a certificate is really relevant, the check usually needs to be
19//! repeated after canonicalizing it (by using, e.g., [`Cert::from`])
20//! and validating it (by using [`Cert::with_policy`]).
21//!
22//! [`Cert::from`]: From<RawCert>
23//!
24//! # Examples
25//!
26//! Search for a specific certificate in a keyring:
27//!
28//! ```rust
29//! # use std::convert::TryFrom;
30//! #
31//! use sequoia_openpgp as openpgp;
32//!
33//! # use openpgp::Result;
34//! use openpgp::cert::prelude::*;
35//! use openpgp::cert::raw::RawCertParser;
36//! use openpgp::parse::Parse;
37//! # use openpgp::serialize::Serialize;
38//! #
39//! # fn main() -> Result<()> {
40//! # fn doit() -> Result<Cert> {
41//! #      let (cert, _) = CertBuilder::new()
42//! #          .generate()?;
43//! #      let fpr = cert.fingerprint();
44//! #
45//! #      let mut bytes = Vec::new();
46//! #      cert.serialize(&mut bytes);
47//! for cert in RawCertParser::from_bytes(&bytes)? {
48//!     /// Ignore corrupt and invalid certificates.
49//!     let cert = if let Ok(cert) = cert {
50//!         cert
51//!     } else {
52//!         continue;
53//!     };
54//!
55//!     if cert.fingerprint() == fpr {
56//!         // Found it!  Try to convert it to a Cert.
57//!         return Cert::try_from(cert);
58//!     }
59//! }
60//!
61//! // Not found.
62//! return Err(anyhow::anyhow!("Not found!").into());
63//! # }
64//! # doit().expect("Found the certificate");
65//! # Ok(())
66//! # }
67//! ```
68use std::borrow::Cow;
69use std::convert::TryFrom;
70use std::fmt;
71
72use buffered_reader::{BufferedReader, Dup, EOF, Memory};
73
74use crate::Fingerprint;
75use crate::KeyID;
76use crate::Result;
77use crate::armor;
78use crate::cert::Cert;
79use crate::packet::Header;
80use crate::packet::Key;
81use crate::packet::Packet;
82use crate::packet::Tag;
83use crate::packet::UserID;
84use crate::packet::header::BodyLength;
85use crate::packet::header::CTB;
86use crate::packet::key;
87use crate::parse::Cookie;
88use crate::parse::PacketParser;
89use crate::parse::Parse;
90use crate::parse::RECOVERY_THRESHOLD;
91
92use super::TRACE;
93
94mod iter;
95pub use iter::KeyIter;
96
97/// A mostly unparsed `Packet`.
98///
99/// This is returned by [`RawCert::packets`].
100///
101/// The data includes the OpenPGP framing (i.e., the CTB, and length
102/// information).  [`RawPacket::body`] returns just the bytes
103/// corresponding to the packet's body, i.e., without the OpenPGP
104/// framing.
105///
106/// You can convert it to a [`Packet`] using `TryFrom`.
107///
108/// # Examples
109///
110/// ```rust
111/// use sequoia_openpgp as openpgp;
112/// # use openpgp::Result;
113/// # use openpgp::cert::prelude::*;
114/// # use openpgp::cert::raw::RawCert;
115/// use openpgp::packet::Packet;
116/// use openpgp::packet::Tag;
117/// # use openpgp::parse::Parse;
118/// # use openpgp::serialize::Serialize;
119/// #
120/// # fn main() -> Result<()> {
121/// #      let (cert, _) = CertBuilder::new()
122/// #          .add_signing_subkey()
123/// #          .add_certification_subkey()
124/// #          .add_transport_encryption_subkey()
125/// #          .add_storage_encryption_subkey()
126/// #          .add_authentication_subkey()
127/// #          .generate()?;
128/// #
129/// #      let mut bytes = Vec::new();
130/// #      cert.as_tsk().serialize(&mut bytes);
131/// # let mut count = 0;
132/// #
133/// # let rawcert = RawCert::from_bytes(&bytes)?;
134/// for p in rawcert.packets() {
135///     if p.tag() == Tag::SecretSubkey {
136///         if let Ok(packet) = Packet::try_from(p) {
137///             // Do something with the packet.
138/// #           count += 1;
139///         }
140/// #       else { panic!("Failed to parse packet"); }
141///     }
142/// }
143/// #     assert_eq!(count, 5);
144/// #     Ok(())
145/// # }
146/// ```
147#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
148pub struct RawPacket<'a> {
149    tag: Tag,
150    header_len: usize,
151    data: &'a [u8],
152}
153assert_send_and_sync!(RawPacket<'_>);
154
155impl fmt::Debug for RawPacket<'_> {
156    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157        f.debug_struct("RawPacket")
158            .field("tag", &self.tag)
159            .field("data (bytes)", &self.data.len())
160            .finish()
161    }
162}
163
164impl<'a> RawPacket<'a> {
165    fn new(tag: Tag, header_len: usize, bytes: &'a [u8]) -> Self {
166        Self {
167            tag,
168            header_len,
169            data: bytes,
170        }
171    }
172
173    /// Returns the packet's tag.
174    pub fn tag(&self) -> Tag {
175        self.tag
176    }
177
178    /// Returns the packet's bytes.
179    pub fn as_bytes(&self) -> &[u8] {
180        self.data
181    }
182
183    /// Return the packet's body without the OpenPGP framing.
184    pub fn body(&self) -> &[u8] {
185        &self.data[self.header_len..]
186    }
187}
188
189impl<'a> TryFrom<RawPacket<'a>> for Packet {
190    type Error = anyhow::Error;
191
192    fn try_from(p: RawPacket<'a>) -> Result<Self> {
193        Packet::from_bytes(p.as_bytes())
194    }
195}
196
197impl<'a> crate::seal::Sealed for RawPacket<'a> {}
198impl<'a> crate::serialize::Marshal for RawPacket<'a> {
199    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
200        o.write_all(self.as_bytes())?;
201        Ok(())
202    }
203}
204
205/// A mostly unparsed `Cert`.
206///
207/// This data structure contains the unparsed packets for a
208/// certificate or key.  The packet sequence is well-formed in the
209/// sense that the sequence of tags conforms to the [Transferable
210/// Public Key grammar] or [Transferable Secret Key grammar], and that
211/// it can extract the primary key's fingerprint.  Beyond that, the
212/// packets are not guaranteed to be valid.
213///
214/// [Transferable Public Key grammar]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.1
215/// [Transferable Secret Key grammar]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.2
216///
217/// This data structure exists to quickly split a large keyring, and
218/// only parse those certificates that appear to be relevant.
219#[derive(Clone)]
220pub struct RawCert<'a> {
221    data: Cow<'a, [u8]>,
222
223    primary_key: Key<key::PublicParts, key::PrimaryRole>,
224
225    // The packet's tag, the length of the header, and the offset of
226    // the start of the packet (including the header) into data.
227    packets: Vec<(Tag, usize, usize)>,
228}
229assert_send_and_sync!(RawCert<'_>);
230
231impl<'a> fmt::Debug for RawCert<'a> {
232    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233        f.debug_struct("RawCert")
234            .field("fingerprint", &self.fingerprint())
235            .field("packets",
236                   &self.packets
237                   .iter()
238                   .map(|p| format!("{} (offset: {})", p.0, p.1))
239                   .collect::<Vec<String>>()
240                   .join(", "))
241            .field("data (bytes)", &self.data.as_ref().len())
242            .finish()
243    }
244}
245
246impl<'a> PartialEq for RawCert<'a> {
247    fn eq(&self, other: &Self) -> bool {
248        self.data == other.data
249    }
250}
251
252impl<'a> Eq for RawCert<'a> {
253}
254
255impl<'a> RawCert<'a> {
256    /// Returns the certificate's bytes.
257    ///
258    /// If you want an individual packet's bytes, use
259    /// [`RawCert::packet`] or [`RawCert::packets`], and then call
260    /// [`RawPacket::as_bytes`].
261    pub fn as_bytes(&'a self) -> &'a [u8] {
262        self.data.as_ref()
263    }
264
265    /// Returns the certificate's fingerprint.
266    pub fn fingerprint(&self) -> Fingerprint {
267        self.primary_key.fingerprint()
268    }
269
270    /// Returns the certificate's Key ID.
271    pub fn keyid(&self) -> KeyID {
272        KeyID::from(self.fingerprint())
273    }
274
275    /// Returns the ith packet.
276    pub fn packet(&self, i: usize) -> Option<RawPacket> {
277        let data: &[u8] = self.data.as_ref();
278
279        let &(tag, header_len, start) = self.packets.get(i)?;
280        let following = self.packets
281            .get(i + 1)
282            .map(|&(_, _, offset)| offset)
283            .unwrap_or(data.len());
284
285        Some(RawPacket::new(tag, header_len, &data[start..following]))
286    }
287
288    /// Returns an iterator over each raw packet.
289    pub fn packets(&self) -> impl Iterator<Item=RawPacket> {
290        let data: &[u8] = self.data.as_ref();
291
292        let count = self.packets.len();
293        (0..count)
294            .map(move |i| {
295                let (tag, header_len, start) = self.packets[i];
296                let following = self.packets
297                    .get(i + 1)
298                    .map(|&(_, _, offset)| offset)
299                    .unwrap_or(data.len());
300
301                RawPacket::new(tag, header_len, &data[start..following])
302            })
303    }
304
305    /// Returns the number of packets.
306    pub fn count(&self) -> usize {
307        self.packets.len()
308    }
309
310    /// Returns an iterator over the certificate's keys.
311    ///
312    /// Note: this parses the key packets, but it does not verify any
313    /// binding signatures.  As such, this can only be used as part of
314    /// a precheck.  If the certificate appears to match, then the
315    /// caller must convert the [`RawCert`] to a [`Cert`] or a
316    /// [`ValidCert`], depending on the requirements, and perform the
317    /// check again.
318    ///
319    /// [`ValidCert`]: crate::cert::ValidCert
320    ///
321    /// Use [`subkeys`] to just return the subkeys.  This function
322    /// also changes the return type.  Instead of the iterator
323    /// returning a [`Key`] whose role is [`key::UnspecifiedRole`],
324    /// the role is [`key::SubordinateRole`].
325    ///
326    /// [`subkeys`]: KeyIter::subkeys
327    ///
328    /// # Examples
329    ///
330    /// ```rust
331    /// use sequoia_openpgp as openpgp;
332    //
333    /// # use openpgp::Result;
334    /// # use openpgp::cert::prelude::*;
335    /// use openpgp::cert::raw::RawCertParser;
336    /// use openpgp::parse::Parse;
337    /// # use openpgp::serialize::Serialize;
338    /// #
339    /// # fn main() -> Result<()> {
340    /// #      let (cert, _) = CertBuilder::new()
341    /// #          .add_signing_subkey()
342    /// #          .add_certification_subkey()
343    /// #          .add_transport_encryption_subkey()
344    /// #          .add_storage_encryption_subkey()
345    /// #          .add_authentication_subkey()
346    /// #          .generate()?;
347    /// #
348    /// #      let mut bytes = Vec::new();
349    /// #      cert.serialize(&mut bytes);
350    /// # let mut certs = 0;
351    /// # let mut keys = 0;
352    /// for cert in RawCertParser::from_bytes(&bytes)? {
353    ///     /// Ignore corrupt and invalid certificates.
354    ///     let cert = if let Ok(cert) = cert {
355    ///         cert
356    ///     } else {
357    ///         continue;
358    ///     };
359    ///
360    ///     // Iterate over the keys.  Note: this parses the Key
361    ///     // packets.
362    ///     for key in cert.keys() {
363    ///         println!("{}", key.fingerprint());
364    /// #       keys += 1;
365    ///     }
366    /// #   certs += 1;
367    /// }
368    /// # assert_eq!(certs, 1);
369    /// # assert_eq!(keys, 6);
370    /// #     Ok(())
371    /// # }
372    /// ```
373    pub fn keys(&self) -> KeyIter<key::PublicParts, key::UnspecifiedRole> {
374        KeyIter::new(self)
375    }
376
377    // Returns an iterator over the certificate's keys.
378    //
379    // This is used by `KeyIter`, which implements a number of
380    // filters.
381    fn keys_internal(&self)
382        -> impl Iterator<Item=Key<key::PublicParts, key::UnspecifiedRole>> + '_
383    {
384        std::iter::once(self.primary_key().clone().role_into_unspecified())
385            .chain(self.packets()
386                   .filter(|p| matches!(p.tag(),
387                                        Tag::PublicKey | Tag::PublicSubkey
388                                        | Tag::SecretKey | Tag::SecretSubkey))
389                   .skip(1) // The primary key.
390                   .filter_map(|p| Key::from_bytes(p.body())
391                               .ok()
392                               .map(|k| k.parts_into_public())))
393    }
394
395    /// Returns the certificate's primary key.
396    ///
397    /// Note: this parses the primary key packet, but it does not
398    /// verify any binding signatures.  As such, this can only be used
399    /// as part of a precheck.  If the certificate appears to match,
400    /// then the caller must convert the [`RawCert`] to a [`Cert`] or
401    /// a [`ValidCert`], depending on the requirements, and perform
402    /// the check again.
403    ///
404    /// [`ValidCert`]: crate::cert::ValidCert
405    pub fn primary_key(&self) -> Key<key::PublicParts, key::PrimaryRole> {
406        self.primary_key.clone()
407    }
408
409    /// Returns the certificate's User IDs.
410    ///
411    /// Note: this parses the User ID packets, but it does not verify
412    /// any binding signatures.  That is, there is no guarantee that
413    /// the User IDs should actually be associated with the primary
414    /// key.  As such, this can only be used as part of a precheck.
415    /// If a User ID appears to match, then the caller must convert
416    /// the [`RawCert`] to a [`Cert`] or a [`ValidCert`], depending on
417    /// the requirements, and perform the check again.
418    ///
419    /// [`ValidCert`]: crate::cert::ValidCert
420    pub fn userids(&self) -> impl Iterator<Item=UserID> + '_
421    {
422        self.packets()
423            .filter_map(|p| {
424                if p.tag() == Tag::UserID {
425                    UserID::try_from(p.body()).ok()
426                } else {
427                    None
428                }
429            })
430    }
431
432    /// Changes the `RawCert`'s lifetime to the static lifetime.
433    ///
434    /// Returns a `RawCert` with a static lifetime by copying any
435    /// referenced data.
436    ///
437    /// [`RawCertParser::next`] returns a `RawCert` with the same
438    /// lifetime as its reader.  In certain situations,
439    /// `RawCertParser::next` can take advantage of this to avoid
440    /// copying data.  Tying the `RawCert`'s lifetime to the reader is
441    /// inconvenient when the `RawCert` needs to outlive the reader,
442    /// however.  This function copies any referenced data thereby
443    /// breaking the dependency.
444    ///
445    /// ```
446    /// # use sequoia_openpgp::Result;
447    /// # use sequoia_openpgp::cert::raw::RawCert;
448    /// # use sequoia_openpgp::cert::raw::RawCertParser;
449    /// # use sequoia_openpgp::parse::Parse;
450    ///
451    /// # fn main() -> Result<()> {
452    /// fn read_certs<'a>() -> Result<Vec<RawCert<'static>>> {
453    ///     let input = // ...
454    ///     # Vec::new();
455    ///
456    ///     // The lifetime of the returned certs is tied to input.
457    ///     // We use into_owned to break the dependency.
458    ///     let parser = RawCertParser::from_bytes(&input)?;
459    ///     let certs = parser
460    ///         .map(|r| r.map(|c| c.into_owned()))
461    ///         .collect::<Result<Vec<_>>>()?;
462    ///     Ok(certs)
463    /// }
464    ///
465    /// let cert = read_certs()?;
466    /// # assert_eq!(cert.len(), 0);
467    /// # Ok(()) }
468    /// ```
469    pub fn into_owned(self) -> RawCert<'static> {
470        match self.data {
471            Cow::Owned(data) => {
472                RawCert {
473                    data: Cow::Owned(data),
474                    primary_key: self.primary_key,
475                    packets: self.packets,
476                }
477            }
478            Cow::Borrowed(data) => {
479                RawCert {
480                    data: Cow::Owned(data.to_vec()),
481                    primary_key: self.primary_key,
482                    packets: self.packets,
483                }
484            }
485        }
486    }
487}
488
489impl<'a> TryFrom<&RawCert<'a>> for Cert {
490    type Error = anyhow::Error;
491
492    fn try_from(c: &RawCert) -> Result<Self> {
493        Cert::from_bytes(c.as_bytes())
494    }
495}
496
497impl<'a> TryFrom<RawCert<'a>> for Cert {
498    type Error = anyhow::Error;
499
500    fn try_from(c: RawCert) -> Result<Self> {
501        Cert::try_from(&c)
502    }
503}
504
505impl<'a> Parse<'a, RawCert<'a>> for RawCert<'a> {
506    /// Returns the first RawCert encountered in the reader.
507    ///
508    /// Returns an error if there are multiple certificates.
509    fn from_buffered_reader<R>(reader: R) -> Result<RawCert<'a>>
510    where
511        R: BufferedReader<Cookie> + 'a
512    {
513        fn parse<'a>(reader: Box<dyn BufferedReader<Cookie> + 'a>) -> Result<RawCert<'a>> {
514            let mut parser = RawCertParser::from_buffered_reader(reader)?;
515            if let Some(cert_result) = parser.next() {
516                if parser.next().is_some() {
517                    Err(crate::Error::MalformedCert(
518                        "Additional packets found, is this a keyring?".into()
519                    ).into())
520                } else {
521                    cert_result
522                }
523            } else {
524                Err(crate::Error::MalformedCert("No data".into()).into())
525            }
526        }
527
528        parse(reader.into_boxed())
529    }
530}
531
532impl<'a> crate::seal::Sealed for RawCert<'a> {}
533impl<'a> crate::serialize::Marshal for RawCert<'a> {
534    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
535        o.write_all(self.as_bytes())?;
536        Ok(())
537    }
538}
539
540/// An iterator over a sequence of unparsed certificates, i.e., an
541/// OpenPGP keyring.
542///
543/// A `RawCertParser` returns each certificate that it encounters.
544///
545/// It implements the same state machine as [`CertParser`], however, a
546/// `CertParser` is stricter.  Specifically, a `CertParser` performs
547/// some sanity checks on the content of the packets whereas a
548/// `RawCertParser` doesn't do those checks, because it avoids parsing
549/// the packets' contents; it primarily looks at the packets' framing,
550/// and their headers.
551///
552/// [`CertParser`]: crate::cert::CertParser
553///
554/// `RawCertParser` checks that the packet sequence is well-formed in
555/// the sense that the sequence of tags conforms to the [Transferable
556/// Public Key grammar] or [Transferable Secret Key grammar], and it
557/// performs a few basic checks.  See the documentation for
558/// [`RawCert`] for details.
559///
560/// [Transferable Public Key grammar]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.1
561/// [Transferable Secret Key grammar]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.2
562///
563/// Because a `RawCertParser` doesn't parse the contents of the
564/// packets, it is significantly faster than a [`CertParser`] when
565/// many of the certificates in a keyring are irrelevant.
566///
567/// # Examples
568///
569/// Search for a specific certificate in a keyring:
570///
571/// ```rust
572/// # use std::convert::TryFrom;
573/// #
574/// use sequoia_openpgp as openpgp;
575///
576/// # use openpgp::Result;
577/// use openpgp::cert::prelude::*;
578/// use openpgp::cert::raw::RawCertParser;
579/// use openpgp::parse::Parse;
580/// # use openpgp::serialize::Serialize;
581/// #
582/// # fn main() -> Result<()> {
583/// # fn doit() -> Result<Cert> {
584/// #      let (cert, _) = CertBuilder::new()
585/// #          .generate()?;
586/// #      let fpr = cert.fingerprint();
587/// #
588/// #      let mut bytes = Vec::new();
589/// #      cert.serialize(&mut bytes);
590/// for cert in RawCertParser::from_bytes(&bytes)? {
591///     /// Ignore corrupt and invalid certificates.
592///     let cert = if let Ok(cert) = cert {
593///         cert
594///     } else {
595///         continue;
596///     };
597///
598///     if cert.fingerprint() == fpr {
599///         // Found it!  Try to convert it to a Cert.
600///         if let cert = Cert::try_from(cert) {
601///             return cert;
602///         }
603///     }
604/// }
605///
606/// // Not found.
607/// return Err(anyhow::anyhow!("Not found!").into());
608/// # }
609/// # doit().expect("Found the certificate");
610/// # Ok(())
611/// # }
612/// ```
613pub struct RawCertParser<'a>
614{
615    // If the data is being read from a slice, then the slice.  This
616    // is used to avoid copying the data into the RawCert.
617    slice: Option<&'a [u8]>,
618
619    // Where `RawCertParser` reads the data.  When reading from a
620    // slice, this is a `buffered_reader::Memory`.  Note: the slice
621    // field will not be set, if the input needs to be transferred
622    // (i.e., dearmored).
623    reader: Box<dyn BufferedReader<Cookie> + 'a>,
624
625    // Whether we are dearmoring the input.
626    dearmor: bool,
627
628    // The total number of bytes read.
629    bytes_read: usize,
630
631    // Any pending error.
632    pending_error: Option<anyhow::Error>,
633
634    // Whether there was an unrecoverable error.
635    done: bool,
636}
637assert_send_and_sync!(RawCertParser<'_>);
638
639impl<'a> RawCertParser<'a> {
640    fn new(reader: Box<dyn BufferedReader<Cookie> + 'a>) -> Result<Self>
641    {
642        // Check that we can read the first header and that it is
643        // reasonable.  Note: an empty keyring is not an error; we're
644        // just checking for bad data here.  If not, try again after
645        // dearmoring the input.
646        let mut dearmor = false;
647        let mut dup = Dup::with_cookie(reader, Default::default());
648        if ! dup.eof() {
649            match Header::parse(&mut dup) {
650                Ok(header) => {
651                    let tag = header.ctb().tag();
652                    if matches!(tag, Tag::Unknown(_) | Tag::Private(_)) {
653                        return Err(crate::Error::MalformedCert(
654                            format!("A certificate must start with a \
655                                     public key or a secret key packet, \
656                                     got a {}",
657                                    tag))
658                                   .into());
659                    }
660                }
661                Err(_err) => {
662                    // We failed to read a header.  Try to dearmor the
663                    // input.
664                    dearmor = true;
665                }
666            }
667        }
668
669        // Strip the Dup reader.
670        let mut reader = dup.into_boxed().into_inner().expect("inner");
671
672        if dearmor {
673            reader = armor::Reader::from_cookie_reader(
674                reader, armor::ReaderMode::Tolerant(None),
675                Default::default()).into_boxed();
676
677            let mut dup = Dup::with_cookie(reader, Default::default());
678            match Header::parse(&mut dup) {
679                Ok(header) => {
680                    let tag = header.ctb().tag();
681                    if matches!(tag, Tag::Unknown(_) | Tag::Private(_)) {
682                        return Err(crate::Error::MalformedCert(
683                            format!("A certificate must start with a \
684                                     public key or a secret key packet, \
685                                     got a {}",
686                                    tag))
687                                   .into());
688                    }
689                }
690                Err(err) => {
691                    return Err(err);
692                }
693            }
694
695            reader = dup.into_boxed().into_inner().expect("inner");
696        }
697
698        Ok(RawCertParser {
699            slice: None,
700            reader,
701            dearmor,
702            bytes_read: 0,
703            pending_error: None,
704            done: false,
705        })
706    }
707}
708
709impl<'a> Parse<'a, RawCertParser<'a>> for RawCertParser<'a>
710{
711    /// Initializes a `RawCertParser` from a `BufferedReader`.
712    fn from_buffered_reader<R>(reader: R) -> Result<RawCertParser<'a>>
713    where
714        R: BufferedReader<Cookie> + 'a
715    {
716        RawCertParser::new(reader.into_boxed())
717    }
718
719    /// Initializes a `RawCertParser` from a byte string.
720    fn from_bytes<D: AsRef<[u8]> + ?Sized + Send + Sync>(data: &'a D) -> Result<Self> {
721        let data = data.as_ref();
722        let mut p = RawCertParser::new(
723            Memory::with_cookie(data, Default::default()).into_boxed())?;
724
725        // If we are dearmoring the input, then the slice doesn't
726        // reflect the raw packets.
727        if ! p.dearmor {
728            p.slice = Some(data);
729        }
730        Ok(p)
731    }
732}
733
734impl<'a> crate::seal::Sealed for RawCertParser<'a> {}
735
736impl<'a> Iterator for RawCertParser<'a>
737{
738    type Item = Result<RawCert<'a>>;
739
740    fn next(&mut self) -> Option<Self::Item> {
741        tracer!(TRACE, "RawCertParser::next", 0);
742
743        // Return the pending error.
744        if let Some(err) = self.pending_error.take() {
745            t!("Returning the queued error: {}", err);
746            return Some(Err(err));
747        }
748
749        if self.done {
750            return None;
751        }
752
753        if self.reader.eof() && self.dearmor {
754            // We are dearmoring and hit EOF.  Maybe there is a second
755            // armor block next to this one!
756
757            // Get the reader,
758            let reader = std::mem::replace(
759                &mut self.reader,
760                EOF::with_cookie(Default::default()).into_boxed());
761
762            // peel off the armor reader,
763            let reader = reader.into_inner().expect("the armor reader");
764
765            // and install a new one!
766            self.reader = armor::Reader::from_cookie_reader(
767                reader, armor::ReaderMode::Tolerant(None),
768                Default::default()).into_boxed();
769        }
770
771        if self.reader.eof() {
772            return None;
773        }
774
775        let mut reader = Dup::with_cookie(
776            std::mem::replace(&mut self.reader,
777                              Box::new(EOF::with_cookie(Default::default()))),
778                Default::default());
779
780        // The absolute start of this certificate in the stream.
781        let cert_start_absolute = self.bytes_read;
782
783        // The number of bytes processed relative to the start of the
784        // dup'ed buffered reader.  This may be less than the number
785        // of bytes read, e.g., when we encounter a new certificate,
786        // we read the header, but we don't necessarily want to
787        // consider it consumed.
788        let mut processed = 0;
789
790        // The certificate's span relative to the start of the dup'ed
791        // buffered reader.  The start will be larger than zero when
792        // we skip a marker packet.
793        let mut cert_start = 0;
794        let mut cert_end = 0;
795
796        // (Tag, header length, offset from start of the certificate)
797        let mut packets: Vec<(Tag, usize, usize)> = Vec::new();
798        let mut primary_key = None;
799
800        let mut pending_error = None;
801        'packet_parser: loop {
802            if reader.eof() {
803                break;
804            }
805
806            let packet_start = reader.total_out();
807            processed = packet_start;
808
809            let mut skip = 0;
810            let mut header_len = 0;
811            let header = loop {
812                match Header::parse(&mut reader) {
813                    Err(err) => {
814                        if skip == 0 {
815                            t!("Reading the next packet's header: {}", err);
816                        }
817
818                        if skip >= RECOVERY_THRESHOLD {
819                            pending_error = Some(err.context(
820                                format!("Splitting keyring at offset {}",
821                                        self.bytes_read + packet_start)));
822                            processed = reader.total_out();
823
824                            // We tried to recover and failed.  Once
825                            // we return the above error, we're done.
826                            self.done = true;
827
828                            break 'packet_parser;
829                        } else if reader.eof() {
830                            t!("EOF while trying to recover");
831                            skip += 1;
832                            break Header::new(CTB::new(Tag::Reserved),
833                                              BodyLength::Full(skip as u32));
834                        } else {
835                            skip += 1;
836                            reader.rewind();
837                            reader.consume(packet_start + skip);
838                        }
839                    }
840                    Ok(header) if skip > 0 => {
841                        if PacketParser::plausible_cert(&mut reader, &header)
842                            .is_ok()
843                        {
844                            // We recovered.  First return an error.  The
845                            // next time this function is called, we'll
846                            // resume here.
847                            t!("Found a valid header after {} bytes \
848                                of junk: {:?}",
849                               skip, header);
850
851                            break Header::new(CTB::new(Tag::Reserved),
852                                              BodyLength::Full(skip as u32));
853                        } else {
854                            skip += 1;
855                            reader.rewind();
856                            reader.consume(packet_start + skip);
857                        }
858                    }
859                    Ok(header) => {
860                        header_len = reader.total_out() - packet_start;
861                        break header;
862                    }
863                }
864            };
865
866            if skip > 0 {
867                // Fabricate a header.
868                t!("Recovered after {} bytes of junk", skip);
869
870                pending_error = Some(crate::Error::MalformedPacket(
871                    format!("Encountered {} bytes of junk at offset {}",
872                            skip, self.bytes_read)).into());
873
874                // Be careful: if we recovered, then we
875                // reader.total_out() includes the good header.
876                processed += skip;
877
878                break;
879            }
880
881            let tag = header.ctb().tag();
882            t!("Found a {:?}, length: {:?}",
883               tag, header.length());
884
885            if packet_start > cert_start
886                && (tag == Tag::PublicKey || tag == Tag::SecretKey)
887            {
888                // Start of new cert.  Note: we don't advanced
889                // processed!  That would consume the header that
890                // we want to read the next time this function is
891                // called.
892                t!("Stopping: found the start of a new cert ({})", tag);
893                break;
894            }
895
896            match header.length() {
897                BodyLength::Full(l) => {
898                    let l = *l as usize;
899
900                    match reader.data_consume_hard(l) {
901                        Err(err) => {
902                            t!("Stopping: reading {}'s body: {}", tag, err);
903
904                            // If we encountered an EOF while reading
905                            // the packet body, then we're done.
906                            if err.kind() == std::io::ErrorKind::UnexpectedEof {
907                                t!("Got an unexpected EOF, done.");
908                                self.done = true;
909                            }
910
911                            pending_error = Some(
912                                anyhow::Error::from(err).context(format!(
913                                    "While reading {}'s body", tag)));
914
915                            break;
916                        }
917                        Ok(data) => {
918                            if tag == Tag::PublicKey
919                                || tag == Tag::SecretKey
920                            {
921                                let data = &data[..l];
922                                match Key::from_bytes(data) {
923                                    Err(err) => {
924                                        t!("Stopping: parsing public key: {}",
925                                           err);
926                                        primary_key = Some(Err(err));
927                                    }
928                                    Ok(key) => primary_key = Some(
929                                        Ok(key.parts_into_public()
930                                           .role_into_primary())),
931                                }
932                            }
933                        }
934                    }
935                }
936                BodyLength::Partial(_) => {
937                    t!("Stopping: Partial body length not allowed \
938                        for {} packets",
939                       tag);
940                    pending_error = Some(
941                        crate::Error::MalformedPacket(
942                            format!("Packet {} uses partial body length \
943                                     encoding, which is not allowed in \
944                                     certificates",
945                                    tag))
946                            .into());
947                    self.done = true;
948                    break;
949                }
950                BodyLength::Indeterminate => {
951                    t!("Stopping: Indeterminate length not allowed \
952                        for {} packets",
953                       tag);
954                    pending_error = Some(
955                        crate::Error::MalformedPacket(
956                            format!("Packet {} uses intedeterminite length \
957                                     encoding, which is not allowed in \
958                                     certificates",
959                                    tag))
960                            .into());
961                    self.done = true;
962                    break;
963                }
964            }
965
966            let end = reader.total_out();
967            processed = end;
968
969            let r = if packet_start == cert_start {
970                if tag == Tag::Marker {
971                    // Silently skip marker packets at the start of a
972                    // packet sequence.
973                    cert_start = end;
974                    Ok(())
975                } else {
976                    packets.push((tag, header_len, packet_start));
977                    Cert::valid_start(tag)
978                }
979            } else {
980                packets.push((tag, header_len, packet_start));
981                Cert::valid_packet(tag)
982            };
983            if let Err(err) = r {
984                t!("Stopping: {:?} => not a certificate: {}", header, err);
985                pending_error = Some(err);
986
987                if self.bytes_read == 0 && packet_start == cert_start
988                    && matches!(tag, Tag::Unknown(_) | Tag::Private(_))
989                {
990                    // The very first packet is not known.  Don't
991                    // bother to parse anything else.
992                    self.done = true;
993                }
994
995                break;
996            }
997
998            cert_end = end;
999        }
1000
1001        t!("{} bytes processed; RawCert @ offset {}, {} bytes",
1002           processed,
1003           self.bytes_read + cert_start, cert_end - cert_start);
1004
1005        assert!(cert_start <= cert_end);
1006        assert!(cert_end <= processed);
1007        self.bytes_read += processed;
1008
1009        // Strip the buffered_reader::Dup.
1010        self.reader = Box::new(reader).into_inner()
1011            .expect("just put it there");
1012
1013        // Consume the data.
1014        let cert_data = &self.reader
1015            .data_consume_hard(processed)
1016            .expect("just read it")[cert_start..cert_end];
1017
1018        if let Some(err) = pending_error.take() {
1019            if cert_start == cert_end {
1020                // We didn't read anything.
1021                t!("Directly returning the error");
1022                return Some(Err(err));
1023            } else {
1024                t!("Queuing the error");
1025                self.pending_error = Some(err);
1026            }
1027        }
1028
1029        if cert_start == cert_end {
1030            t!("No data.");
1031            return None;
1032        }
1033
1034        match primary_key.expect("set") {
1035            Ok(primary_key) => Some(Ok(RawCert {
1036                data: if let Some(slice) = self.slice.as_ref() {
1037                    let data = &slice[cert_start_absolute + cert_start
1038                                      ..cert_start_absolute + cert_end];
1039                    assert_eq!(data, cert_data);
1040                    Cow::Borrowed(data)
1041                } else {
1042                    Cow::Owned(cert_data.to_vec())
1043                },
1044                primary_key,
1045                packets,
1046            })),
1047            Err(err) =>
1048                Some(Err(Error::UnsupportedCert(err, cert_data.into()).into())),
1049        }
1050    }
1051}
1052
1053/// Errors used in this module.
1054#[non_exhaustive]
1055#[derive(thiserror::Error, Debug)]
1056pub enum Error {
1057    /// Unsupported Cert.
1058    ///
1059    /// This usually occurs, because the primary key is in an
1060    /// unsupported format.  In particular, Sequoia does not support
1061    /// version 3 keys.
1062    #[error("Unsupported Cert: {0}")]
1063    UnsupportedCert(anyhow::Error, Vec<u8>),
1064}
1065
1066#[cfg(test)]
1067mod test {
1068    use super::*;
1069
1070    use crate::cert::CertParser;
1071    use crate::cert::CertBuilder;
1072    use crate::packet::Literal;
1073    use crate::parse::RECOVERY_THRESHOLD;
1074    use crate::parse::PacketParserResult;
1075    use crate::serialize::Serialize;
1076    use crate::types::DataFormat;
1077    use crate::packet::Unknown;
1078    use crate::packet::CompressedData;
1079
1080    fn cert_cmp(a: Cert, b: Cert)
1081    {
1082        if a == b {
1083            return;
1084        }
1085
1086        let a = a.into_tsk().into_packets().collect::<Vec<_>>();
1087        let b = b.into_tsk().into_packets().collect::<Vec<_>>();
1088
1089        for (i, (a, b)) in a.iter().zip(b.iter()).enumerate() {
1090            if a != b {
1091                panic!("Differ at element #{}:\n  {:?}\n  {:?}",
1092                       i, a, b);
1093            }
1094        }
1095        if a.len() > b.len() {
1096            eprintln!("Left has more packets:");
1097            for p in &a[b.len()..] {
1098                eprintln!("  - {}", p.tag());
1099            }
1100        }
1101        if b.len() > a.len() {
1102            eprintln!("Right has more packets:");
1103            for p in &b[a.len()..] {
1104                eprintln!("  - {}", p.tag());
1105            }
1106        }
1107        if a.len() != b.len() {
1108            panic!("Different lengths (common prefix identical): {} vs. {}",
1109                   a.len(), b.len());
1110        }
1111    }
1112
1113    // Compares the result of a RawCertParser with the results of a
1114    // CertParser on a particular byte stream.
1115    fn compare_parse(bytes: &[u8]) -> Vec<RawCert> {
1116        let mut result = Vec::new();
1117
1118        // We do the comparison two times: once with a byte stream
1119        // (this exercises the Cow::Borrowed path), and one
1120        // with a buffered reader (this exercises the Cow::Owned
1121        // code path).
1122        for &from_bytes in [true, false].iter() {
1123            let cp = CertParser::from_bytes(bytes);
1124            let rp = if from_bytes {
1125                eprintln!("=== RawCertParser::from_bytes");
1126                RawCertParser::from_bytes(bytes)
1127            } else {
1128                eprintln!("=== RawCertParser::from_reader");
1129                RawCertParser::from_reader(std::io::Cursor::new(bytes))
1130            };
1131
1132            assert_eq!(cp.is_err(), rp.is_err(),
1133                       "CertParser: {:?}; RawCertParser: {:?}",
1134                       cp.map(|_| "Parsed"),
1135                       rp.map(|_| "Parsed"));
1136            if cp.is_err() && rp.is_err() {
1137                return Vec::new();
1138            }
1139
1140            let mut cp = cp.expect("valid");
1141            let mut rp = rp.expect("valid");
1142
1143            let mut raw_certs = Vec::new();
1144            loop {
1145                eprintln!("=== NEXT CERTPARSER");
1146                let c = cp.next();
1147                eprintln!("=== END CERTPARSER");
1148                eprintln!("=== NEXT RAWCERTPARSER");
1149                let r = rp.next();
1150                eprintln!("=== END RAWCERTPARSER");
1151
1152                let (c, r) = match (c, r) {
1153                    // Both return ok.
1154                    (Some(Ok(c)), Some(Ok(r))) => (c, r),
1155                    // Both return an error.
1156                    (Some(Err(_)), Some(Err(_))) => continue,
1157                    // Both return EOF.
1158                    (None, None) => break,
1159                    (c, r) => {
1160                        panic!("\n\
1161                                CertParser returned: {:?}\n\
1162                                RawCertParser returned: {:?}",
1163                               c, r);
1164                    }
1165                };
1166
1167                assert_eq!(c.fingerprint(), r.fingerprint());
1168
1169                eprintln!("CertParser says:");
1170                for (i, p) in c.clone().into_tsk().into_packets().enumerate() {
1171                    eprintln!("  - {}. {}", i, p.tag());
1172                }
1173
1174                let rp = Cert::from_bytes(r.as_bytes()).unwrap();
1175                eprintln!("RawCertParser says:");
1176                for (i, p) in rp.clone().into_tsk().into_packets().enumerate() {
1177                    eprintln!("  - {}. {}", i, p.tag());
1178                }
1179
1180                cert_cmp(c.clone(), rp);
1181
1182                raw_certs.push(r);
1183            }
1184
1185            result = raw_certs;
1186        }
1187        result
1188    }
1189
1190    #[test]
1191    fn empty() {
1192        let bytes = &[];
1193
1194        let certs = compare_parse(bytes);
1195        assert_eq!(certs.len(), 0);
1196    }
1197
1198    #[test]
1199    fn a_cert() {
1200        let testy = crate::tests::key("testy.pgp");
1201
1202        let bytes = testy;
1203
1204        let certs = compare_parse(bytes);
1205        assert_eq!(certs.len(), 1);
1206        let cert = &certs[0];
1207        assert_eq!(cert.as_bytes(), testy);
1208
1209        let tags = &[ Tag::PublicKey,
1210                      Tag::UserID, Tag::Signature,
1211                      Tag::PublicSubkey, Tag::Signature
1212        ];
1213        assert_eq!(
1214            &cert.packets().map(|p| p.tag()).collect::<Vec<Tag>>()[..],
1215            tags);
1216
1217        // Check that we can parse the individual packets and that
1218        // they have the correct tag.
1219        for (p, tag) in cert.packets().zip(tags.iter()) {
1220            let ppr = PacketParser::from_bytes(p.as_bytes()).expect("valid");
1221            if let PacketParserResult::Some(pp) = ppr {
1222                let (p, pp) = pp.next().expect("valid");
1223                assert_eq!(p.tag(), *tag);
1224                assert!(matches!(pp, PacketParserResult::EOF(_)));
1225            } else {
1226                panic!("Unexpected EOF");
1227            }
1228        }
1229    }
1230
1231    #[test]
1232    fn two_certs() {
1233        let testy = crate::tests::key("testy.pgp");
1234
1235        let mut bytes = testy.to_vec();
1236        bytes.extend_from_slice(testy);
1237
1238        let certs = compare_parse(&bytes[..]);
1239        assert_eq!(certs.len(), 2);
1240        for cert in certs.into_iter() {
1241            assert_eq!(cert.as_bytes(), testy);
1242            assert_eq!(
1243                &cert.packets().map(|p| p.tag()).collect::<Vec<Tag>>()[..],
1244                &[ Tag::PublicKey,
1245                   Tag::UserID, Tag::Signature,
1246                   Tag::PublicSubkey, Tag::Signature
1247                ]);
1248        }
1249    }
1250
1251    #[test]
1252    fn marker_packet_ignored() {
1253        use crate::serialize::Serialize;
1254
1255        // Only a marker packet.
1256        let mut marker = Vec::new();
1257        Packet::Marker(Default::default())
1258            .serialize(&mut marker).unwrap();
1259        compare_parse(&marker[..]);
1260
1261        // Marker at the start.
1262        let mut testy_with_marker = Vec::new();
1263        Packet::Marker(Default::default())
1264            .serialize(&mut testy_with_marker).unwrap();
1265        testy_with_marker.extend_from_slice(crate::tests::key("testy.pgp"));
1266        compare_parse(&testy_with_marker[..]);
1267
1268        // Marker at the end.
1269        let mut testy_with_marker = Vec::new();
1270        testy_with_marker.extend_from_slice(crate::tests::key("testy.pgp"));
1271        Packet::Marker(Default::default())
1272            .serialize(&mut testy_with_marker).unwrap();
1273        compare_parse(&testy_with_marker[..]);
1274    }
1275
1276    #[test]
1277    fn invalid_packets() -> Result<()> {
1278        tracer!(TRACE, "invalid_packets", 0);
1279
1280        let (cert, _) =
1281            CertBuilder::general_purpose(Some("alice@example.org"))
1282            .generate()?;
1283        let cert = cert.into_packets().collect::<Vec<_>>();
1284
1285        // A userid packet.
1286        let userid : Packet = cert.clone()
1287            .into_iter()
1288            .filter(|p| p.tag() == Tag::UserID)
1289            .next()
1290            .unwrap();
1291
1292        // An unknown packet.
1293        let tag = Tag::Private(61);
1294        let unknown : Packet
1295            = Unknown::new(tag, crate::Error::UnsupportedPacketType(tag).into())
1296            .into();
1297
1298        // A literal packet.  (This is a valid OpenPGP Message.)
1299        let mut lit = Literal::new(DataFormat::Unicode);
1300        lit.set_body(b"test".to_vec());
1301        let lit = Packet::from(lit);
1302
1303        // A compressed data packet containing a literal data packet.
1304        // (This is a valid OpenPGP Message.)
1305        let cd = {
1306            use crate::types::CompressionAlgorithm;
1307            use crate::packet;
1308            use crate::PacketPile;
1309            use crate::serialize::Serialize;
1310            use crate::parse::Parse;
1311
1312            let mut cd = CompressedData::new(
1313                CompressionAlgorithm::Uncompressed);
1314            let mut body = Vec::new();
1315            lit.serialize(&mut body)?;
1316            cd.set_body(packet::Body::Processed(body));
1317            let cd = Packet::from(cd);
1318
1319            // Make sure we created the message correctly: serialize,
1320            // parse it, and then check its form.
1321            let mut bytes = Vec::new();
1322            cd.serialize(&mut bytes)?;
1323
1324            let pp = PacketPile::from_bytes(&bytes[..])?;
1325
1326            assert_eq!(pp.descendants().count(), 2);
1327            assert_eq!(pp.path_ref(&[ 0 ]).unwrap().tag(),
1328                       packet::Tag::CompressedData);
1329            assert_eq!(pp.path_ref(&[ 0, 0 ]), Some(&lit));
1330
1331            cd
1332        };
1333
1334        fn check(input: impl Iterator<Item=Packet>) {
1335            let mut bytes = Vec::new();
1336            for p in input {
1337                p.serialize(&mut bytes).unwrap();
1338            }
1339
1340            compare_parse(&bytes[..]);
1341        }
1342
1343        fn interleave(cert: &Vec<Packet>, p: &Packet) {
1344            t!("A certificate, a {}.", p.tag());
1345            check(
1346                cert.clone().into_iter()
1347                    .chain(p.clone()));
1348
1349            t!("A certificate, two {}.", p.tag());
1350            check(
1351                cert.clone().into_iter()
1352                    .chain(p.clone())
1353                    .chain(p.clone()));
1354
1355            t!("A {}, a certificate.", p.tag());
1356            check(
1357                p.clone().into_iter()
1358                    .chain(cert.clone()));
1359
1360            t!("Two {}, a certificate.", p.tag());
1361            check(
1362                p.clone().into_iter()
1363                    .chain(p.clone())
1364                    .chain(cert.clone()));
1365
1366            t!("Two {}, a certificate, two {}.", p.tag(), p.tag());
1367            check(
1368                p.clone().into_iter()
1369                    .chain(p.clone())
1370                    .chain(cert.clone())
1371                    .chain(p.clone())
1372                    .chain(p.clone()));
1373
1374            t!("Two {}, two certificates, two {}, a certificate.");
1375            check(
1376                p.clone().into_iter()
1377                    .chain(p.clone())
1378                    .chain(cert.clone())
1379                    .chain(cert.clone())
1380                    .chain(p.clone())
1381                    .chain(p.clone())
1382                    .chain(cert.clone()));
1383        }
1384
1385        interleave(&cert, &lit);
1386
1387        // The certificate parser shouldn't recurse into containers.
1388        // So, the compressed data packets should show up as a single
1389        // error.
1390        interleave(&cert, &cd);
1391
1392
1393        // The certificate parser should treat unknown packets as
1394        // valid certificate components.
1395        let mut cert_plus = cert.clone();
1396        cert_plus.push(unknown.clone());
1397
1398        t!("A certificate, an unknown.");
1399        check(
1400            cert.clone().into_iter()
1401                .chain(unknown.clone()));
1402
1403        t!("An unknown, a certificate.");
1404        check(
1405             unknown.clone().into_iter()
1406                 .chain(cert.clone()));
1407
1408        t!("A certificate, two unknowns.");
1409        check(
1410            cert.clone().into_iter()
1411                .chain(unknown.clone())
1412                .chain(unknown.clone()));
1413
1414        t!("A certificate, an unknown, a certificate.");
1415        check(
1416            cert.clone().into_iter()
1417                .chain(unknown.clone())
1418                .chain(cert.clone()));
1419
1420        t!("A Literal, two User IDs");
1421        check(
1422            lit.clone().into_iter()
1423                .chain(userid.clone())
1424                .chain(userid.clone()));
1425
1426        t!("A User ID, a certificate");
1427        check(
1428            userid.clone().into_iter()
1429                .chain(cert.clone()));
1430
1431        t!("Two User IDs, a certificate");
1432        check(
1433            userid.clone().into_iter()
1434                .chain(userid.clone())
1435                .chain(cert.clone()));
1436
1437        Ok(())
1438    }
1439
1440    fn parse_test(n: usize, literal: bool, bad: usize) -> Result<()> {
1441        tracer!(TRACE, "t", 0);
1442
1443        // Parses keyrings with different numbers of keys and
1444        // different errors.
1445
1446        // n: number of keys
1447        // literal: whether to interleave literal packets.
1448        // bad: whether to insert invalid data (NUL bytes where
1449        //      the start of a certificate is expected).
1450        let nulls = vec![ 0; bad ];
1451
1452        t!("n: {}, literals: {}, bad data: {}",
1453           n, literal, bad);
1454
1455        let mut data = Vec::new();
1456
1457        let mut certs_orig = vec![];
1458        for i in 0..n {
1459            let (cert, _) =
1460                CertBuilder::general_purpose(
1461                    Some(format!("{}@example.org", i)))
1462                .generate()?;
1463
1464            cert.as_tsk().serialize(&mut data)?;
1465            certs_orig.push(cert);
1466
1467            if literal {
1468                let mut lit = Literal::new(DataFormat::Unicode);
1469                lit.set_body(b"data".to_vec());
1470
1471                Packet::from(lit).serialize(&mut data)?;
1472            }
1473            // Push some NUL bytes.
1474            data.extend(&nulls[..bad]);
1475        }
1476        if n == 0 {
1477            // Push some NUL bytes even if we didn't add any packets.
1478            data.extend(&nulls[..bad]);
1479        }
1480        assert_eq!(certs_orig.len(), n);
1481
1482        t!("Start of data: {} {}",
1483           if let Some(x) = data.get(0) {
1484               format!("{:02X}", x)
1485           } else {
1486               "XX".into()
1487           },
1488           if let Some(x) = data.get(1) {
1489               format!("{:02X}", x)
1490           } else {
1491               "XX".into()
1492           });
1493
1494        compare_parse(&data);
1495
1496        Ok(())
1497    }
1498
1499    #[test]
1500    fn parse_keyring_simple() -> Result<()> {
1501        for n in [1, 100, 0].iter() {
1502            parse_test(*n, false, 0)?;
1503        }
1504
1505        Ok(())
1506    }
1507
1508    #[test]
1509    fn parse_keyring_interleaved_literals() -> Result<()> {
1510        for n in [1, 100, 0].iter() {
1511            parse_test(*n, true, 0)?;
1512        }
1513
1514        Ok(())
1515    }
1516
1517    #[test]
1518    fn parse_keyring_interleaved_small_junk() -> Result<()> {
1519        for n in [1, 100, 0].iter() {
1520            parse_test(*n, false, 1)?;
1521        }
1522
1523        Ok(())
1524    }
1525
1526    #[test]
1527    fn parse_keyring_interleaved_unrecoverable_junk() -> Result<()> {
1528        // PacketParser is pretty good at recovering from junk in the
1529        // middle: it will search the next RECOVERY_THRESHOLD bytes
1530        // for a valid packet.  If it finds it, it will turn the junk
1531        // into a reserved packet and resume.  Insert a lot of NULs to
1532        // prevent the recovery mechanism from working.
1533        for n in [1, 100, 0].iter() {
1534            parse_test(*n, false, 2 * RECOVERY_THRESHOLD)?;
1535        }
1536
1537        Ok(())
1538    }
1539
1540    #[test]
1541    fn parse_keyring_interleaved_literal_and_small_junk() -> Result<()> {
1542        for n in [1, 100, 0].iter() {
1543            parse_test(*n, true, 1)?;
1544        }
1545
1546        Ok(())
1547    }
1548
1549    #[test]
1550    fn parse_keyring_interleaved_literal_and_unrecoverable_junk() -> Result<()> {
1551        for n in [1, 100, 0].iter() {
1552            parse_test(*n, true, 2 * RECOVERY_THRESHOLD)?;
1553        }
1554
1555        Ok(())
1556    }
1557
1558    #[test]
1559    fn parse_keyring_no_public_key() -> Result<()> {
1560        tracer!(TRACE, "parse_keyring_no_public_key", 0);
1561
1562        // The first few packets are not the valid start of a
1563        // certificate.  Each of those should return in an Error.
1564        // But, that shouldn't stop us from parsing the rest of the
1565        // keyring.
1566
1567        let (cert_1, _) =
1568            CertBuilder::general_purpose(
1569                Some("a@example.org"))
1570            .generate()?;
1571        let cert_1_packets: Vec<Packet>
1572            = cert_1.into_packets().collect();
1573
1574        let (cert_2, _) =
1575            CertBuilder::general_purpose(
1576                Some("b@example.org"))
1577            .generate()?;
1578
1579        for n in 1..cert_1_packets.len() {
1580            t!("n: {}", n);
1581
1582            let mut data = Vec::new();
1583
1584            for i in n..cert_1_packets.len() {
1585                cert_1_packets[i].serialize(&mut data)?;
1586            }
1587
1588            cert_2.as_tsk().serialize(&mut data)?;
1589
1590            compare_parse(&data);
1591        }
1592
1593        Ok(())
1594    }
1595
1596    #[test]
1597    fn accessors() {
1598        let testy = crate::tests::key("testy.pgp");
1599
1600        let certs = RawCertParser::from_bytes(testy)
1601            .expect("valid")
1602            .collect::<Result<Vec<RawCert>>>()
1603            .expect("valid");
1604        assert_eq!(certs.len(), 1);
1605        let cert = &certs[0];
1606        assert_eq!(cert.as_bytes(), testy);
1607
1608        assert_eq!(cert.primary_key().fingerprint(),
1609                   "3E8877C877274692975189F5D03F6F865226FE8B"
1610                       .parse().expect("valid"));
1611        assert_eq!(cert.keys().map(|k| k.fingerprint()).collect::<Vec<_>>(),
1612                   vec![
1613                       "3E8877C877274692975189F5D03F6F865226FE8B"
1614                           .parse().expect("valid"),
1615                       "01F187575BD45644046564C149E2118166C92632"
1616                           .parse().expect("valid")
1617                   ]);
1618        assert_eq!(cert.keys().subkeys()
1619                   .map(|k| k.fingerprint()).collect::<Vec<_>>(),
1620                   vec![
1621                       "01F187575BD45644046564C149E2118166C92632"
1622                           .parse().expect("valid")
1623                   ]);
1624        assert_eq!(
1625            cert.userids()
1626                .map(|u| {
1627                    String::from_utf8_lossy(u.value()).into_owned()
1628                })
1629                .collect::<Vec<_>>(),
1630            vec![ "Testy McTestface <testy@example.org>" ]);
1631    }
1632
1633    // Test the raw cert parser implementation.
1634    #[test]
1635    fn raw_cert_parser_impl() {
1636        // Read one certificate.
1637        let testy = crate::tests::key("testy.pgp");
1638
1639        let raw = RawCert::from_bytes(testy).expect("valid");
1640        let cert = Cert::from_bytes(testy).expect("valid");
1641
1642        assert_eq!(
1643            raw.keys().map(|k| k.fingerprint()).collect::<Vec<_>>(),
1644            cert.keys().map(|k| k.key().fingerprint()).collect::<Vec<_>>());
1645
1646        assert_eq!(
1647            raw.userids().collect::<Vec<_>>(),
1648            cert.userids().map(|ua| ua.userid().clone()).collect::<Vec<_>>());
1649
1650        // Parse zero certificates.
1651        eprintln!("Parsing 0 bytes");
1652        let raw = RawCert::from_bytes(b"");
1653        match &raw {
1654            Ok(_) => eprintln!("raw: Ok"),
1655            Err(err) => eprintln!("raw: {}", err),
1656        }
1657        let cert = Cert::from_bytes(b"");
1658        match &cert {
1659            Ok(_) => eprintln!("cert: Ok"),
1660            Err(err) => eprintln!("cert: {}", err),
1661        }
1662
1663        assert!(
1664            matches!(cert.map_err(|e| e.downcast::<crate::Error>()),
1665                     Err(Ok(crate::Error::MalformedCert(_)))));
1666        assert!(
1667            matches!(raw.map_err(|e| e.downcast::<crate::Error>()),
1668                     Err(Ok(crate::Error::MalformedCert(_)))));
1669
1670        // Parse two certificates.
1671        let mut bytes = Vec::new();
1672        bytes.extend(testy);
1673        bytes.extend(testy);
1674
1675        let parser = CertParser::from_bytes(&bytes).expect("valid");
1676        assert_eq!(parser.count(), 2);
1677
1678        eprintln!("Parsing two certificates");
1679        let raw = RawCert::from_bytes(&bytes);
1680        match &raw {
1681            Ok(_) => eprintln!("raw: Ok"),
1682            Err(err) => eprintln!("raw: {}", err),
1683        }
1684        let cert = Cert::from_bytes(&bytes);
1685        match &cert {
1686            Ok(_) => eprintln!("cert: Ok"),
1687            Err(err) => eprintln!("cert: {}", err),
1688        }
1689
1690        assert!(
1691            matches!(cert.map_err(|e| e.downcast::<crate::Error>()),
1692                     Err(Ok(crate::Error::MalformedCert(_)))));
1693        assert!(
1694            matches!(raw.map_err(|e| e.downcast::<crate::Error>()),
1695                     Err(Ok(crate::Error::MalformedCert(_)))));
1696    }
1697
1698    #[test]
1699    fn concatenated_armored_certs() -> Result<()> {
1700        let mut keyring = Vec::new();
1701        keyring.extend_from_slice(b"some\ntext\n");
1702        keyring.extend_from_slice(crate::tests::key("testy.asc"));
1703        keyring.extend_from_slice(crate::tests::key("testy.asc"));
1704        keyring.extend_from_slice(b"some\ntext\n");
1705        keyring.extend_from_slice(crate::tests::key("testy.asc"));
1706        keyring.extend_from_slice(b"some\ntext\n");
1707        let certs = RawCertParser::from_bytes(&keyring)?.collect::<Vec<_>>();
1708        assert_eq!(certs.len(), 3);
1709        assert!(certs.iter().all(|c| c.is_ok()));
1710        Ok(())
1711    }
1712}