Skip to main content

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                            break Header::new(CTB::new(Tag::Reserved),
832                                              BodyLength::Full(skip as u32));
833                        } else {
834                            skip += 1;
835                            reader.rewind();
836                            reader.consume(packet_start + skip);
837                        }
838                    }
839                    Ok(header) if skip > 0 => {
840                        if PacketParser::plausible_cert(&mut reader, &header)
841                            .is_ok()
842                        {
843                            // We recovered.  First return an error.  The
844                            // next time this function is called, we'll
845                            // resume here.
846                            t!("Found a valid header after {} bytes \
847                                of junk: {:?}",
848                               skip, header);
849
850                            break Header::new(CTB::new(Tag::Reserved),
851                                              BodyLength::Full(skip as u32));
852                        } else {
853                            skip += 1;
854                            reader.rewind();
855                            reader.consume(packet_start + skip);
856                        }
857                    }
858                    Ok(header) => {
859                        header_len = reader.total_out() - packet_start;
860                        break header;
861                    }
862                }
863            };
864
865            if skip > 0 {
866                // Fabricate a header.
867                t!("Recovered after {} bytes of junk", skip);
868
869                pending_error = Some(crate::Error::MalformedPacket(
870                    format!("Encountered {} bytes of junk at offset {}",
871                            skip, self.bytes_read)).into());
872
873                // Be careful: if we recovered, then we
874                // reader.total_out() includes the good header.
875                processed += skip;
876
877                break;
878            }
879
880            let tag = header.ctb().tag();
881            t!("Found a {:?}, length: {:?}",
882               tag, header.length());
883
884            if packet_start > cert_start
885                && (tag == Tag::PublicKey || tag == Tag::SecretKey)
886            {
887                // Start of new cert.  Note: we don't advanced
888                // processed!  That would consume the header that
889                // we want to read the next time this function is
890                // called.
891                t!("Stopping: found the start of a new cert ({})", tag);
892                break;
893            }
894
895            match header.length() {
896                BodyLength::Full(l) => {
897                    let l = *l as usize;
898
899                    match reader.data_consume_hard(l) {
900                        Err(err) => {
901                            t!("Stopping: reading {}'s body: {}", tag, err);
902
903                            // If we encountered an EOF while reading
904                            // the packet body, then we're done.
905                            if err.kind() == std::io::ErrorKind::UnexpectedEof {
906                                t!("Got an unexpected EOF, done.");
907                                self.done = true;
908                            }
909
910                            pending_error = Some(
911                                anyhow::Error::from(err).context(format!(
912                                    "While reading {}'s body", tag)));
913
914                            break;
915                        }
916                        Ok(data) => {
917                            if tag == Tag::PublicKey
918                                || tag == Tag::SecretKey
919                            {
920                                let data = &data[..l];
921                                match Key::from_bytes(data) {
922                                    Err(err) => {
923                                        t!("Stopping: parsing public key: {}",
924                                           err);
925                                        primary_key = Some(Err(err));
926                                    }
927                                    Ok(key) => primary_key = Some(
928                                        Ok(key.parts_into_public()
929                                           .role_into_primary())),
930                                }
931                            }
932                        }
933                    }
934                }
935                BodyLength::Partial(_) => {
936                    t!("Stopping: Partial body length not allowed \
937                        for {} packets",
938                       tag);
939                    pending_error = Some(
940                        crate::Error::MalformedPacket(
941                            format!("Packet {} uses partial body length \
942                                     encoding, which is not allowed in \
943                                     certificates",
944                                    tag))
945                            .into());
946                    self.done = true;
947                    break;
948                }
949                BodyLength::Indeterminate => {
950                    t!("Stopping: Indeterminate length not allowed \
951                        for {} packets",
952                       tag);
953                    pending_error = Some(
954                        crate::Error::MalformedPacket(
955                            format!("Packet {} uses intedeterminite length \
956                                     encoding, which is not allowed in \
957                                     certificates",
958                                    tag))
959                            .into());
960                    self.done = true;
961                    break;
962                }
963            }
964
965            let end = reader.total_out();
966            processed = end;
967
968            let r = if packet_start == cert_start {
969                if tag == Tag::Marker {
970                    // Silently skip marker packets at the start of a
971                    // packet sequence.
972                    cert_start = end;
973                    Ok(())
974                } else {
975                    packets.push((tag, header_len, packet_start));
976                    Cert::valid_start(tag)
977                }
978            } else {
979                packets.push((tag, header_len, packet_start));
980                Cert::valid_packet(tag)
981            };
982            if let Err(err) = r {
983                t!("Stopping: {:?} => not a certificate: {}", header, err);
984                pending_error = Some(err);
985
986                if self.bytes_read == 0 && packet_start == cert_start
987                    && matches!(tag, Tag::Unknown(_) | Tag::Private(_))
988                {
989                    // The very first packet is not known.  Don't
990                    // bother to parse anything else.
991                    self.done = true;
992                }
993
994                break;
995            }
996
997            cert_end = end;
998        }
999
1000        t!("{} bytes processed; RawCert @ offset {}, {} bytes",
1001           processed,
1002           self.bytes_read + cert_start, cert_end - cert_start);
1003
1004        assert!(cert_start <= cert_end);
1005        assert!(cert_end <= processed);
1006        self.bytes_read += processed;
1007
1008        // Strip the buffered_reader::Dup.
1009        self.reader = Box::new(reader).into_inner()
1010            .expect("just put it there");
1011
1012        // Consume the data.
1013        let cert_data = &self.reader
1014            .data_consume_hard(processed)
1015            .expect("just read it")[cert_start..cert_end];
1016
1017        if let Some(err) = pending_error.take() {
1018            if cert_start == cert_end {
1019                // We didn't read anything.
1020                t!("Directly returning the error");
1021                return Some(Err(err));
1022            } else {
1023                t!("Queuing the error");
1024                self.pending_error = Some(err);
1025            }
1026        }
1027
1028        if cert_start == cert_end {
1029            t!("No data.");
1030            return None;
1031        }
1032
1033        match primary_key.expect("set") {
1034            Ok(primary_key) => Some(Ok(RawCert {
1035                data: if let Some(slice) = self.slice.as_ref() {
1036                    let data = &slice[cert_start_absolute + cert_start
1037                                      ..cert_start_absolute + cert_end];
1038                    assert_eq!(data, cert_data);
1039                    Cow::Borrowed(data)
1040                } else {
1041                    Cow::Owned(cert_data.to_vec())
1042                },
1043                primary_key,
1044                packets,
1045            })),
1046            Err(err) =>
1047                Some(Err(Error::UnsupportedCert(err, cert_data.into()).into())),
1048        }
1049    }
1050}
1051
1052/// Errors used in this module.
1053#[non_exhaustive]
1054#[derive(thiserror::Error, Debug)]
1055pub enum Error {
1056    /// Unsupported Cert.
1057    ///
1058    /// This usually occurs, because the primary key is in an
1059    /// unsupported format.  In particular, Sequoia does not support
1060    /// version 3 keys.
1061    #[error("Unsupported Cert: {0}")]
1062    UnsupportedCert(anyhow::Error, Vec<u8>),
1063}
1064
1065#[cfg(test)]
1066mod test {
1067    use super::*;
1068
1069    use crate::cert::CertParser;
1070    use crate::cert::CertBuilder;
1071    use crate::packet::Literal;
1072    use crate::parse::RECOVERY_THRESHOLD;
1073    use crate::parse::PacketParserResult;
1074    use crate::serialize::Serialize;
1075    use crate::types::DataFormat;
1076    use crate::packet::Unknown;
1077    use crate::packet::CompressedData;
1078
1079    fn cert_cmp(a: Cert, b: Cert)
1080    {
1081        if a == b {
1082            return;
1083        }
1084
1085        let a = a.into_tsk().into_packets().collect::<Vec<_>>();
1086        let b = b.into_tsk().into_packets().collect::<Vec<_>>();
1087
1088        for (i, (a, b)) in a.iter().zip(b.iter()).enumerate() {
1089            if a != b {
1090                panic!("Differ at element #{}:\n  {:?}\n  {:?}",
1091                       i, a, b);
1092            }
1093        }
1094        if a.len() > b.len() {
1095            eprintln!("Left has more packets:");
1096            for p in &a[b.len()..] {
1097                eprintln!("  - {}", p.tag());
1098            }
1099        }
1100        if b.len() > a.len() {
1101            eprintln!("Right has more packets:");
1102            for p in &b[a.len()..] {
1103                eprintln!("  - {}", p.tag());
1104            }
1105        }
1106        if a.len() != b.len() {
1107            panic!("Different lengths (common prefix identical): {} vs. {}",
1108                   a.len(), b.len());
1109        }
1110    }
1111
1112    // Compares the result of a RawCertParser with the results of a
1113    // CertParser on a particular byte stream.
1114    fn compare_parse(bytes: &[u8]) -> Vec<RawCert<'_>> {
1115        let mut result = Vec::new();
1116
1117        // We do the comparison two times: once with a byte stream
1118        // (this exercises the Cow::Borrowed path), and one
1119        // with a buffered reader (this exercises the Cow::Owned
1120        // code path).
1121        for &from_bytes in [true, false].iter() {
1122            let cp = CertParser::from_bytes(bytes);
1123            let rp = if from_bytes {
1124                eprintln!("=== RawCertParser::from_bytes");
1125                RawCertParser::from_bytes(bytes)
1126            } else {
1127                eprintln!("=== RawCertParser::from_reader");
1128                RawCertParser::from_reader(std::io::Cursor::new(bytes))
1129            };
1130
1131            assert_eq!(cp.is_err(), rp.is_err(),
1132                       "CertParser: {:?}; RawCertParser: {:?}",
1133                       cp.map(|_| "Parsed"),
1134                       rp.map(|_| "Parsed"));
1135            if cp.is_err() && rp.is_err() {
1136                return Vec::new();
1137            }
1138
1139            let mut cp = cp.expect("valid");
1140            let mut rp = rp.expect("valid");
1141
1142            let mut raw_certs = Vec::new();
1143            loop {
1144                eprintln!("=== NEXT CERTPARSER");
1145                let c = cp.next();
1146                eprintln!("=== END CERTPARSER");
1147                eprintln!("=== NEXT RAWCERTPARSER");
1148                let r = rp.next();
1149                eprintln!("=== END RAWCERTPARSER");
1150
1151                let (c, r) = match (c, r) {
1152                    // Both return ok.
1153                    (Some(Ok(c)), Some(Ok(r))) => (c, r),
1154                    // Both return an error.
1155                    (Some(Err(_)), Some(Err(_))) => continue,
1156                    // Both return EOF.
1157                    (None, None) => break,
1158                    (c, r) => {
1159                        panic!("\n\
1160                                CertParser returned: {:?}\n\
1161                                RawCertParser returned: {:?}",
1162                               c, r);
1163                    }
1164                };
1165
1166                assert_eq!(c.fingerprint(), r.fingerprint());
1167
1168                eprintln!("CertParser says:");
1169                for (i, p) in c.clone().into_tsk().into_packets().enumerate() {
1170                    eprintln!("  - {}. {}", i, p.tag());
1171                }
1172
1173                let rp = Cert::from_bytes(r.as_bytes()).unwrap();
1174                eprintln!("RawCertParser says:");
1175                for (i, p) in rp.clone().into_tsk().into_packets().enumerate() {
1176                    eprintln!("  - {}. {}", i, p.tag());
1177                }
1178
1179                cert_cmp(c.clone(), rp);
1180
1181                raw_certs.push(r);
1182            }
1183
1184            result = raw_certs;
1185        }
1186        result
1187    }
1188
1189    #[test]
1190    fn empty() {
1191        let bytes = &[];
1192
1193        let certs = compare_parse(bytes);
1194        assert_eq!(certs.len(), 0);
1195    }
1196
1197    #[test]
1198    fn a_cert() {
1199        let testy = crate::tests::key("testy.pgp");
1200
1201        let bytes = testy;
1202
1203        let certs = compare_parse(bytes);
1204        assert_eq!(certs.len(), 1);
1205        let cert = &certs[0];
1206        assert_eq!(cert.as_bytes(), testy);
1207
1208        let tags = &[ Tag::PublicKey,
1209                      Tag::UserID, Tag::Signature,
1210                      Tag::PublicSubkey, Tag::Signature
1211        ];
1212        assert_eq!(
1213            &cert.packets().map(|p| p.tag()).collect::<Vec<Tag>>()[..],
1214            tags);
1215
1216        // Check that we can parse the individual packets and that
1217        // they have the correct tag.
1218        for (p, tag) in cert.packets().zip(tags.iter()) {
1219            let ppr = PacketParser::from_bytes(p.as_bytes()).expect("valid");
1220            if let PacketParserResult::Some(pp) = ppr {
1221                let (p, pp) = pp.next().expect("valid");
1222                assert_eq!(p.tag(), *tag);
1223                assert!(matches!(pp, PacketParserResult::EOF(_)));
1224            } else {
1225                panic!("Unexpected EOF");
1226            }
1227        }
1228    }
1229
1230    #[test]
1231    fn two_certs() {
1232        let testy = crate::tests::key("testy.pgp");
1233
1234        let mut bytes = testy.to_vec();
1235        bytes.extend_from_slice(testy);
1236
1237        let certs = compare_parse(&bytes[..]);
1238        assert_eq!(certs.len(), 2);
1239        for cert in certs.into_iter() {
1240            assert_eq!(cert.as_bytes(), testy);
1241            assert_eq!(
1242                &cert.packets().map(|p| p.tag()).collect::<Vec<Tag>>()[..],
1243                &[ Tag::PublicKey,
1244                   Tag::UserID, Tag::Signature,
1245                   Tag::PublicSubkey, Tag::Signature
1246                ]);
1247        }
1248    }
1249
1250    #[test]
1251    fn marker_packet_ignored() {
1252        use crate::serialize::Serialize;
1253
1254        // Only a marker packet.
1255        let mut marker = Vec::new();
1256        Packet::Marker(Default::default())
1257            .serialize(&mut marker).unwrap();
1258        compare_parse(&marker[..]);
1259
1260        // Marker at the start.
1261        let mut testy_with_marker = Vec::new();
1262        Packet::Marker(Default::default())
1263            .serialize(&mut testy_with_marker).unwrap();
1264        testy_with_marker.extend_from_slice(crate::tests::key("testy.pgp"));
1265        compare_parse(&testy_with_marker[..]);
1266
1267        // Marker at the end.
1268        let mut testy_with_marker = Vec::new();
1269        testy_with_marker.extend_from_slice(crate::tests::key("testy.pgp"));
1270        Packet::Marker(Default::default())
1271            .serialize(&mut testy_with_marker).unwrap();
1272        compare_parse(&testy_with_marker[..]);
1273    }
1274
1275    #[test]
1276    fn invalid_packets() -> Result<()> {
1277        tracer!(TRACE, "invalid_packets", 0);
1278
1279        let (cert, _) =
1280            CertBuilder::general_purpose(Some("alice@example.org"))
1281            .generate()?;
1282        let cert = cert.into_packets().collect::<Vec<_>>();
1283
1284        // A userid packet.
1285        let userid : Packet = cert.clone()
1286            .into_iter()
1287            .filter(|p| p.tag() == Tag::UserID)
1288            .next()
1289            .unwrap();
1290
1291        // An unknown packet.
1292        let tag = Tag::Private(61);
1293        let unknown : Packet
1294            = Unknown::new(tag, crate::Error::UnsupportedPacketType(tag).into())
1295            .into();
1296
1297        // A literal packet.  (This is a valid OpenPGP Message.)
1298        let mut lit = Literal::new(DataFormat::Unicode);
1299        lit.set_body(b"test".to_vec());
1300        let lit = Packet::from(lit);
1301
1302        // A compressed data packet containing a literal data packet.
1303        // (This is a valid OpenPGP Message.)
1304        let cd = {
1305            use crate::types::CompressionAlgorithm;
1306            use crate::packet;
1307            use crate::PacketPile;
1308            use crate::serialize::Serialize;
1309            use crate::parse::Parse;
1310
1311            let mut cd = CompressedData::new(
1312                CompressionAlgorithm::Uncompressed);
1313            let mut body = Vec::new();
1314            lit.serialize(&mut body)?;
1315            cd.set_body(packet::Body::Processed(body));
1316            let cd = Packet::from(cd);
1317
1318            // Make sure we created the message correctly: serialize,
1319            // parse it, and then check its form.
1320            let mut bytes = Vec::new();
1321            cd.serialize(&mut bytes)?;
1322
1323            let pp = PacketPile::from_bytes(&bytes[..])?;
1324
1325            assert_eq!(pp.descendants().count(), 2);
1326            assert_eq!(pp.path_ref(&[ 0 ]).unwrap().tag(),
1327                       packet::Tag::CompressedData);
1328            assert_eq!(pp.path_ref(&[ 0, 0 ]), Some(&lit));
1329
1330            cd
1331        };
1332
1333        fn check(input: impl Iterator<Item=Packet>) {
1334            let mut bytes = Vec::new();
1335            for p in input {
1336                p.serialize(&mut bytes).unwrap();
1337            }
1338
1339            compare_parse(&bytes[..]);
1340        }
1341
1342        fn interleave(cert: &Vec<Packet>, p: &Packet) {
1343            t!("A certificate, a {}.", p.tag());
1344            check(
1345                cert.clone().into_iter()
1346                    .chain(p.clone()));
1347
1348            t!("A certificate, two {}.", p.tag());
1349            check(
1350                cert.clone().into_iter()
1351                    .chain(p.clone())
1352                    .chain(p.clone()));
1353
1354            t!("A {}, a certificate.", p.tag());
1355            check(
1356                p.clone().into_iter()
1357                    .chain(cert.clone()));
1358
1359            t!("Two {}, a certificate.", p.tag());
1360            check(
1361                p.clone().into_iter()
1362                    .chain(p.clone())
1363                    .chain(cert.clone()));
1364
1365            t!("Two {}, a certificate, two {}.", p.tag(), p.tag());
1366            check(
1367                p.clone().into_iter()
1368                    .chain(p.clone())
1369                    .chain(cert.clone())
1370                    .chain(p.clone())
1371                    .chain(p.clone()));
1372
1373            t!("Two {}, two certificates, two {}, a certificate.");
1374            check(
1375                p.clone().into_iter()
1376                    .chain(p.clone())
1377                    .chain(cert.clone())
1378                    .chain(cert.clone())
1379                    .chain(p.clone())
1380                    .chain(p.clone())
1381                    .chain(cert.clone()));
1382        }
1383
1384        interleave(&cert, &lit);
1385
1386        // The certificate parser shouldn't recurse into containers.
1387        // So, the compressed data packets should show up as a single
1388        // error.
1389        interleave(&cert, &cd);
1390
1391
1392        // The certificate parser should treat unknown packets as
1393        // valid certificate components.
1394        let mut cert_plus = cert.clone();
1395        cert_plus.push(unknown.clone());
1396
1397        t!("A certificate, an unknown.");
1398        check(
1399            cert.clone().into_iter()
1400                .chain(unknown.clone()));
1401
1402        t!("An unknown, a certificate.");
1403        check(
1404             unknown.clone().into_iter()
1405                 .chain(cert.clone()));
1406
1407        t!("A certificate, two unknowns.");
1408        check(
1409            cert.clone().into_iter()
1410                .chain(unknown.clone())
1411                .chain(unknown.clone()));
1412
1413        t!("A certificate, an unknown, a certificate.");
1414        check(
1415            cert.clone().into_iter()
1416                .chain(unknown.clone())
1417                .chain(cert.clone()));
1418
1419        t!("A Literal, two User IDs");
1420        check(
1421            lit.clone().into_iter()
1422                .chain(userid.clone())
1423                .chain(userid.clone()));
1424
1425        t!("A User ID, a certificate");
1426        check(
1427            userid.clone().into_iter()
1428                .chain(cert.clone()));
1429
1430        t!("Two User IDs, a certificate");
1431        check(
1432            userid.clone().into_iter()
1433                .chain(userid.clone())
1434                .chain(cert.clone()));
1435
1436        Ok(())
1437    }
1438
1439    fn parse_test(n: usize, literal: bool, bad: usize) -> Result<()> {
1440        tracer!(TRACE, "t", 0);
1441
1442        // Parses keyrings with different numbers of keys and
1443        // different errors.
1444
1445        // n: number of keys
1446        // literal: whether to interleave literal packets.
1447        // bad: whether to insert invalid data (NUL bytes where
1448        //      the start of a certificate is expected).
1449        let nulls = vec![ 0; bad ];
1450
1451        t!("n: {}, literals: {}, bad data: {}",
1452           n, literal, bad);
1453
1454        let mut data = Vec::new();
1455
1456        let mut certs_orig = vec![];
1457        for i in 0..n {
1458            let (cert, _) =
1459                CertBuilder::general_purpose(
1460                    Some(format!("{}@example.org", i)))
1461                .generate()?;
1462
1463            cert.as_tsk().serialize(&mut data)?;
1464            certs_orig.push(cert);
1465
1466            if literal {
1467                let mut lit = Literal::new(DataFormat::Unicode);
1468                lit.set_body(b"data".to_vec());
1469
1470                Packet::from(lit).serialize(&mut data)?;
1471            }
1472            // Push some NUL bytes.
1473            data.extend(&nulls[..bad]);
1474        }
1475        if n == 0 {
1476            // Push some NUL bytes even if we didn't add any packets.
1477            data.extend(&nulls[..bad]);
1478        }
1479        assert_eq!(certs_orig.len(), n);
1480
1481        t!("Start of data: {} {}",
1482           if let Some(x) = data.get(0) {
1483               format!("{:02X}", x)
1484           } else {
1485               "XX".into()
1486           },
1487           if let Some(x) = data.get(1) {
1488               format!("{:02X}", x)
1489           } else {
1490               "XX".into()
1491           });
1492
1493        compare_parse(&data);
1494
1495        Ok(())
1496    }
1497
1498    #[test]
1499    fn parse_keyring_simple() -> Result<()> {
1500        for n in [1, 100, 0].iter() {
1501            parse_test(*n, false, 0)?;
1502        }
1503
1504        Ok(())
1505    }
1506
1507    #[test]
1508    fn parse_keyring_interleaved_literals() -> Result<()> {
1509        for n in [1, 100, 0].iter() {
1510            parse_test(*n, true, 0)?;
1511        }
1512
1513        Ok(())
1514    }
1515
1516    #[test]
1517    fn parse_keyring_interleaved_small_junk() -> Result<()> {
1518        for n in [1, 100, 0].iter() {
1519            parse_test(*n, false, 1)?;
1520        }
1521
1522        Ok(())
1523    }
1524
1525    #[test]
1526    fn parse_keyring_interleaved_unrecoverable_junk() -> Result<()> {
1527        // PacketParser is pretty good at recovering from junk in the
1528        // middle: it will search the next RECOVERY_THRESHOLD bytes
1529        // for a valid packet.  If it finds it, it will turn the junk
1530        // into a reserved packet and resume.  Insert a lot of NULs to
1531        // prevent the recovery mechanism from working.
1532        for n in [1, 100, 0].iter() {
1533            parse_test(*n, false, 2 * RECOVERY_THRESHOLD)?;
1534        }
1535
1536        Ok(())
1537    }
1538
1539    #[test]
1540    fn parse_keyring_interleaved_literal_and_small_junk() -> Result<()> {
1541        for n in [1, 100, 0].iter() {
1542            parse_test(*n, true, 1)?;
1543        }
1544
1545        Ok(())
1546    }
1547
1548    #[test]
1549    fn parse_keyring_interleaved_literal_and_unrecoverable_junk() -> Result<()> {
1550        for n in [1, 100, 0].iter() {
1551            parse_test(*n, true, 2 * RECOVERY_THRESHOLD)?;
1552        }
1553
1554        Ok(())
1555    }
1556
1557    #[test]
1558    fn parse_keyring_no_public_key() -> Result<()> {
1559        tracer!(TRACE, "parse_keyring_no_public_key", 0);
1560
1561        // The first few packets are not the valid start of a
1562        // certificate.  Each of those should return in an Error.
1563        // But, that shouldn't stop us from parsing the rest of the
1564        // keyring.
1565
1566        let (cert_1, _) =
1567            CertBuilder::general_purpose(
1568                Some("a@example.org"))
1569            .generate()?;
1570        let cert_1_packets: Vec<Packet>
1571            = cert_1.into_packets().collect();
1572
1573        let (cert_2, _) =
1574            CertBuilder::general_purpose(
1575                Some("b@example.org"))
1576            .generate()?;
1577
1578        for n in 1..cert_1_packets.len() {
1579            t!("n: {}", n);
1580
1581            let mut data = Vec::new();
1582
1583            for i in n..cert_1_packets.len() {
1584                cert_1_packets[i].serialize(&mut data)?;
1585            }
1586
1587            cert_2.as_tsk().serialize(&mut data)?;
1588
1589            compare_parse(&data);
1590        }
1591
1592        Ok(())
1593    }
1594
1595    #[test]
1596    fn accessors() {
1597        let testy = crate::tests::key("testy.pgp");
1598
1599        let certs = RawCertParser::from_bytes(testy)
1600            .expect("valid")
1601            .collect::<Result<Vec<RawCert>>>()
1602            .expect("valid");
1603        assert_eq!(certs.len(), 1);
1604        let cert = &certs[0];
1605        assert_eq!(cert.as_bytes(), testy);
1606
1607        assert_eq!(cert.primary_key().fingerprint(),
1608                   "3E8877C877274692975189F5D03F6F865226FE8B"
1609                       .parse().expect("valid"));
1610        assert_eq!(cert.keys().map(|k| k.fingerprint()).collect::<Vec<_>>(),
1611                   vec![
1612                       "3E8877C877274692975189F5D03F6F865226FE8B"
1613                           .parse().expect("valid"),
1614                       "01F187575BD45644046564C149E2118166C92632"
1615                           .parse().expect("valid")
1616                   ]);
1617        assert_eq!(cert.keys().subkeys()
1618                   .map(|k| k.fingerprint()).collect::<Vec<_>>(),
1619                   vec![
1620                       "01F187575BD45644046564C149E2118166C92632"
1621                           .parse().expect("valid")
1622                   ]);
1623        assert_eq!(
1624            cert.userids()
1625                .map(|u| {
1626                    String::from_utf8_lossy(u.value()).into_owned()
1627                })
1628                .collect::<Vec<_>>(),
1629            vec![ "Testy McTestface <testy@example.org>" ]);
1630    }
1631
1632    // Test the raw cert parser implementation.
1633    #[test]
1634    fn raw_cert_parser_impl() {
1635        // Read one certificate.
1636        let testy = crate::tests::key("testy.pgp");
1637
1638        let raw = RawCert::from_bytes(testy).expect("valid");
1639        let cert = Cert::from_bytes(testy).expect("valid");
1640
1641        assert_eq!(
1642            raw.keys().map(|k| k.fingerprint()).collect::<Vec<_>>(),
1643            cert.keys().map(|k| k.key().fingerprint()).collect::<Vec<_>>());
1644
1645        assert_eq!(
1646            raw.userids().collect::<Vec<_>>(),
1647            cert.userids().map(|ua| ua.userid().clone()).collect::<Vec<_>>());
1648
1649        // Parse zero certificates.
1650        eprintln!("Parsing 0 bytes");
1651        let raw = RawCert::from_bytes(b"");
1652        match &raw {
1653            Ok(_) => eprintln!("raw: Ok"),
1654            Err(err) => eprintln!("raw: {}", err),
1655        }
1656        let cert = Cert::from_bytes(b"");
1657        match &cert {
1658            Ok(_) => eprintln!("cert: Ok"),
1659            Err(err) => eprintln!("cert: {}", err),
1660        }
1661
1662        assert!(
1663            matches!(cert.map_err(|e| e.downcast::<crate::Error>()),
1664                     Err(Ok(crate::Error::MalformedCert(_)))));
1665        assert!(
1666            matches!(raw.map_err(|e| e.downcast::<crate::Error>()),
1667                     Err(Ok(crate::Error::MalformedCert(_)))));
1668
1669        // Parse two certificates.
1670        let mut bytes = Vec::new();
1671        bytes.extend(testy);
1672        bytes.extend(testy);
1673
1674        let parser = CertParser::from_bytes(&bytes).expect("valid");
1675        assert_eq!(parser.count(), 2);
1676
1677        eprintln!("Parsing two certificates");
1678        let raw = RawCert::from_bytes(&bytes);
1679        match &raw {
1680            Ok(_) => eprintln!("raw: Ok"),
1681            Err(err) => eprintln!("raw: {}", err),
1682        }
1683        let cert = Cert::from_bytes(&bytes);
1684        match &cert {
1685            Ok(_) => eprintln!("cert: Ok"),
1686            Err(err) => eprintln!("cert: {}", err),
1687        }
1688
1689        assert!(
1690            matches!(cert.map_err(|e| e.downcast::<crate::Error>()),
1691                     Err(Ok(crate::Error::MalformedCert(_)))));
1692        assert!(
1693            matches!(raw.map_err(|e| e.downcast::<crate::Error>()),
1694                     Err(Ok(crate::Error::MalformedCert(_)))));
1695    }
1696
1697    #[test]
1698    fn issue_1244() {
1699        // Regression test for malformed prefix-plus-junk input that used to
1700        // panic while iterating RawCertParser after successful initialization.
1701        let input = &[
1702            0xc6, 0x02, 0x2b, 0x6d, 0x71, 0x8d, 0xa7, 0x01,
1703            0xfd, 0xfc, 0x01, 0x5c, 0x89, 0x10, 0x0e, 0x53,
1704            0xb4, 0x7a, 0xdc, 0xa3, 0x5a, 0xa7, 0xbb, 0x3b,
1705            0xed, 0x89, 0x94, 0x24, 0x81, 0xcd, 0x73, 0xa8,
1706            0xab,
1707        ];
1708
1709        eprintln!("Testing malformed certificate");
1710        let mut parser = RawCertParser::from_bytes(input)
1711            .expect("parser initializes on this malformed input");
1712
1713        // We expect: an unsupported certificate error, junk, nothing.
1714        parser.next().expect("result").expect_err("Unsupported certificate");
1715        parser.next().expect("result").expect_err("Malformed packet");
1716        assert!(parser.next().is_none());
1717
1718        eprintln!("Testing malformed certificate followed by valid certificate");
1719        let testy = crate::tests::key("testy.pgp");
1720        let mut input = input.to_vec();
1721        input.extend(testy);
1722
1723        let mut parser = RawCertParser::from_bytes(&input)
1724            .expect("parser initializes on this malformed input");
1725
1726        // We expect: an unsupported certificate error, junk, a valid
1727        // certificate, nothing.
1728        parser.next().expect("result").expect_err("Unsupported certificate");
1729        parser.next().expect("result").expect_err("Malformed packet");
1730        parser.next().expect("result").expect("certificate");
1731        assert!(parser.next().is_none());
1732    }
1733
1734    #[test]
1735    fn concatenated_armored_certs() -> Result<()> {
1736        let mut keyring = Vec::new();
1737        keyring.extend_from_slice(b"some\ntext\n");
1738        keyring.extend_from_slice(crate::tests::key("testy.asc"));
1739        keyring.extend_from_slice(crate::tests::key("testy.asc"));
1740        keyring.extend_from_slice(b"some\ntext\n");
1741        keyring.extend_from_slice(crate::tests::key("testy.asc"));
1742        keyring.extend_from_slice(b"some\ntext\n");
1743        let certs = RawCertParser::from_bytes(&keyring)?.collect::<Vec<_>>();
1744        assert_eq!(certs.len(), 3);
1745        assert!(certs.iter().all(|c| c.is_ok()));
1746        Ok(())
1747    }
1748}