Skip to main content

sequoia_openpgp/
parse.rs

1//! Packet parsing infrastructure.
2//!
3//! OpenPGP defines a binary representation suitable for storing and
4//! communicating OpenPGP data structures (see [Section 3 ff. of RFC
5//! 9580]).  Parsing is the process of interpreting the binary
6//! representation.
7//!
8//!   [Section 3 ff. of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3
9//!
10//! An OpenPGP stream represents a sequence of packets.  Some of the
11//! packets contain other packets.  These so-called containers include
12//! encrypted data packets (the SED and [SEIP] packets), and
13//! [compressed data] packets.  This structure results in a tree,
14//! which is laid out in depth-first order.
15//!
16//!   [SEIP]: crate::packet::SEIP
17//!   [compressed data]: crate::packet::CompressedData
18//!
19//! OpenPGP defines objects consisting of several packets with a
20//! specific structure.  These objects are [`Message`]s, [`Cert`]s and
21//! sequences of [`Cert`]s ("keyrings").  Verifying the structure of
22//! these objects is also an act of parsing.
23//!
24//!   [`Message`]: super::Message
25//!   [`Cert`]: crate::cert::Cert
26//!
27//! This crate provides several interfaces to parse OpenPGP data.
28//! They fall in roughly three categories:
29//!
30//!  - First, most data structures in this crate implement the
31//!    [`Parse`] trait.  It provides a uniform interface to parse data
32//!    from an [`io::Read`]er, a file identified by its [`Path`], or
33//!    simply a byte slice.
34//!
35//!  - Second, there is a convenient interface to decrypt and/or
36//!    verify OpenPGP messages in a streaming fashion.  Encrypted
37//!    and/or signed data is read using the [`Parse`] interface, and
38//!    decrypted and/or verified data can be read using [`io::Read`].
39//!
40//!  - Finally, we expose the low-level [`PacketParser`], allowing
41//!    fine-grained control over the parsing.
42//!
43//!   [`io::Read`]: std::io::Read
44//!   [`Path`]: std::path::Path
45//!
46//! The choice of interface depends on the specific use case.  In many
47//! circumstances, OpenPGP data can not be trusted until it has been
48//! authenticated.  Therefore, it has to be treated as attacker
49//! controlled data, and it has to be treated with great care.  See
50//! the section [Security Considerations] below.
51//!
52//!   [Security Considerations]: #security-considerations
53//!
54//! # Common Operations
55//!
56//!  - *Decrypt a message*: Use a [streaming `Decryptor`].
57//!  - *Verify a message*: Use a [streaming `Verifier`].
58//!  - *Verify a detached signature*: Use a [`DetachedVerifier`].
59//!  - *Parse a [`Cert`]*: Use [`Cert`]'s [`Parse`] interface.
60//!  - *Parse a keyring*: Use [`CertParser`]'s [`Parse`] interface.
61//!  - *Parse an unstructured sequence of small packets from a trusted
62//!     source*: Use [`PacketPile`]s [`Parse`] interface (e.g.
63//!     [`PacketPile::from_file`]).
64//!  - *Parse an unstructured sequence of packets*: Use the
65//!    [`PacketPileParser`].
66//!  - *Parse an unstructured sequence of packets with full control
67//!    over the parser*: Use a [`PacketParser`].
68//!  - *Customize the parser behavior even more*: Use a
69//!    [`PacketParserBuilder`].
70//!
71//!   [`CertParser`]: crate::cert::CertParser
72//!   [streaming `Decryptor`]: stream::Decryptor
73//!   [streaming `Verifier`]: stream::Verifier
74//!   [`DetachedVerifier`]: stream::DetachedVerifier
75//!   [`PacketPile`]: crate::PacketPile
76//!   [`PacketPile::from_file`]: super::PacketPile::from_file()
77//!
78//! # Data Structures and Interfaces
79//!
80//! This crate provides several interfaces for parsing OpenPGP
81//! streams, ordered from the most convenient but least flexible to
82//! the least convenient but most flexible:
83//!
84//!   - The streaming [`Verifier`], [`DetachedVerifier`], and
85//!     [`Decryptor`] are the most convenient way to parse OpenPGP
86//!     messages.
87//!
88//!   - The [`PacketPile::from_file`] (and related methods) is the
89//!     most convenient, but least flexible way to parse an arbitrary
90//!     sequence of OpenPGP packets.  Whereas a [`PacketPileParser`]
91//!     allows the caller to determine how to handle individual
92//!     packets, the [`PacketPile::from_file`] parses the whole stream
93//!     at once and returns a [`PacketPile`].
94//!
95//!   - The [`PacketPileParser`] abstraction builds on the
96//!     [`PacketParser`] abstraction and provides a similar interface.
97//!     However, after each iteration, the [`PacketPileParser`] adds the
98//!     packet to a [`PacketPile`], which is returned once the packets are
99//!     completely processed.
100//!
101//!     This interface should only be used if the caller actually
102//!     wants a [`PacketPile`]; if the OpenPGP stream is parsed in place,
103//!     then using a [`PacketParser`] is better.
104//!
105//!     This interface should only be used if the caller is certain
106//!     that the parsed stream will fit in memory.
107//!
108//!   - The [`PacketParser`] abstraction produces one packet at a
109//!     time.  What is done with those packets is completely up to the
110//!     caller.
111//!
112//! The behavior of the [`PacketParser`] can be configured using a
113//! [`PacketParserBuilder`].
114//!
115//!   [`Decryptor`]: stream::Decryptor
116//!   [`Verifier`]: stream::Verifier
117//!
118//! # ASCII armored data
119//!
120//! The [`PacketParser`] will by default automatically detect and
121//! remove any ASCII armor encoding (see [Section 6 of RFC 9580]).
122//! This automatism can be disabled and fine-tuned using
123//! [`PacketParserBuilder::dearmor`].
124//!
125//!   [Section 6 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-6
126//!   [`PacketParserBuilder::dearmor`]: PacketParserBuilder::dearmor()
127//!
128//! # Security Considerations
129//!
130//! In general, OpenPGP data must be considered attacker controlled
131//! and thus treated with great care.  Even though we use a
132//! memory-safe language, there are several aspects to be aware of:
133//!
134//!  - OpenPGP messages may be compressed.  Therefore, one cannot
135//!    predict the uncompressed size of a message by looking at the
136//!    compressed representation.  Operations that parse OpenPGP
137//!    streams and buffer the packet data (like using the
138//!    [`PacketPile`]'s [`Parse`] interface) are inherently unsafe and
139//!    must only be used on trusted data.
140//!
141//!  - The authenticity of an OpenPGP message can only be checked once
142//!    it has been fully processed.  Therefore, the plaintext must be
143//!    buffered and not be trusted until the whole message is
144//!    processed and signatures and/or ciphertext integrity are
145//!    verified.  On the other hand, buffering an unbounded amount of
146//!    data is problematic and can lead to out-of-memory situations
147//!    resulting in denial of service.  The streaming message
148//!    processing interfaces address this problem by buffering a
149//!    configurable amount of data before releasing any data to the
150//!    caller, and only revert to streaming unverified data if the
151//!    message exceeds the buffer.  See [`DEFAULT_BUFFER_SIZE`] for
152//!    more information.
153//!
154//!  - Not all parts of signed-then-encrypted OpenPGP messages are
155//!    authenticated.  Notably, all packets outside the encryption
156//!    container (any [`PKESK`] and [`SKESK`] packets, as well as the
157//!    encryption container itself), the [`Literal`] packet's headers,
158//!    as well as parts of the [`Signature`] are not covered by the
159//!    signatures.
160//!
161//!  - Ciphertext integrity is provided by the [version 2 SEIP]
162//!    packet's use of authenticated encryption.
163//!
164//!  - In messages compatible with [RFC 4880], ciphertext integrity is
165//!    provided by the [`version 1 SEIP`] packet's [`MDC`] mechanism,
166//!    but the integrity can only be checked after decrypting the whole
167//!    container.
168//!
169//!   [`DEFAULT_BUFFER_SIZE`]: stream::DEFAULT_BUFFER_SIZE
170//!   [`PKESK`]: crate::packet::PKESK
171//!   [`SKESK`]: crate::packet::PKESK
172//!   [`Literal`]: crate::packet::Literal
173//!   [`Signature`]: crate::packet::Signature
174//!   [`version 2 SEIP`]: crate::packet::seip::SEIP2
175//!   [RFC 4880]: https://datatracker.ietf.org/doc/html/rfc4880
176//!   [`version 1 SEIP`]: crate::packet::seip::SEIP1
177//!   [`SEIP`]: crate::packet::SEIP
178//!   [`MDC`]: crate::packet::MDC
179
180use std::io;
181use std::io::prelude::*;
182use std::convert::TryFrom;
183use std::cmp;
184use std::str;
185use std::mem;
186use std::fmt;
187use std::path::Path;
188use std::result::Result as StdResult;
189
190use xxhash_rust::xxh3::Xxh3;
191
192// Re-export buffered_reader.
193//
194// We use this in our API, and re-exporting it here makes it easy to
195// use the correct version of the crate in downstream code without
196// having to explicitly depend on it.
197pub use buffered_reader;
198use ::buffered_reader::*;
199
200use crate::{
201    cert::CertValidator,
202    cert::CertValidity,
203    cert::KeyringValidator,
204    cert::KeyringValidity,
205    crypto::{aead, hash::Hash},
206    Result,
207    packet::header::{
208        CTB,
209        BodyLength,
210        PacketLengthType,
211    },
212    crypto::S2K,
213    Error,
214    packet::{
215        Container,
216        Header,
217    },
218    packet::signature::Signature3,
219    packet::signature::Signature4,
220    packet::signature::Signature6,
221    packet::prelude::*,
222    Packet,
223    Fingerprint,
224    KeyID,
225    crypto::SessionKey,
226};
227use crate::types::{
228    AEADAlgorithm,
229    CompressionAlgorithm,
230    Features,
231    HashAlgorithm,
232    KeyFlags,
233    KeyServerPreferences,
234    PublicKeyAlgorithm,
235    RevocationKey,
236    SignatureType,
237    SymmetricAlgorithm,
238    Timestamp,
239};
240use crate::crypto::{self, mpi::{PublicKey, MPI, ProtectedMPI}};
241use crate::crypto::symmetric::{Decryptor, InternalDecryptor};
242use crate::message;
243use crate::message::MessageValidator;
244
245mod partial_body;
246use self::partial_body::BufferedReaderPartialBodyFilter;
247
248use crate::packet::signature::subpacket::{
249    NotationData,
250    NotationDataFlags,
251    Subpacket,
252    SubpacketArea,
253    SubpacketLength,
254    SubpacketTag,
255    SubpacketValue,
256};
257
258use crate::serialize::MarshalInto;
259
260mod packet_pile_parser;
261pub use self::packet_pile_parser::PacketPileParser;
262
263mod hashed_reader;
264pub(crate) use self::hashed_reader::{
265    HashingMode,
266    HashedReader,
267};
268
269mod packet_parser_builder;
270pub use self::packet_parser_builder::{Dearmor, PacketParserBuilder};
271use packet_parser_builder::ARMOR_READER_LEVEL;
272
273pub mod map;
274mod mpis;
275pub mod stream;
276
277// Whether to trace execution by default (on stderr).
278const TRACE : bool = false;
279
280// How much junk the packet parser is willing to skip when recovering.
281// This is an internal implementation detail and hence not exported.
282pub(crate) const RECOVERY_THRESHOLD: usize = 32 * 1024;
283
284/// Parsing of packets and related structures.
285///
286/// This is a uniform interface to parse packets, messages, keys, and
287/// related data structures.
288///
289/// # Sealed trait
290///
291/// This trait is [sealed] and cannot be implemented for types outside this crate.
292/// Therefore it can be extended in a non-breaking way.
293/// If you want to implement the trait inside the crate
294/// you also need to implement the `seal::Sealed` marker trait.
295///
296/// [sealed]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed
297pub trait Parse<'a, T>: crate::seal::Sealed {
298    /// Reads from the given buffered reader.
299    ///
300    /// Implementations of this function should be short.  Ideally,
301    /// they should hand of the reader to a private function erasing
302    /// the readers type by invoking [`BufferedReader::into_boxed`].
303    fn from_buffered_reader<R>(reader: R) -> Result<T>
304    where
305        R: BufferedReader<Cookie> + 'a;
306
307    /// Reads from the given reader.
308    ///
309    /// The default implementation just uses
310    /// [`Parse::from_buffered_reader`], but implementations can
311    /// provide their own specialized version.
312    fn from_reader<R: 'a + Read + Send + Sync>(reader: R) -> Result<T> {
313        Self::from_buffered_reader(
314            buffered_reader::Generic::with_cookie(reader,
315                                                  None,
316                                                  Default::default())
317                .into_boxed())
318    }
319
320    /// Reads from the given file.
321    ///
322    /// The default implementation just uses
323    /// [`Parse::from_buffered_reader`], but implementations can
324    /// provide their own specialized version.
325    fn from_file<P: AsRef<Path>>(path: P) -> Result<T>
326    {
327        Self::from_buffered_reader(
328            buffered_reader::File::with_cookie(path.as_ref(),
329                                               Default::default())?
330                .into_boxed())
331    }
332
333    /// Reads from the given slice.
334    ///
335    /// The default implementation just uses
336    /// [`Parse::from_buffered_reader`], but implementations can
337    /// provide their own specialized version.
338    fn from_bytes<D: AsRef<[u8]> + ?Sized + Send + Sync>(data: &'a D) -> Result<T> {
339        Self::from_buffered_reader(
340            buffered_reader::Memory::with_cookie(data.as_ref(), Default::default())
341                .into_boxed())
342    }
343}
344
345// Implement type::from_buffered_reader and the Parse trait in terms
346// of type::from_buffered_reader for a particular packet type.  If the
347// generic from_buffered_reader implementation is inappropriate, then
348// it can be overridden.
349macro_rules! impl_parse_with_buffered_reader {
350    ($typ: ident) => {
351        impl_parse_with_buffered_reader!($typ, $typ);
352    };
353
354    ($typ_in: ident, $typ_out: ident) => {
355        impl_parse_with_buffered_reader!(
356            $typ_in,
357            $typ_out,
358            |br: Box<dyn BufferedReader<Cookie>>| -> Result<$typ_out> {
359                let parser = PacketHeaderParser::new_naked(br);
360
361                let mut pp = Self::parse(parser)?;
362                pp.buffer_unread_content()?;
363
364                match pp.next()? {
365                    #[allow(deprecated)]
366                    (Packet::$typ_out(o), PacketParserResult::EOF(_))
367                        => Ok(o),
368                    (Packet::Unknown(u), PacketParserResult::EOF(_)) =>
369                        Err(u.into_error()),
370                    (p, PacketParserResult::EOF(_)) =>
371                        Err(Error::InvalidOperation(
372                            format!("Not a {} packet: {:?}", stringify!($typ_out),
373                                    p)).into()),
374                    (_, PacketParserResult::Some(_)) =>
375                        Err(Error::InvalidOperation(
376                            "Excess data after packet".into()).into()),
377                }
378            });
379    };
380
381    ($typ: ident, $from_buffered_reader: expr) => {
382        impl_parse_with_buffered_reader!($typ, $typ, $from_buffered_reader);
383    };
384
385    // from_buffered_reader should be a closure that takes a
386    // BufferedReader and returns a Result<Self>.
387    ($typ_in: ident, $typ_out: ident, $from_buffered_reader: expr) => {
388        impl<'a> Parse<'a, $typ_out> for $typ_in {
389            fn from_buffered_reader<R>(reader: R) -> Result<$typ_out>
390            where
391                R: BufferedReader<Cookie> + 'a,
392            {
393                Ok($from_buffered_reader(reader.into_boxed())?)
394            }
395        }
396    }
397}
398
399/// The default amount of acceptable nesting.
400///
401/// The default is `16`.
402///
403/// Typically, we expect a message to look like:
404///
405/// ```text
406/// [ encryption container: [ compression container: [ signature: [ literal data ]]]]
407/// ```
408///
409/// So, this should be more than enough.
410///
411/// To change the maximum recursion depth, use
412/// [`PacketParserBuilder::max_recursion_depth`].
413///
414///   [`PacketParserBuilder::max_recursion_depth`]: PacketParserBuilder::max_recursion_depth()
415pub const DEFAULT_MAX_RECURSION_DEPTH : u8 = 16;
416
417/// The default maximum size of non-container packets.
418///
419/// The default is `1 MiB`.
420///
421/// Packets that exceed this limit will be returned as
422/// `Packet::Unknown`, with the error set to `Error::PacketTooLarge`.
423///
424/// This limit applies to any packet type that is *not* a container
425/// packet, i.e. any packet that is not a literal data packet, a
426/// compressed data packet, a symmetrically encrypted data packet, or
427/// an AEAD encrypted data packet.
428///
429/// To change the maximum recursion depth, use
430/// [`PacketParserBuilder::max_packet_size`].
431///
432///   [`PacketParserBuilder::max_packet_size`]: PacketParserBuilder::max_packet_size()
433pub const DEFAULT_MAX_PACKET_SIZE: u32 = 1 << 20; // 1 MiB
434
435// Used to parse an OpenPGP packet's header (note: in this case, the
436// header means a Packet's fixed data, not the OpenPGP framing
437// information, such as the CTB, and length information).
438//
439// This struct is not exposed to the user.  Instead, when a header has
440// been successfully parsed, a `PacketParser` is returned.
441pub(crate) struct PacketHeaderParser<'a> {
442    // The reader stack wrapped in a buffered_reader::Dup so that if
443    // there is a parse error, we can abort and still return an
444    // Unknown packet.
445    reader: buffered_reader::Dup<Box<dyn BufferedReader<Cookie> + 'a>, Cookie>,
446
447    // The current packet's header.
448    header: Header,
449    header_bytes: Vec<u8>,
450
451    // This packet's path.
452    path: Vec<usize>,
453
454    // The `PacketParser`'s state.
455    state: PacketParserState,
456
457    /// A map of this packet.
458    map: Option<map::Map>,
459}
460
461/// Creates a local marco called php_try! that returns an Unknown
462/// packet instead of an Error like try! on parsing-related errors.
463/// (Errors like read errors are still returned as usual.)
464///
465/// If you want to fail like this in a non-try! context, use
466/// php.fail("reason").
467macro_rules! make_php_try {
468    ($parser:expr) => {
469        macro_rules! php_try {
470            ($e:expr) => {
471                match $e {
472                    Ok(b) => {
473                        Ok(b)
474                    },
475                    Err(e) => {
476                        t!("parsing failed at {}:{}: {}", file!(), line!(), e);
477                        let e = match e.downcast::<io::Error>() {
478                            Ok(e) =>
479                                if let io::ErrorKind::UnexpectedEof = e.kind() {
480                                    return $parser.error(e.into());
481                                } else {
482                                    e.into()
483                                },
484                            Err(e) => e,
485                        };
486                        let e = match e.downcast::<Error>() {
487                            Ok(e) => return $parser.error(e.into()),
488                            Err(e) => e,
489                        };
490
491                        Err(e)
492                    },
493                }?
494            };
495        }
496    };
497}
498
499impl std::fmt::Debug for PacketHeaderParser<'_> {
500    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
501        f.debug_struct("PacketHeaderParser")
502            .field("header", &self.header)
503            .field("path", &self.path)
504            .field("reader", &self.reader)
505            .field("state", &self.state)
506            .field("map", &self.map)
507            .finish()
508    }
509}
510
511impl<'a> PacketHeaderParser<'a> {
512    // Returns a `PacketHeaderParser` to parse an OpenPGP packet.
513    // `inner` points to the start of the OpenPGP framing information,
514    // i.e., the CTB.
515    fn new(inner: Box<dyn BufferedReader<Cookie> + 'a>,
516           state: PacketParserState,
517           path: Vec<usize>, header: Header,
518           header_bytes: Vec<u8>) -> Self
519    {
520        assert!(!path.is_empty());
521
522        let cookie = Cookie {
523            level: inner.cookie_ref().level,
524            ..Default::default()
525        };
526        let map = if state.settings.map {
527            Some(map::Map::new(header_bytes.clone()))
528        } else {
529            None
530        };
531        PacketHeaderParser {
532            reader: buffered_reader::Dup::with_cookie(inner, cookie),
533            header,
534            header_bytes,
535            path,
536            state,
537            map,
538        }
539    }
540
541    // Returns a `PacketHeaderParser` that parses a bare packet.  That
542    // is, `inner` points to the start of the packet; the OpenPGP
543    // framing has already been processed, and `inner` already
544    // includes any required filters (e.g., a
545    // `BufferedReaderPartialBodyFilter`, etc.).
546    fn new_naked(inner: Box<dyn BufferedReader<Cookie> + 'a>) -> Self {
547        PacketHeaderParser::new(inner,
548                                PacketParserState::new(Default::default()),
549                                vec![ 0 ],
550                                Header::new(CTB::new(Tag::Reserved),
551                                            BodyLength::Full(0)),
552                                Vec::new())
553    }
554
555    // Consumes the bytes belonging to the packet's header (i.e., the
556    // number of bytes read) from the reader, and returns a
557    // `PacketParser` that can be returned to the user.
558    //
559    // Only call this function if the packet's header has been
560    // completely and correctly parsed.  If a failure occurs while
561    // parsing the header, use `fail()` instead.
562    fn ok(mut self, packet: Packet) -> Result<PacketParser<'a>> {
563        tracer!(TRACE, "PacketHeaderParser::ok",
564                self.reader.cookie_ref().level.unwrap_or(0));
565        let total_out = self.reader.total_out();
566        t!("total_out = {}", total_out);
567
568        if self.state.settings.map {
569            // Steal the body for the map.
570            self.reader.rewind();
571            let body = if self.state.settings.buffer_unread_content {
572                self.reader.steal_eof()?
573            } else {
574                self.reader.steal(total_out)?
575            };
576            t!("got {} bytes of body for the map", body.len());
577            if body.len() > total_out {
578                self.field("body", body.len() - total_out);
579            }
580            self.map.as_mut().unwrap().finalize(body);
581        }
582
583        // This is a buffered_reader::Dup, so this always has an
584        // inner.
585        let mut reader = Box::new(self.reader).into_inner().unwrap();
586
587        if total_out > 0 {
588            // We know the data has been read, so this cannot fail.
589            reader.data_consume_hard(total_out).unwrap();
590        }
591
592        Ok(PacketParser {
593            header: self.header,
594            packet,
595            path: self.path,
596            last_path: vec![],
597            reader,
598            content_was_read: false,
599            processed: true,
600            finished: false,
601            map: self.map,
602            body_hash: Some(Container::make_body_hash()),
603            state: self.state,
604        })
605    }
606
607    // Something went wrong while parsing the packet's header.  Aborts
608    // and returns an Unknown packet instead.
609    fn fail(self, reason: &'static str) -> Result<PacketParser<'a>> {
610        self.error(Error::MalformedPacket(reason.into()).into())
611    }
612
613    fn error(mut self, error: anyhow::Error) -> Result<PacketParser<'a>> {
614        // Rewind the dup reader, so that the caller has a chance to
615        // buffer the whole body of the unknown packet.
616        self.reader.rewind();
617        Unknown::parse(self, error)
618    }
619
620    fn field(&mut self, name: &'static str, size: usize) {
621        if let Some(ref mut map) = self.map {
622            map.add(name, size)
623        }
624    }
625
626    fn parse_u8(&mut self, name: &'static str) -> Result<u8> {
627        let r = self.reader.data_consume_hard(1)?[0];
628        self.field(name, 1);
629        Ok(r)
630    }
631
632    fn parse_u8_len(&mut self, name: &'static str) -> Result<usize> {
633        self.parse_u8(name).map(Into::into)
634    }
635
636    fn parse_be_u16(&mut self, name: &'static str) -> Result<u16> {
637        let r = self.reader.read_be_u16()?;
638        self.field(name, 2);
639        Ok(r)
640    }
641
642    fn parse_be_u32(&mut self, name: &'static str) -> Result<u32> {
643        let r = self.reader.read_be_u32()?;
644        self.field(name, 4);
645        Ok(r)
646    }
647
648    fn parse_bool(&mut self, name: &'static str) -> Result<bool> {
649        let v = self.reader.data_consume_hard(1)?[0];
650        self.field(name, 1);
651        match v {
652            0 => Ok(false),
653            1 => Ok(true),
654            n => Err(Error::MalformedPacket(
655                format!("Invalid value for bool: {}", n)).into()),
656        }
657    }
658
659    fn parse_bytes(&mut self, name: &'static str, amount: usize)
660                   -> Result<Vec<u8>> {
661        let r = self.reader.steal(amount)?;
662        self.field(name, amount);
663        Ok(r)
664    }
665
666    fn parse_bytes_into(&mut self, name: &'static str, buf: &mut [u8])
667                   -> Result<()> {
668        self.reader.read_exact(buf)?;
669        self.field(name, buf.len());
670        Ok(())
671    }
672
673    fn parse_bytes_eof(&mut self, name: &'static str) -> Result<Vec<u8>> {
674        let r = self.reader.steal_eof()?;
675        self.field(name, r.len());
676        Ok(r)
677    }
678
679    fn recursion_depth(&self) -> isize {
680        self.path.len() as isize - 1
681    }
682
683    /// Marks the start of a variable-sized field `name` of length
684    /// `len`.
685    ///
686    /// After parsing the variable-sized field, hand the returned
687    /// object to [`PacketHeaderParser::variable_sized_field_end`].
688    fn variable_sized_field_start<L>(&self, name: &'static str, len: L)
689                                     -> VariableSizedField
690    where
691        L: Into<u32>,
692    {
693        VariableSizedField {
694            name,
695            start: self.reader.total_out().try_into()
696                .expect("offsets in packet headers cannot exceed u32"),
697            length: len.into(),
698        }
699    }
700
701    /// Returns the remaining bytes in a variable-sized field.
702    fn variable_sized_field_remaining(&self, f: &VariableSizedField) -> usize {
703        let current: u32 = self.reader.total_out().try_into()
704            .expect("offsets in packet headers cannot exceed u32");
705        f.length.saturating_sub(current - f.start) as usize
706    }
707
708    /// Marks the start of a variable-sized field and checks whether
709    /// the correct amount of data has been consumed.
710    fn variable_sized_field_end(&self, f: VariableSizedField) -> Result<()>
711    {
712        let l = u32::try_from(self.reader.total_out())
713            .expect("offsets in packet headers cannot exceed u32")
714            - f.start;
715
716        use std::cmp::Ordering;
717        match l.cmp(&f.length) {
718            Ordering::Less => Err(Error::MalformedPacket(format!(
719                "{}: length {} but only consumed {} bytes",
720                f.name, f.length, l)).into()),
721            Ordering::Equal => Ok(()),
722            Ordering::Greater => Err(Error::MalformedPacket(format!(
723                "{}: length {} but consumed {} bytes",
724                f.name, f.length, l)).into()),
725        }
726    }
727}
728
729/// Represents a variable-sized field in a packet header.
730#[must_use]
731struct VariableSizedField {
732    /// Name of the field.
733    name: &'static str,
734
735    /// The amount of bytes consumed in self.reader at the start of
736    /// the field.
737    start: u32,
738
739    /// The expected length of the variable-sized field.
740    length: u32,
741}
742
743/// What the hash in the Cookie is for.
744#[derive(Copy, Clone, PartialEq, Debug)]
745pub(crate) enum HashesFor {
746    Nothing,
747    MDC,
748    Signature,
749    CleartextSignature,
750}
751
752/// Controls whether a hashed reader hashes data.
753#[derive(Copy, Clone, PartialEq, Debug)]
754enum Hashing {
755    /// Hashing is enabled.
756    Enabled,
757    /// Hashing is enabled for notarized signatures.
758    Notarized,
759    /// Hashing is disabled.
760    Disabled,
761}
762
763/// Private state used by the `PacketParser`.
764///
765/// This is not intended to be used.  It is possible to explicitly
766/// create `Cookie` instances using its `Default` implementation for
767/// low-level interfacing with parsing code.
768#[derive(Debug)]
769pub struct Cookie {
770    // `BufferedReader`s managed by a `PacketParser` have
771    // `Some(level)`; an external `BufferedReader` (i.e., the
772    // underlying `BufferedReader`) has no level.
773    //
774    // Before parsing a top-level packet, we may push a
775    // `buffered_reader::Limitor` in front of the external
776    // `BufferedReader`.  Such `BufferedReader`s are assigned a level
777    // of 0.
778    //
779    // When a top-level packet (i.e., a packet with a recursion depth
780    // of 0) reads from the `BufferedReader` stack, the top
781    // `BufferedReader` will have a level of at most 0.
782    //
783    // If the top-level packet is a container, say, a `CompressedData`
784    // packet, then it pushes a decompression filter with a level of 0
785    // onto the `BufferedReader` stack, and it recursively invokes the
786    // parser.
787    //
788    // When the parser encounters the `CompressedData`'s first child,
789    // say, a `Literal` packet, it pushes a `buffered_reader::Limitor` on
790    // the `BufferedReader` stack with a level of 1.  Then, a
791    // `PacketParser` for the `Literal` data packet is created with a
792    // recursion depth of 1.
793    //
794    // There are several things to note:
795    //
796    //   - When a `PacketParser` with a recursion depth of N reads
797    //     from the `BufferedReader` stack, the top `BufferedReader`'s
798    //     level is (at most) N.
799    //
800    //     - Because we sometimes don't need to push a limitor
801    //       (specifically, when the length is indeterminate), the
802    //       `BufferedReader` at the top of the stack may have a level
803    //       less than the current `PacketParser`'s recursion depth.
804    //
805    //   - When a packet at depth N is a container that filters the
806    //     data, it pushes a `BufferedReader` at level N onto the
807    //     `BufferedReader` stack.
808    //
809    //   - When we finish parsing a packet at depth N, we pop all
810    //     `BufferedReader`s from the `BufferedReader` stack that are
811    //     at level N.  The intuition is: the `BufferedReaders` at
812    //     level N are associated with the packet at depth N.
813    //
814    //   - If a OnePassSig packet occurs at the top level, then we
815    //     need to push a HashedReader above the current level.  The
816    //     top level is level 0, thus we push the HashedReader at
817    //     level -1.
818    level: Option<isize>,
819
820    hashes_for: HashesFor,
821    hashing: Hashing,
822
823    /// Keeps track of whether the last one pass signature packet had
824    /// the last flag set.
825    saw_last: bool,
826    sig_groups: Vec<SignatureGroup>,
827    /// Keep track of the maximal size of sig_groups to compute
828    /// signature levels.
829    sig_groups_max_len: usize,
830
831    /// Stashed bytes that need to be hashed.
832    ///
833    /// When checking nested signatures, we need to hash the framing.
834    /// However, at the time we know that we want to hash it, it has
835    /// already been consumed.  Deferring the consumption of headers
836    /// failed due to complications with the partial body decoder
837    /// eagerly consuming data.  I (Justus) decided that doing the
838    /// right thing is not worth the trouble, at least for now.  Also,
839    /// hash stash sounds funny.
840    hash_stash: Option<Vec<u8>>,
841
842    /// Whether this `BufferedReader` is actually an interior EOF in a
843    /// container.
844    ///
845    /// This is used by the SEIP parser to prevent a child packet from
846    /// accidentally swallowing the trailing MDC packet.  This can
847    /// happen when there is a compressed data packet with an
848    /// indeterminate body length encoding.  In this case, due to
849    /// buffering, the decompressor consumes data beyond the end of
850    /// the compressed data.
851    ///
852    /// When set, buffered_reader_stack_pop will return early when it
853    /// encounters a fake EOF at the level it is popping to.
854    fake_eof: bool,
855
856    /// Indicates that this is the top-level armor reader that is
857    /// doing a transformation of a message using the cleartext
858    /// signature framework into a signed message.
859    csf_transformation: bool,
860}
861assert_send_and_sync!(Cookie);
862
863/// Contains hashes for consecutive one pass signature packets ending
864/// in one with the last flag set.
865#[derive(Default)]
866pub(crate) struct SignatureGroup {
867    /// Counts the number of one pass signature packets this group is
868    /// for.  Once this drops to zero, we pop the group from the
869    /// stack.
870    ops_count: usize,
871
872    /// The hash contexts.
873    ///
874    /// We store a salt and the hash context as tuples.
875    ///
876    /// In v6, the hash is salted.  We store the salt here so that we
877    /// can find the right hash context again when we encounter the
878    /// signature packet.
879    ///
880    /// In v4, the hash is not salted.  Hence, salt is the zero-length
881    /// vector.  The fact that the hash is not salted allows for an
882    /// optimization: to verify two signatures using the same hash
883    /// algorithm, the hash must be computed just once.  We implement
884    /// this optimization for v4 signatures.
885    pub(crate) hashes: Vec<HashingMode<crypto::hash::Context>>,
886}
887
888impl fmt::Debug for SignatureGroup {
889    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
890        let algos = self.hashes.iter()
891            .map(|mode| mode.map(|ctx| ctx.algo()))
892            .collect::<Vec<_>>();
893
894        f.debug_struct("Cookie")
895            .field("ops_count", &self.ops_count)
896            .field("hashes", &algos)
897            .finish()
898    }
899}
900
901impl SignatureGroup {
902    /// Clears the signature group.
903    fn clear(&mut self) {
904        self.ops_count = 0;
905        self.hashes.clear();
906    }
907}
908
909impl Default for Cookie {
910    fn default() -> Self {
911        Cookie {
912            level: None,
913            hashing: Hashing::Enabled,
914            hashes_for: HashesFor::Nothing,
915            saw_last: false,
916            sig_groups: vec![Default::default()],
917            sig_groups_max_len: 1,
918            hash_stash: None,
919            fake_eof: false,
920            csf_transformation: false,
921        }
922    }
923}
924
925impl Cookie {
926    fn new(level: isize) -> Cookie {
927        Cookie {
928            level: Some(level),
929            hashing: Hashing::Enabled,
930            hashes_for: HashesFor::Nothing,
931            saw_last: false,
932            sig_groups: vec![Default::default()],
933            sig_groups_max_len: 1,
934            hash_stash: None,
935            fake_eof: false,
936            csf_transformation: false,
937        }
938    }
939
940    /// Returns a reference to the topmost signature group.
941    pub(crate) fn sig_group(&self) -> &SignatureGroup {
942        assert!(!self.sig_groups.is_empty());
943        &self.sig_groups[self.sig_groups.len() - 1]
944    }
945
946    /// Returns a mutable reference to the topmost signature group.
947    pub(crate) fn sig_group_mut(&mut self) -> &mut SignatureGroup {
948        assert!(!self.sig_groups.is_empty());
949        let len = self.sig_groups.len();
950        &mut self.sig_groups[len - 1]
951    }
952
953    /// Returns the level of the currently parsed signature.
954    fn signature_level(&self) -> usize {
955        // The signature with the deepest "nesting" is closest to the
956        // data, and hence level 0.
957        self.sig_groups_max_len - self.sig_groups.len()
958    }
959
960    /// Tests whether the topmost signature group is no longer used.
961    fn sig_group_unused(&self) -> bool {
962        assert!(!self.sig_groups.is_empty());
963        self.sig_groups[self.sig_groups.len() - 1].ops_count == 0
964    }
965
966    /// Pushes a new signature group to the stack.
967    fn sig_group_push(&mut self) {
968        self.sig_groups.push(Default::default());
969        self.sig_groups_max_len += 1;
970    }
971
972    /// Pops a signature group from the stack.
973    fn sig_group_pop(&mut self) {
974        if self.sig_groups.len() == 1 {
975            // Don't pop the last one, just clear it.
976            self.sig_groups[0].clear();
977            self.hashes_for = HashesFor::Nothing;
978        } else {
979            self.sig_groups.pop();
980        }
981    }
982}
983
984impl Cookie {
985    // Enables or disables signature hashers (HashesFor::Signature) at
986    // level `level`.
987    //
988    // Thus to disable the hashing of a level 3 literal packet's
989    // meta-data, we disable hashing at level 2.
990    fn hashing(reader: &mut dyn BufferedReader<Cookie>,
991               how: Hashing, level: isize) {
992        let mut reader : Option<&mut dyn BufferedReader<Cookie>>
993            = Some(reader);
994        while let Some(r) = reader {
995            {
996                let cookie = r.cookie_mut();
997                if let Some(br_level) = cookie.level {
998                    if br_level < level {
999                        break;
1000                    }
1001                    if br_level == level
1002                        && (cookie.hashes_for == HashesFor::Signature
1003                            || cookie.hashes_for == HashesFor::CleartextSignature)
1004                    {
1005                        cookie.hashing = how;
1006                    }
1007                } else {
1008                    break;
1009                }
1010            }
1011            reader = r.get_mut();
1012        }
1013    }
1014
1015    /// Signals that we are processing a message using the Cleartext
1016    /// Signature Framework.
1017    ///
1018    /// This is used by the armor reader to signal that it has
1019    /// encountered such a message and is transforming it into an
1020    /// inline signed message.
1021    pub(crate) fn set_processing_csf_message(&mut self) {
1022        tracer!(TRACE, "set_processing_csf_message", self.level.unwrap_or(0));
1023        t!("Enabling CSF Transformation mode");
1024        self.csf_transformation = true;
1025    }
1026
1027    /// Checks if we are processing a signed message using the
1028    /// Cleartext Signature Framework.
1029    fn processing_csf_message(reader: &dyn BufferedReader<Cookie>)
1030                              -> bool {
1031        let mut reader: Option<&dyn BufferedReader<Cookie>>
1032            = Some(reader);
1033        while let Some(r) = reader {
1034            if r.cookie_ref().level == Some(ARMOR_READER_LEVEL) {
1035                return r.cookie_ref().csf_transformation;
1036            } else {
1037                reader = r.get_ref();
1038            }
1039        }
1040        false
1041    }
1042}
1043
1044// Pops readers from a buffered reader stack at the specified level.
1045fn buffered_reader_stack_pop<'a>(
1046    mut reader: Box<dyn BufferedReader<Cookie> + 'a>, depth: isize)
1047    -> Result<(bool, Box<dyn BufferedReader<Cookie> + 'a>)>
1048{
1049    tracer!(TRACE, "buffered_reader_stack_pop", depth);
1050    t!("(reader level: {:?}, pop through: {})",
1051       reader.cookie_ref().level, depth);
1052
1053    while let Some(level) = reader.cookie_ref().level {
1054        assert!(level <= depth // Peel off exactly one level.
1055                || depth < 0); // Except for the topmost filters.
1056
1057        if level >= depth {
1058            let fake_eof = reader.cookie_ref().fake_eof;
1059
1060            t!("top reader at level {:?} (fake eof: {}), pop through: {}",
1061               reader.cookie_ref().level, fake_eof, depth);
1062
1063            t!("popping level {:?} reader, reader: {:?}",
1064               reader.cookie_ref().level,
1065               reader);
1066
1067            if reader.eof() && ! reader.consummated() {
1068                return Err(Error::MalformedPacket("Truncated packet".into())
1069                           .into());
1070            }
1071            reader.drop_eof()?;
1072            reader = reader.into_inner().unwrap();
1073
1074            if level == depth && fake_eof {
1075                t!("Popped a fake EOF reader at level {}, stopping.", depth);
1076                return Ok((true, reader));
1077            }
1078
1079            t!("now at level {:?} reader: {:?}",
1080               reader.cookie_ref().level, reader);
1081        } else {
1082            break;
1083        }
1084    }
1085
1086    Ok((false, reader))
1087}
1088
1089
1090// A `PacketParser`'s settings.
1091#[derive(Clone, Debug)]
1092struct PacketParserSettings {
1093    // The maximum allowed recursion depth.
1094    //
1095    // There is absolutely no reason that this should be more than
1096    // 255.  (GnuPG defaults to 32.)  Moreover, if it is too large,
1097    // then a read from the reader pipeline could blow the stack.
1098    max_recursion_depth: u8,
1099
1100    // The maximum size of non-container packets.
1101    //
1102    // Packets that exceed this limit will be returned as
1103    // `Packet::Unknown`, with the error set to
1104    // `Error::PacketTooLarge`.
1105    //
1106    // This limit applies to any packet type that is *not* a
1107    // container packet, i.e. any packet that is not a literal data
1108    // packet, a compressed data packet, a symmetrically encrypted
1109    // data packet, or an AEAD encrypted data packet.
1110    max_packet_size: u32,
1111
1112    // Whether a packet's contents should be buffered or dropped when
1113    // the next packet is retrieved.
1114    buffer_unread_content: bool,
1115
1116    // Whether to create a map.
1117    map: bool,
1118
1119    // Whether to implicitly start hashing upon parsing OnePassSig
1120    // packets.
1121    automatic_hashing: bool,
1122}
1123
1124// The default `PacketParser` settings.
1125impl Default for PacketParserSettings {
1126    fn default() -> Self {
1127        PacketParserSettings {
1128            max_recursion_depth: DEFAULT_MAX_RECURSION_DEPTH,
1129            max_packet_size: DEFAULT_MAX_PACKET_SIZE,
1130            buffer_unread_content: false,
1131            map: false,
1132            automatic_hashing: true,
1133        }
1134    }
1135}
1136
1137impl S2K {
1138    /// Reads an S2K from `php`.
1139    fn parse_v4(php: &mut PacketHeaderParser<'_>)
1140                                           -> Result<Self> {
1141        Self::parse_common(php, None)
1142    }
1143
1144    /// Reads an S2K from `php` with explicit S2K length.
1145    fn parse_v6(php: &mut PacketHeaderParser, s2k_len: u8) -> Result<Self> {
1146        Self::parse_common(php, Some(s2k_len))
1147    }
1148
1149    /// Reads an S2K from `php` with optional explicit S2K length.
1150    fn parse_common(php: &mut PacketHeaderParser<'_>,
1151                                               s2k_len: Option<u8>)
1152                                               -> Result<Self>
1153    {
1154        if s2k_len == Some(0) {
1155            return Err(Error::MalformedPacket(
1156                "Invalid size for S2K object: 0 octets".into()).into());
1157        }
1158
1159        let check_size = |expected| {
1160            if let Some(got) = s2k_len {
1161                if got != expected {
1162                    return Err(Error::MalformedPacket(format!(
1163                        "Invalid size for S2K object: {} octets, expected {}",
1164                        got, expected)));
1165                }
1166            }
1167            Ok(())
1168        };
1169
1170        let s2k = php.parse_u8("s2k_type")?;
1171        #[allow(deprecated)]
1172        let ret = match s2k {
1173            0 => {
1174                check_size(2)?;
1175                S2K::Simple {
1176                    hash: HashAlgorithm::from(php.parse_u8("s2k_hash_algo")?),
1177                }
1178            },
1179            1 => {
1180                check_size(10)?;
1181                S2K::Salted {
1182                    hash: HashAlgorithm::from(php.parse_u8("s2k_hash_algo")?),
1183                    salt: Self::read_salt(php)?,
1184                }
1185            },
1186            3 => {
1187                check_size(11)?;
1188                S2K::Iterated {
1189                    hash: HashAlgorithm::from(php.parse_u8("s2k_hash_algo")?),
1190                    salt: Self::read_salt(php)?,
1191                    hash_bytes: S2K::decode_count(php.parse_u8("s2k_count")?),
1192                }
1193            },
1194            4 => S2K::Argon2 {
1195                salt: {
1196                    let mut b = [0u8; 16];
1197                    let b_len = b.len();
1198                    b.copy_from_slice(
1199                        &php.parse_bytes("argon2_salt", b_len)?);
1200                    b
1201                },
1202                t: php.parse_u8("argon2_t")?,
1203                p: php.parse_u8("argon2_p")?,
1204                m: php.parse_u8("argon2_m")?,
1205            },
1206            100..=110 => S2K::Private {
1207                tag: s2k,
1208                parameters: if let Some(l) = s2k_len {
1209                    Some(
1210                        php.parse_bytes("parameters", l as usize - 1 /* Tag */)?
1211                            .into())
1212                } else {
1213                    None
1214                },
1215            },
1216            u => S2K::Unknown {
1217                tag: u,
1218                parameters: if let Some(l) = s2k_len {
1219                    Some(
1220                        php.parse_bytes("parameters", l as usize - 1 /* Tag */)?
1221                            .into())
1222                } else {
1223                    None
1224                },
1225            },
1226        };
1227
1228        Ok(ret)
1229    }
1230
1231    fn read_salt(php: &mut PacketHeaderParser<'_>) -> Result<[u8; 8]> {
1232        let mut b = [0u8; 8];
1233        b.copy_from_slice(&php.parse_bytes("s2k_salt", 8)?);
1234
1235        Ok(b)
1236    }
1237}
1238
1239impl_parse_with_buffered_reader!(
1240    S2K,
1241    |bio: Box<dyn BufferedReader<Cookie>>| -> Result<Self> {
1242        let mut parser = PacketHeaderParser::new_naked(bio.into_boxed());
1243        Self::parse_v4(&mut parser)
1244    });
1245
1246impl Header {
1247    pub(crate) fn parse<R: BufferedReader<C>, C: fmt::Debug + Send + Sync> (bio: &mut R)
1248        -> Result<Header>
1249    {
1250        let ctb = CTB::try_from(bio.data_consume_hard(1)?[0])?;
1251        let length = match ctb {
1252            CTB::New(_) => BodyLength::parse_new_format(bio)?,
1253            CTB::Old(ref ctb) =>
1254                BodyLength::parse_old_format(bio, ctb.length_type())?,
1255        };
1256        Ok(Header::new(ctb, length))
1257    }
1258}
1259
1260impl_parse_with_buffered_reader!(
1261    Header,
1262    |mut reader| -> Result<Self> {
1263        Header::parse(&mut reader)
1264    });
1265
1266impl BodyLength {
1267    /// Decodes a new format body length as described in [Section
1268    /// 4.2.1 of RFC 9580].
1269    ///
1270    ///   [Section 4.2.1 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-4.2.1
1271    pub(crate) fn parse_new_format<T: BufferedReader<C>, C: fmt::Debug + Send + Sync> (bio: &mut T)
1272        -> io::Result<BodyLength>
1273    {
1274        let octet1 : u8 = bio.data_consume_hard(1)?[0];
1275        match octet1 {
1276            0..=191 => // One octet.
1277                Ok(BodyLength::Full(octet1 as u32)),
1278            192..=223 => { // Two octets length.
1279                let octet2 = bio.data_consume_hard(1)?[0];
1280                Ok(BodyLength::Full(((octet1 as u32 - 192) << 8)
1281                                    + octet2 as u32 + 192))
1282            },
1283            224..=254 => // Partial body length.
1284                Ok(BodyLength::Partial(1 << (octet1 & 0x1F))),
1285            255 => // Five octets.
1286                Ok(BodyLength::Full(bio.read_be_u32()?)),
1287        }
1288    }
1289
1290    /// Decodes an old format body length as described in [Section
1291    /// 4.2.2 of RFC 9580].
1292    ///
1293    ///   [Section 4.2.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-4.2.2
1294    pub(crate) fn parse_old_format<T: BufferedReader<C>, C: fmt::Debug + Send + Sync>
1295        (bio: &mut T, length_type: PacketLengthType)
1296         -> Result<BodyLength>
1297    {
1298        match length_type {
1299            PacketLengthType::OneOctet =>
1300                Ok(BodyLength::Full(bio.data_consume_hard(1)?[0] as u32)),
1301            PacketLengthType::TwoOctets =>
1302                Ok(BodyLength::Full(bio.read_be_u16()? as u32)),
1303            PacketLengthType::FourOctets =>
1304                Ok(BodyLength::Full(bio.read_be_u32()? as u32)),
1305            PacketLengthType::Indeterminate =>
1306                Ok(BodyLength::Indeterminate),
1307        }
1308    }
1309}
1310
1311#[test]
1312fn body_length_new_format() {
1313    fn test(input: &[u8], expected_result: BodyLength) {
1314        assert_eq!(
1315            BodyLength::parse_new_format(
1316                &mut buffered_reader::Memory::new(input)).unwrap(),
1317            expected_result);
1318    }
1319
1320    // Examples from Section 4.2.3 of RFC4880.
1321
1322    // Example #1.
1323    test(&[0x64][..], BodyLength::Full(100));
1324
1325    // Example #2.
1326    test(&[0xC5, 0xFB][..], BodyLength::Full(1723));
1327
1328    // Example #3.
1329    test(&[0xFF, 0x00, 0x01, 0x86, 0xA0][..], BodyLength::Full(100000));
1330
1331    // Example #4.
1332    test(&[0xEF][..], BodyLength::Partial(32768));
1333    test(&[0xE1][..], BodyLength::Partial(2));
1334    test(&[0xF0][..], BodyLength::Partial(65536));
1335    test(&[0xC5, 0xDD][..], BodyLength::Full(1693));
1336}
1337
1338#[test]
1339fn body_length_old_format() {
1340    fn test(input: &[u8], plt: PacketLengthType,
1341            expected_result: BodyLength, expected_rest: &[u8]) {
1342        let mut bio = buffered_reader::Memory::new(input);
1343        assert_eq!(BodyLength::parse_old_format(&mut bio, plt).unwrap(),
1344                   expected_result);
1345        let rest = bio.data_eof();
1346        assert_eq!(rest.unwrap(), expected_rest);
1347    }
1348
1349    test(&[1], PacketLengthType::OneOctet, BodyLength::Full(1), &b""[..]);
1350    test(&[1, 2], PacketLengthType::TwoOctets,
1351         BodyLength::Full((1 << 8) + 2), &b""[..]);
1352    test(&[1, 2, 3, 4], PacketLengthType::FourOctets,
1353         BodyLength::Full((1 << 24) + (2 << 16) + (3 << 8) + 4), &b""[..]);
1354    test(&[1, 2, 3, 4, 5, 6], PacketLengthType::FourOctets,
1355         BodyLength::Full((1 << 24) + (2 << 16) + (3 << 8) + 4), &[5, 6][..]);
1356    test(&[1, 2, 3, 4], PacketLengthType::Indeterminate,
1357         BodyLength::Indeterminate, &[1, 2, 3, 4][..]);
1358}
1359
1360impl Unknown {
1361    /// Parses the body of any packet and returns an Unknown.
1362    fn parse(php: PacketHeaderParser, error: anyhow::Error)
1363             -> Result<PacketParser>
1364    {
1365        let tag = php.header.ctb().tag();
1366        php.ok(Packet::Unknown(Unknown::new(tag, error)))
1367    }
1368}
1369
1370// Read the next packet as an unknown packet.
1371//
1372// The `reader` must point to the packet's header, i.e., the CTB.
1373// This buffers the packet's contents.
1374//
1375// Note: we only need this function for testing purposes in a
1376// different module.
1377#[cfg(test)]
1378pub(crate) fn to_unknown_packet<R: Read + Send + Sync>(reader: R) -> Result<Unknown>
1379{
1380    let mut reader = buffered_reader::Generic::with_cookie(
1381        reader, None, Cookie::default());
1382    let header = Header::parse(&mut reader)?;
1383
1384    let reader : Box<dyn BufferedReader<Cookie>>
1385        = match header.length() {
1386            &BodyLength::Full(len) =>
1387                Box::new(buffered_reader::Limitor::with_cookie(
1388                    reader, len as u64, Cookie::default())),
1389            &BodyLength::Partial(len) =>
1390                Box::new(BufferedReaderPartialBodyFilter::with_cookie(
1391                    reader, len, true, Cookie::default())),
1392            _ => Box::new(reader),
1393    };
1394
1395    let parser = PacketHeaderParser::new(
1396        reader, PacketParserState::new(Default::default()), vec![ 0 ], header, Vec::new());
1397    let mut pp =
1398        Unknown::parse(parser,
1399                       anyhow::anyhow!("explicit conversion to unknown"))?;
1400    pp.buffer_unread_content()?;
1401    pp.finish()?;
1402
1403    if let Packet::Unknown(packet) = pp.packet {
1404        Ok(packet)
1405    } else {
1406        panic!("Internal inconsistency.");
1407    }
1408}
1409
1410/// A parser for embedded signatures.
1411///
1412/// An embedded signature is parsed just like a normal signature, but
1413/// has the restriction that it cannot contain an embedded signature.
1414/// If it does, then it fails and returns `Error::MalformedPacket`.
1415///
1416/// This type is internal to this module.
1417struct EmbeddedSignature;
1418
1419impl crate::seal::Sealed for EmbeddedSignature {}
1420
1421impl EmbeddedSignature {
1422    // Parses a signature packet.
1423    fn parse(php: PacketHeaderParser)
1424        -> Result<PacketParser>
1425    {
1426        Signature::parse_internal(php, true)
1427    }
1428}
1429
1430impl_parse_with_buffered_reader!(EmbeddedSignature, Signature);
1431
1432impl Signature {
1433    // Parses a signature packet.
1434    fn parse(php: PacketHeaderParser)
1435        -> Result<PacketParser>
1436    {
1437        Signature::parse_internal(php, false)
1438    }
1439
1440    // Parses a signature packet.
1441    //
1442    // If `from_embedded_signature` is `true`, then any embedded
1443    // signature subpackets will make the signature invalid, as nested
1444    // embedded signatures are not allowed.
1445    fn parse_internal(mut php: PacketHeaderParser,
1446                      from_embedded_signature: bool)
1447        -> Result<PacketParser>
1448    {
1449        let indent = php.recursion_depth();
1450        tracer!(TRACE, "Signature::parse", indent);
1451
1452        make_php_try!(php);
1453
1454        let version = php_try!(php.parse_u8("version"));
1455
1456        match version {
1457            3 => Signature3::parse(php),
1458            4 => Signature4::parse(php, from_embedded_signature),
1459            6 => Signature6::parse(php, from_embedded_signature),
1460            _ => {
1461                t!("Ignoring version {} packet.", version);
1462                php.fail("unknown version")
1463            },
1464        }
1465    }
1466
1467    /// Returns whether the data appears to be a signature (no promises).
1468    fn plausible(bio: &mut dyn BufferedReader<Cookie>, header: &Header)
1469        -> Result<()>
1470    {
1471        // XXX: Support other versions.
1472        Signature4::plausible(bio, header)
1473    }
1474
1475    /// When parsing an inline-signed message, attaches the digest to
1476    /// the signature.
1477    fn parse_finish(indent: isize, mut pp: PacketParser,
1478                    hash_algo: HashAlgorithm)
1479        -> Result<PacketParser>
1480    {
1481        tracer!(TRACE, "Signature::parse_finish", indent);
1482
1483        let sig: &Signature = pp.packet.downcast_ref()
1484            .ok_or_else(
1485                || Error::InvalidOperation(
1486                    format!("Called Signature::parse_finish on a {:?}",
1487                            pp.packet)))?;
1488
1489        // If we are not parsing an inline-signed message, we are
1490        // done.
1491        if sig.typ() != SignatureType::Binary
1492            && sig.typ() != SignatureType::Text
1493        {
1494            return Ok(pp);
1495        }
1496
1497        let need_hash = HashingMode::for_signature(hash_algo, sig);
1498        t!("Need a {:?}", need_hash);
1499        if TRACE {
1500            pp.reader.dump(&mut std::io::stderr())?;
1501        }
1502
1503        // Locate the corresponding HashedReader and extract the
1504        // computed hash.
1505        let mut computed_digest = None;
1506        {
1507            let recursion_depth = pp.recursion_depth();
1508
1509            // We know that the top reader is not a HashedReader (it's
1510            // a buffered_reader::Dup).  So, start with its child.
1511            let mut r = (&mut pp.reader).get_mut();
1512            while let Some(tmp) = r {
1513                {
1514                    let cookie = tmp.cookie_mut();
1515
1516                    assert!(cookie.level.unwrap_or(-1)
1517                            <= recursion_depth);
1518                    // The HashedReader has to be at level
1519                    // 'recursion_depth - 1'.
1520                    if cookie.level.is_none()
1521                        || cookie.level.unwrap() < recursion_depth - 1 {
1522                            t!("Abandoning search for suitable \
1523                                hashed reader at {:?}.", cookie.level);
1524                            break
1525                        }
1526
1527                    if cookie.hashes_for == HashesFor::Signature {
1528                        // When verifying cleartext signed messages,
1529                        // we may have more signatures than
1530                        // one-pass-signature packets, but are
1531                        // guaranteed to only have one signature
1532                        // group.
1533                        //
1534                        // Only decrement the count when hashing for
1535                        // signatures, not when hashing for cleartext
1536                        // signatures.
1537                        cookie.sig_group_mut().ops_count -= 1;
1538                    }
1539
1540                    if cookie.hashes_for == HashesFor::Signature
1541                        || cookie.hashes_for == HashesFor::CleartextSignature
1542                    {
1543                        t!("Have: {:?}",
1544                           cookie.sig_group().hashes.iter()
1545                           .map(|h| h.map(|h| h.algo()))
1546                           .collect::<Vec<_>>());
1547                        if let Some(hash) =
1548                            cookie.sig_group().hashes.iter().find_map(
1549                                |mode|
1550                                if mode.map(|ctx| ctx.algo()) == need_hash
1551                                {
1552                                    Some(mode.as_ref())
1553                                } else {
1554                                    None
1555                                })
1556                        {
1557                            t!("found a {:?} HashedReader", need_hash);
1558                            computed_digest = Some((cookie.signature_level(),
1559                                                    hash.clone()));
1560                        }
1561
1562                        if cookie.sig_group_unused() {
1563                            cookie.sig_group_pop();
1564                        }
1565                        break;
1566                    }
1567                }
1568
1569                r = tmp.get_mut();
1570            }
1571        }
1572
1573        if let Some((level, mut hash)) = computed_digest {
1574            if let Packet::Signature(ref mut sig) = pp.packet {
1575                sig.hash(&mut hash)?;
1576
1577                let mut digest = vec![0u8; hash.digest_size()];
1578                let _ = hash.digest(&mut digest);
1579
1580                sig.set_computed_digest(Some(digest));
1581                sig.set_level(level);
1582            } else {
1583                unreachable!()
1584            }
1585        }
1586
1587        Ok(pp)
1588    }
1589}
1590
1591impl Signature6 {
1592    // Parses a signature packet.
1593    //
1594    // If `from_embedded_signature` is `true`, then any embedded
1595    // signature subpackets will make the signature invalid, as nested
1596    // embedded signatures are not allowed.
1597    fn parse(mut php: PacketHeaderParser,
1598             from_embedded_signature: bool)
1599        -> Result<PacketParser>
1600    {
1601        let indent = php.recursion_depth();
1602        tracer!(TRACE, "Signature6::parse", indent);
1603
1604        make_php_try!(php);
1605
1606        let typ = php_try!(php.parse_u8("type"));
1607        let pk_algo: PublicKeyAlgorithm = php_try!(php.parse_u8("pk_algo")).into();
1608        let hash_algo: HashAlgorithm =
1609            php_try!(php.parse_u8("hash_algo")).into();
1610        let hashed_area_len = php_try!(php.parse_be_u32("hashed_area_len"));
1611        let hashed_area
1612            = php_try!(SubpacketArea::parse(&mut php,
1613                                            hashed_area_len as usize,
1614                                            hash_algo,
1615                                            from_embedded_signature));
1616        let unhashed_area_len = php_try!(php.parse_be_u32("unhashed_area_len"));
1617        let unhashed_area
1618            = php_try!(SubpacketArea::parse(&mut php,
1619                                            unhashed_area_len as usize,
1620                                            hash_algo,
1621                                            from_embedded_signature));
1622        let digest_prefix1 = php_try!(php.parse_u8("digest_prefix1"));
1623        let digest_prefix2 = php_try!(php.parse_u8("digest_prefix2"));
1624        if ! pk_algo.for_signing() {
1625            return php.fail("not a signature algorithm");
1626        }
1627        let salt_len = php_try!(php.parse_u8("salt_len")) as usize;
1628        let salt = php_try!(php.parse_bytes("salt", salt_len));
1629        let mpis = php_try!(
1630            crypto::mpi::Signature::_parse(pk_algo, &mut php));
1631
1632        let typ = typ.into();
1633        let sig = php_try!(Signature6::new(
1634            typ, pk_algo, hash_algo,
1635            hashed_area,
1636            unhashed_area,
1637            [digest_prefix1, digest_prefix2],
1638            salt,
1639            mpis));
1640        let pp = php.ok(sig.into())?;
1641
1642        Signature::parse_finish(indent, pp, hash_algo)
1643    }
1644}
1645
1646impl Signature4 {
1647    // Parses a signature packet.
1648    //
1649    // If `from_embedded_signature` is `true`, then any embedded
1650    // signature subpackets will make the signature invalid, as nested
1651    // embedded signatures are not allowed.
1652    fn parse(mut php: PacketHeaderParser,
1653             from_embedded_signature: bool)
1654        -> Result<PacketParser>
1655    {
1656        let indent = php.recursion_depth();
1657        tracer!(TRACE, "Signature4::parse", indent);
1658
1659        make_php_try!(php);
1660
1661        let typ = php_try!(php.parse_u8("type"));
1662        let pk_algo: PublicKeyAlgorithm = php_try!(php.parse_u8("pk_algo")).into();
1663        let hash_algo: HashAlgorithm =
1664            php_try!(php.parse_u8("hash_algo")).into();
1665        let hashed_area_len = php_try!(php.parse_be_u16("hashed_area_len"));
1666        let hashed_area
1667            = php_try!(SubpacketArea::parse(&mut php,
1668                                            hashed_area_len as usize,
1669                                            hash_algo,
1670                                            from_embedded_signature));
1671        let unhashed_area_len = php_try!(php.parse_be_u16("unhashed_area_len"));
1672        let unhashed_area
1673            = php_try!(SubpacketArea::parse(&mut php,
1674                                            unhashed_area_len as usize,
1675                                            hash_algo,
1676                                            from_embedded_signature));
1677        let digest_prefix1 = php_try!(php.parse_u8("digest_prefix1"));
1678        let digest_prefix2 = php_try!(php.parse_u8("digest_prefix2"));
1679        if ! pk_algo.for_signing() {
1680            return php.fail("not a signature algorithm");
1681        }
1682        let mpis = php_try!(
1683            crypto::mpi::Signature::_parse(pk_algo, &mut php));
1684
1685        let typ = typ.into();
1686        let pp = php.ok(Packet::Signature(Signature4::new(
1687            typ, pk_algo, hash_algo,
1688            hashed_area,
1689            unhashed_area,
1690            [digest_prefix1, digest_prefix2],
1691            mpis).into()))?;
1692
1693        Signature::parse_finish(indent, pp, hash_algo)
1694    }
1695
1696    /// Returns whether the data appears to be a signature (no promises).
1697    fn plausible(bio: &mut dyn BufferedReader<Cookie>, header: &Header)
1698        -> Result<()>
1699    {
1700        // The absolute minimum size for the header is 11 bytes (this
1701        // doesn't include the signature MPIs).
1702
1703        if let BodyLength::Full(len) = header.length() {
1704            if *len < 11 {
1705                // Much too short.
1706                return Err(
1707                    Error::MalformedPacket("Packet too short".into()).into());
1708            }
1709        } else {
1710            return Err(
1711                Error::MalformedPacket(
1712                    format!("Unexpected body length encoding: {:?}",
1713                            header.length())).into());
1714        }
1715
1716        // Make sure we have a minimum header.
1717        let data = bio.data(11)?;
1718        if data.len() < 11 {
1719            return Err(
1720                Error::MalformedPacket("Short read".into()).into());
1721        }
1722
1723        // Assume unknown == bad.
1724        let version = data[0];
1725        let typ : SignatureType = data[1].into();
1726        let pk_algo : PublicKeyAlgorithm = data[2].into();
1727        let hash_algo : HashAlgorithm = data[3].into();
1728
1729        if version == 4
1730            && !matches!(typ, SignatureType::Unknown(_))
1731            && !matches!(pk_algo, PublicKeyAlgorithm::Unknown(_))
1732            && !matches!(hash_algo, HashAlgorithm::Unknown(_))
1733        {
1734            Ok(())
1735        } else {
1736            Err(Error::MalformedPacket("Invalid or unsupported data".into())
1737                .into())
1738        }
1739    }
1740}
1741
1742impl Signature3 {
1743    // Parses a v3 signature packet.
1744    fn parse(mut php: PacketHeaderParser)
1745             -> Result<PacketParser>
1746    {
1747        let indent = php.recursion_depth();
1748        tracer!(TRACE, "Signature3::parse", indent);
1749
1750        make_php_try!(php);
1751
1752        let len = php_try!(php.parse_u8("hashed length"));
1753        if len != 5 {
1754            return php.fail("invalid length \
1755                             (a v3 sig has 5 bytes of hashed data)");
1756        }
1757        let typ = php_try!(php.parse_u8("type"));
1758        let creation_time: Timestamp
1759            = php_try!(php.parse_be_u32("creation_time")).into();
1760        let issuer: KeyID
1761            = KeyID::from_bytes(&php_try!(php.parse_bytes("issuer", 8))[..]);
1762        let pk_algo: PublicKeyAlgorithm
1763            = php_try!(php.parse_u8("pk_algo")).into();
1764        let hash_algo: HashAlgorithm =
1765            php_try!(php.parse_u8("hash_algo")).into();
1766        let digest_prefix1 = php_try!(php.parse_u8("digest_prefix1"));
1767        let digest_prefix2 = php_try!(php.parse_u8("digest_prefix2"));
1768        if ! pk_algo.for_signing() {
1769            return php.fail("not a signature algorithm");
1770        }
1771        let mpis = php_try!(
1772            crypto::mpi::Signature::_parse(pk_algo, &mut php));
1773
1774        let typ = typ.into();
1775        let pp = php.ok(Packet::Signature(Signature3::new(
1776            typ, creation_time, issuer, pk_algo, hash_algo,
1777            [digest_prefix1, digest_prefix2],
1778            mpis).into()))?;
1779
1780        Signature::parse_finish(indent, pp, hash_algo)
1781    }
1782}
1783
1784impl_parse_with_buffered_reader!(Signature);
1785
1786#[test]
1787fn signature_parser_test () {
1788    use crate::serialize::MarshalInto;
1789    let data = crate::tests::message("sig.pgp");
1790
1791    {
1792        let pp = PacketParser::from_bytes(data).unwrap().unwrap();
1793        assert_eq!(pp.header.length(), &BodyLength::Full(307));
1794        if let Packet::Signature(ref p) = pp.packet {
1795            assert_eq!(p.version(), 4);
1796            assert_eq!(p.typ(), SignatureType::Binary);
1797            assert_eq!(p.pk_algo(), PublicKeyAlgorithm::RSAEncryptSign);
1798            assert_eq!(p.hash_algo(), HashAlgorithm::SHA512);
1799            assert_eq!(p.hashed_area().iter().count(), 2);
1800            assert_eq!(p.unhashed_area().iter().count(), 1);
1801            assert_eq!(p.digest_prefix(), &[0x65u8, 0x74]);
1802            assert_eq!(p.mpis().serialized_len(), 258);
1803        } else {
1804            panic!("Wrong packet!");
1805        }
1806    }
1807}
1808
1809impl SubpacketArea {
1810    // Parses a subpacket area.
1811    fn parse(php: &mut PacketHeaderParser,
1812             mut limit: usize,
1813             hash_algo: HashAlgorithm,
1814             from_embedded_signature: bool)
1815             -> Result<Self>
1816    {
1817        let indent = php.recursion_depth();
1818        tracer!(TRACE, "SubpacketArea::parse", indent);
1819
1820        let mut packets = Vec::new();
1821        while limit > 0 {
1822            let r = Subpacket::parse(
1823                php, limit, hash_algo, from_embedded_signature);
1824            t!("Subpacket::parse(_, {}, {:?}) => {:?}",
1825               limit, hash_algo, r);
1826            let p = r?;
1827            assert!(limit >= p.length.len() + p.length.serialized_len());
1828            limit -= p.length.len() + p.length.serialized_len();
1829            packets.push(p);
1830        }
1831        assert!(limit == 0);
1832        Self::new(packets)
1833    }
1834}
1835
1836impl Subpacket {
1837    // Parses a raw subpacket.
1838    fn parse(php: &mut PacketHeaderParser,
1839             limit: usize,
1840             hash_algo: HashAlgorithm,
1841             from_embedded_signature: bool)
1842             -> Result<Self>
1843    {
1844        let length = SubpacketLength::parse(&mut php.reader)?;
1845        php.field("subpacket length", length.serialized_len());
1846        let len = length.len() as usize;
1847
1848        if limit < length.serialized_len() + len {
1849            return Err(Error::MalformedPacket(
1850                "Subpacket extends beyond the end of the subpacket area".into())
1851                       .into());
1852        }
1853
1854        if len == 0 {
1855            return Err(Error::MalformedPacket("Zero-length subpacket".into())
1856                       .into());
1857        }
1858
1859        let tag = php.parse_u8("subpacket tag")?;
1860        let len = len - 1;
1861
1862        // Remember our position in the reader to check subpacket boundaries.
1863        let total_out_before = php.reader.total_out();
1864
1865        // The critical bit is the high bit.  Extract it.
1866        let critical = tag & (1 << 7) != 0;
1867        // Then clear it from the type and convert it.
1868        let tag: SubpacketTag = (tag & !(1 << 7)).into();
1869
1870        #[allow(deprecated)]
1871        let value = match tag {
1872            SubpacketTag::SignatureCreationTime =>
1873                SubpacketValue::SignatureCreationTime(
1874                    php.parse_be_u32("sig creation time")?.into()),
1875            SubpacketTag::SignatureExpirationTime =>
1876                SubpacketValue::SignatureExpirationTime(
1877                    php.parse_be_u32("sig expiry time")?.into()),
1878            SubpacketTag::ExportableCertification =>
1879                SubpacketValue::ExportableCertification(
1880                    php.parse_bool("exportable")?),
1881            SubpacketTag::TrustSignature =>
1882                SubpacketValue::TrustSignature {
1883                    level: php.parse_u8("trust level")?,
1884                    trust: php.parse_u8("trust value")?,
1885                },
1886            SubpacketTag::RegularExpression => {
1887                let mut v = php.parse_bytes("regular expr", len)?;
1888                if v.is_empty() || v[v.len() - 1] != 0 {
1889                    return Err(Error::MalformedPacket(
1890                        "Regular expression not 0-terminated".into())
1891                               .into());
1892                }
1893                v.pop();
1894                SubpacketValue::RegularExpression(v)
1895            },
1896            SubpacketTag::Revocable =>
1897                SubpacketValue::Revocable(php.parse_bool("revocable")?),
1898            SubpacketTag::KeyExpirationTime =>
1899                SubpacketValue::KeyExpirationTime(
1900                    php.parse_be_u32("key expiry time")?.into()),
1901            SubpacketTag::PreferredSymmetricAlgorithms =>
1902                SubpacketValue::PreferredSymmetricAlgorithms(
1903                    php.parse_bytes("pref sym algos", len)?
1904                        .iter().map(|o| (*o).into()).collect()),
1905            SubpacketTag::RevocationKey => {
1906                // 1 octet of class, 1 octet of pk algorithm, 20 bytes
1907                // for a v4 fingerprint and 32 bytes for a v6
1908                // fingerprint.
1909                if len < 22 {
1910                    return Err(Error::MalformedPacket(
1911                        "Short revocation key subpacket".into())
1912                               .into());
1913                }
1914                let class = php.parse_u8("class")?;
1915                let pk_algo = php.parse_u8("pk algo")?.into();
1916                let fp = Fingerprint::from_bytes_intern(
1917                    None,
1918                    &php.parse_bytes("fingerprint", len - 2)?)?;
1919                SubpacketValue::RevocationKey(
1920                    RevocationKey::from_bits(pk_algo, fp, class)?)
1921            },
1922            SubpacketTag::Issuer => {
1923                if len != 8 {
1924                    return Err(Error::MalformedPacket(
1925                        format!("Malformed issuer subpacket: \
1926                                 expect 8 bytes (got {})", len))
1927                               .into());
1928                }
1929                SubpacketValue::Issuer(
1930                    KeyID::from_bytes(&php.parse_bytes("issuer", len)?))
1931            }
1932            SubpacketTag::NotationData => {
1933                let flags = php.parse_bytes("flags", 4)?;
1934                let name_len = php.parse_be_u16("name len")? as usize;
1935                let value_len = php.parse_be_u16("value len")? as usize;
1936
1937                if len != 8 + name_len + value_len {
1938                    return Err(Error::MalformedPacket(
1939                        format!("Malformed notation data subpacket: \
1940                                 expected {} bytes, got {}",
1941                                8 + name_len + value_len,
1942                                len)).into());
1943                }
1944                SubpacketValue::NotationData(
1945                    NotationData::new(
1946                        std::str::from_utf8(
1947                            &php.parse_bytes("notation name", name_len)?)
1948                            .map_err(|e| anyhow::Error::from(
1949                                Error::MalformedPacket(
1950                                    format!("Malformed notation name: {}", e)))
1951                            )?,
1952                        &php.parse_bytes("notation value", value_len)?,
1953                        Some(NotationDataFlags::new(&flags)?)))
1954            },
1955            SubpacketTag::PreferredHashAlgorithms =>
1956                SubpacketValue::PreferredHashAlgorithms(
1957                    php.parse_bytes("pref hash algos", len)?
1958                        .iter().map(|o| (*o).into()).collect()),
1959            SubpacketTag::PreferredCompressionAlgorithms =>
1960                SubpacketValue::PreferredCompressionAlgorithms(
1961                    php.parse_bytes("pref compression algos", len)?
1962                        .iter().map(|o| (*o).into()).collect()),
1963            SubpacketTag::KeyServerPreferences =>
1964                SubpacketValue::KeyServerPreferences(
1965                    KeyServerPreferences::new(
1966                        &php.parse_bytes("key server pref", len)?
1967                    )),
1968            SubpacketTag::PreferredKeyServer =>
1969                SubpacketValue::PreferredKeyServer(
1970                    php.parse_bytes("pref key server", len)?),
1971            SubpacketTag::PrimaryUserID =>
1972                SubpacketValue::PrimaryUserID(
1973                    php.parse_bool("primary user id")?),
1974            SubpacketTag::PolicyURI =>
1975                SubpacketValue::PolicyURI(php.parse_bytes("policy URI", len)?),
1976            SubpacketTag::KeyFlags =>
1977                SubpacketValue::KeyFlags(KeyFlags::new(
1978                    &php.parse_bytes("key flags", len)?)),
1979            SubpacketTag::SignersUserID =>
1980                SubpacketValue::SignersUserID(
1981                    php.parse_bytes("signers user id", len)?),
1982            SubpacketTag::ReasonForRevocation => {
1983                if len == 0 {
1984                    return Err(Error::MalformedPacket(
1985                        "Short reason for revocation subpacket".into()).into());
1986                }
1987                SubpacketValue::ReasonForRevocation {
1988                    code: php.parse_u8("revocation reason")?.into(),
1989                    reason: php.parse_bytes("human-readable", len - 1)?,
1990                }
1991            },
1992            SubpacketTag::Features =>
1993                SubpacketValue::Features(Features::new(
1994                    &php.parse_bytes("features", len)?)),
1995            SubpacketTag::SignatureTarget => {
1996                if len < 2 {
1997                    return Err(Error::MalformedPacket(
1998                        "Short reason for revocation subpacket".into()).into());
1999                }
2000                SubpacketValue::SignatureTarget {
2001                    pk_algo: php.parse_u8("pk algo")?.into(),
2002                    hash_algo: php.parse_u8("hash algo")?.into(),
2003                    digest: php.parse_bytes("digest", len - 2)?,
2004                }
2005            },
2006            SubpacketTag::EmbeddedSignature => {
2007                if from_embedded_signature {
2008                    return Err(Error::MalformedPacket(
2009                        "Nested embedded signatures are not allowed".into())
2010                               .into());
2011                } else {
2012                    SubpacketValue::EmbeddedSignature(
2013                        EmbeddedSignature::from_bytes(
2014                            &php.parse_bytes("embedded sig", len)?)?)
2015                }
2016            }
2017            SubpacketTag::IssuerFingerprint => {
2018                if len == 0 {
2019                    return Err(Error::MalformedPacket(
2020                        "Short issuer fingerprint subpacket".into()).into());
2021                }
2022                let version = php.parse_u8("version")?;
2023                if let Some(expect_len) = match version {
2024                    4 => Some(1 + 20),
2025                    6 => Some(1 + 32),
2026                    _ => None,
2027                } {
2028                    if len != expect_len {
2029                        return Err(Error::MalformedPacket(
2030                            format!("Malformed issuer fingerprint subpacket: \
2031                                     expected {} bytes, got {}",
2032                                    expect_len, len)).into());
2033                    }
2034                }
2035                let bytes = php.parse_bytes("issuer fp", len - 1)?;
2036                SubpacketValue::IssuerFingerprint(
2037                    Fingerprint::from_bytes(version, &bytes)?)
2038            },
2039            SubpacketTag::IntendedRecipient => {
2040                if len == 0 {
2041                    return Err(Error::MalformedPacket(
2042                        "Short intended recipient subpacket".into()).into());
2043                }
2044                let version = php.parse_u8("version")?;
2045                if let Some(expect_len) = match version {
2046                    4 => Some(1 + 20),
2047                    6 => Some(1 + 32),
2048                    _ => None,
2049                } {
2050                    if len != expect_len {
2051                        return Err(Error::MalformedPacket(
2052                            format!("Malformed intended recipient subpacket: \
2053                                     expected {} bytes, got {}",
2054                                    expect_len, len)).into());
2055                    }
2056                }
2057                let bytes = php.parse_bytes("intended rcpt", len - 1)?;
2058                SubpacketValue::IntendedRecipient(
2059                    Fingerprint::from_bytes(version, &bytes)?)
2060            },
2061            SubpacketTag::ApprovedCertifications => {
2062                // If we don't know the hash algorithm, put all digest
2063                // into one bucket.  That way, at least it will
2064                // roundtrip.  It will never verify, because we don't
2065                // know the hash.
2066                let digest_size =
2067                    hash_algo.context().map(|c| c.for_digest().digest_size())
2068                    .unwrap_or(len);
2069
2070                if digest_size == 0 {
2071                    // Empty body with unknown hash algorithm.
2072                    SubpacketValue::ApprovedCertifications(
2073                        Vec::with_capacity(0))
2074                } else {
2075                    if len % digest_size != 0 {
2076                        return Err(Error::BadSignature(
2077                            "Wrong number of bytes in certification subpacket"
2078                                .into()).into());
2079                    }
2080                    let bytes = php.parse_bytes("attested crts", len)?;
2081                    SubpacketValue::ApprovedCertifications(
2082                        bytes.chunks(digest_size).map(Into::into).collect())
2083                }
2084            },
2085
2086            SubpacketTag::PreferredAEADCiphersuites => {
2087                if len % 2 != 0 {
2088                    return Err(Error::BadSignature(
2089                        "Wrong number of bytes in preferred AEAD \
2090                         Ciphersuites subpacket"
2091                            .into()).into());
2092                }
2093
2094                SubpacketValue::PreferredAEADCiphersuites(
2095                    php.parse_bytes("pref aead ciphersuites", len)?
2096                        .chunks(2).map(|o| (o[0].into(),
2097                                            o[1].into())).collect())
2098            },
2099
2100            SubpacketTag::Reserved(_)
2101                | SubpacketTag::PlaceholderForBackwardCompatibility
2102                | SubpacketTag::PreferredAEADAlgorithms
2103                | SubpacketTag::Private(_)
2104                | SubpacketTag::Unknown(_) =>
2105                SubpacketValue::Unknown {
2106                    tag,
2107                    body: php.parse_bytes("unknown subpacket", len)?,
2108                },
2109        };
2110
2111        let total_out = php.reader.total_out();
2112        if total_out_before + len != total_out {
2113            return Err(Error::MalformedPacket(
2114                format!("Malformed subpacket: \
2115                         body length is {} bytes, but read {}",
2116                        len, total_out - total_out_before)).into());
2117        }
2118
2119        Ok(Subpacket::with_length(
2120            length,
2121            value,
2122            critical,
2123        ))
2124    }
2125}
2126
2127impl SubpacketLength {
2128    /// Parses a subpacket length.
2129    fn parse<R: BufferedReader<C>, C: fmt::Debug + Send + Sync>(bio: &mut R) -> Result<Self> {
2130        let octet1 = bio.data_consume_hard(1)?[0];
2131        if octet1 < 192 {
2132            // One octet.
2133            Ok(Self::new(
2134                octet1 as u32,
2135                // Unambiguous.
2136                None))
2137        } else if (192..255).contains(&octet1) {
2138            // Two octets length.
2139            let octet2 = bio.data_consume_hard(1)?[0];
2140            let len = ((octet1 as u32 - 192) << 8) + octet2 as u32 + 192;
2141            Ok(Self::new(
2142                len,
2143                if Self::len_optimal_encoding(len) == 2 {
2144                    None
2145                } else {
2146                    Some(vec![octet1, octet2])
2147                }))
2148        } else {
2149            // Five octets.
2150            assert_eq!(octet1, 255);
2151            let len = bio.read_be_u32()?;
2152            Ok(Self::new(
2153                len,
2154                if Self::len_optimal_encoding(len) == 5 {
2155                    None
2156                } else {
2157                    let mut out = Vec::with_capacity(5);
2158                    out.push(octet1);
2159                    out.extend_from_slice(&len.to_be_bytes());
2160                    Some(out)
2161                }))
2162        }
2163    }
2164}
2165
2166#[cfg(test)]
2167quickcheck! {
2168    fn length_roundtrip(l: u32) -> bool {
2169        use crate::serialize::Marshal;
2170
2171        let length = SubpacketLength::from(l);
2172        let mut encoded = Vec::new();
2173        length.serialize(&mut encoded).unwrap();
2174        assert_eq!(encoded.len(), length.serialized_len());
2175        let mut reader = buffered_reader::Memory::new(&encoded);
2176        SubpacketLength::parse(&mut reader).unwrap().len() == l as usize
2177    }
2178}
2179
2180impl OnePassSig {
2181    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
2182        let indent = php.recursion_depth();
2183        tracer!(TRACE, "OnePassSig", indent);
2184
2185        make_php_try!(php);
2186
2187        let version = php_try!(php.parse_u8("version"));
2188        match version {
2189            3 => OnePassSig3::parse(php),
2190            6 => OnePassSig6::parse(php),
2191            _ => {
2192                t!("Ignoring version {} packet", version);
2193
2194                // Unknown version.  Return an unknown packet.
2195                php.fail("unknown version")
2196            },
2197        }
2198    }
2199}
2200
2201impl_parse_with_buffered_reader!(OnePassSig);
2202
2203impl OnePassSig3 {
2204    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
2205        let indent = php.recursion_depth();
2206        tracer!(TRACE, "OnePassSig3", indent);
2207
2208        make_php_try!(php);
2209
2210        let typ = php_try!(php.parse_u8("type"));
2211        let hash_algo = php_try!(php.parse_u8("hash_algo"));
2212        let pk_algo = php_try!(php.parse_u8("pk_algo"));
2213        let mut issuer = [0u8; 8];
2214        issuer.copy_from_slice(&php_try!(php.parse_bytes("issuer", 8)));
2215        let last = php_try!(php.parse_u8("last"));
2216
2217        let hash_algo = hash_algo.into();
2218        let typ = typ.into();
2219        let mut sig = OnePassSig3::new(typ);
2220        sig.set_hash_algo(hash_algo);
2221        sig.set_pk_algo(pk_algo.into());
2222        sig.set_issuer(KeyID::from_bytes(&issuer));
2223        sig.set_last_raw(last);
2224        let need_hash = HashingMode::for_salt_and_type(hash_algo, &[], typ);
2225
2226        let recursion_depth = php.recursion_depth();
2227
2228        // Check if we are processing a cleartext signed message.
2229        let want_hashes_for = if Cookie::processing_csf_message(&php.reader) {
2230            HashesFor::CleartextSignature
2231        } else {
2232            HashesFor::Signature
2233        };
2234
2235        // Walk up the reader chain to see if there is already a
2236        // hashed reader on level recursion_depth - 1.
2237        let done = {
2238            let mut done = false;
2239            let mut reader : Option<&mut dyn BufferedReader<Cookie>>
2240                = Some(&mut php.reader);
2241            while let Some(r) = reader {
2242                {
2243                    let cookie = r.cookie_mut();
2244                    if let Some(br_level) = cookie.level {
2245                        if br_level < recursion_depth - 1 {
2246                            break;
2247                        }
2248                        if br_level == recursion_depth - 1
2249                            && cookie.hashes_for == want_hashes_for {
2250                                // We found a suitable hashed reader.
2251                                if cookie.saw_last {
2252                                    cookie.sig_group_push();
2253                                    cookie.saw_last = false;
2254                                    cookie.hash_stash =
2255                                        Some(php.header_bytes.clone());
2256                                }
2257
2258                                // Make sure that it uses the required
2259                                // hash algorithm.
2260                                if php.state.settings.automatic_hashing
2261                                    && ! cookie.sig_group().hashes.iter()
2262                                    .any(|mode| {
2263                                        mode.map(|ctx| ctx.algo()) == need_hash
2264                                    })
2265                                {
2266                                    if let Ok(ctx) = hash_algo.context() {
2267                                        let ctx = ctx.for_signature(4);
2268                                        cookie.sig_group_mut().hashes.push(
2269                                            HashingMode::for_salt_and_type(
2270                                                ctx, &[], typ)
2271                                        );
2272                                    }
2273                                }
2274
2275                                // Account for this OPS packet.
2276                                cookie.sig_group_mut().ops_count += 1;
2277
2278                                // Keep track of the last flag.
2279                                cookie.saw_last = last > 0;
2280
2281                                // We're done.
2282                                done = true;
2283                                break;
2284                            }
2285                    } else {
2286                        break;
2287                    }
2288                }
2289                reader = r.get_mut();
2290            }
2291            done
2292        };
2293        // Commit here after potentially pushing a signature group.
2294        let mut pp = php.ok(Packet::OnePassSig(sig.into()))?;
2295        if done {
2296            return Ok(pp);
2297        }
2298
2299        // We create an empty hashed reader even if we don't support
2300        // the hash algorithm so that we have something to match
2301        // against when we get to the Signature packet.  Or, automatic
2302        // hashing may be disabled, and we want to be able to enable
2303        // it explicitly.
2304        let mut algos = Vec::new();
2305        if pp.state.settings.automatic_hashing && hash_algo.is_supported() {
2306            algos.push(HashingMode::for_salt_and_type(hash_algo, &[], typ));
2307        }
2308
2309        // We can't push the HashedReader on the BufferedReader stack:
2310        // when we finish processing this OnePassSig packet, it will
2311        // be popped.  Instead, we need to insert it at the next
2312        // higher level.  Unfortunately, this isn't possible.  But,
2313        // since we're done reading the current packet, we can pop the
2314        // readers associated with it, and then push the HashedReader.
2315        // This is a bit of a layering violation, but I (Neal) can't
2316        // think of a more elegant solution.
2317
2318        assert!(pp.reader.cookie_ref().level <= Some(recursion_depth));
2319        let (fake_eof, reader)
2320            = buffered_reader_stack_pop(Box::new(pp.take_reader()),
2321                                        recursion_depth)?;
2322        // We only pop the buffered readers for the OPS, and we
2323        // (currently) never use a fake eof for OPS packets.
2324        assert!(! fake_eof);
2325
2326        let mut reader = HashedReader::new(
2327            reader, want_hashes_for, algos)?;
2328        reader.cookie_mut().level = Some(recursion_depth - 1);
2329        // Account for this OPS packet.
2330        reader.cookie_mut().sig_group_mut().ops_count += 1;
2331        // Keep track of the last flag.
2332        reader.cookie_mut().saw_last = last > 0;
2333
2334        t!("Pushed a hashed reader, level {:?}", reader.cookie_mut().level);
2335
2336        // We add an empty limitor on top of the hashed reader,
2337        // because when we are done processing a packet,
2338        // PacketParser::finish discards any unread data from the top
2339        // reader.  Since the top reader is the HashedReader, this
2340        // discards any following packets.  To prevent this, we push a
2341        // Limitor on the reader stack.
2342        let mut reader = buffered_reader::Limitor::with_cookie(
2343            reader, 0, Cookie::default());
2344        reader.cookie_mut().level = Some(recursion_depth);
2345
2346        pp.reader = Box::new(reader);
2347
2348        Ok(pp)
2349    }
2350}
2351
2352impl PacketParser<'_> {
2353    /// Starts hashing for the current [`OnePassSig`] packet.
2354    ///
2355    /// If automatic hashing is disabled using
2356    /// [`PacketParserBuilder::automatic_hashing`], then hashing can
2357    /// be explicitly enabled while parsing a [`OnePassSig`] packet.
2358    ///
2359    /// If this function is called on a packet other than a
2360    /// [`OnePassSig`] packet, it returns [`Error::InvalidOperation`].
2361    ///
2362    ///   [`Error::InvalidOperation`]: crate::Error::InvalidOperation
2363    ///
2364    /// # Examples
2365    ///
2366    /// ```rust
2367    /// # fn main() -> sequoia_openpgp::Result<()> {
2368    /// # use sequoia_openpgp as openpgp;
2369    /// # use openpgp::{Cert, Packet};
2370    /// # use openpgp::parse::{Parse, PacketParserResult, PacketParserBuilder};
2371    /// // Parse a signed message, verify using the signer's key.
2372    /// let message_data: &[u8] = // ...
2373    /// #    include_bytes!("../tests/data/messages/signed-1-eddsa-ed25519.pgp");
2374    /// # let cert: Cert = // ...
2375    /// #    Cert::from_bytes(include_bytes!("../tests/data/keys/emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
2376    /// let signer = // ...
2377    /// #    cert.primary_key().key();
2378    /// let mut good = false;
2379    /// let mut ppr = PacketParserBuilder::from_bytes(message_data)?
2380    ///     .automatic_hashing(false)
2381    ///     .build()?;
2382    /// while let PacketParserResult::Some(mut pp) = ppr {
2383    ///     if let Packet::OnePassSig(_) = &pp.packet {
2384    ///         pp.start_hashing()?;
2385    ///     }
2386    ///     if let Packet::Signature(sig) = &mut pp.packet {
2387    ///         good |= sig.verify_document(signer).is_ok();
2388    ///     }
2389    ///     // Start parsing the next packet, recursing.
2390    ///     ppr = pp.recurse()?.1;
2391    /// }
2392    /// assert!(good);
2393    /// # Ok(()) }
2394    /// ```
2395    pub fn start_hashing(&mut self) -> Result<()> {
2396        let ops: &OnePassSig = self.packet.downcast_ref()
2397            .ok_or_else(|| Error::InvalidOperation(
2398                "Must only be invoked on one-pass-signature packets".into())
2399            )?;
2400
2401        let sig_version = match ops.version() {
2402            3 => 4,
2403            n => return Err(Error::InvalidOperation(
2404                format!("don't know how to hash for v{} one pass sig",
2405                        n)).into()),
2406        };
2407
2408        let hash_algo = ops.hash_algo();
2409        let typ = ops.typ();
2410        let salt = ops.salt().unwrap_or(&[]);
2411        let need_hash = HashingMode::for_salt_and_type(hash_algo, salt, typ);
2412        let recursion_depth = self.recursion_depth();
2413        let want_hashes_for = if Cookie::processing_csf_message(&self.reader) {
2414            HashesFor::CleartextSignature
2415        } else {
2416            HashesFor::Signature
2417        };
2418
2419        // Walk up the reader chain to find the hashed reader on level
2420        // recursion_depth - 1.
2421        let mut reader : Option<&mut dyn BufferedReader<Cookie>>
2422            = Some(&mut self.reader);
2423        while let Some(r) = reader {
2424            {
2425                let cookie = r.cookie_mut();
2426                if let Some(br_level) = cookie.level {
2427                    if br_level < recursion_depth - 1 {
2428                        break;
2429                    }
2430                    if br_level == recursion_depth - 1
2431                        && cookie.hashes_for == want_hashes_for {
2432                            // We found a suitable hashed reader.
2433                            // Make sure that it uses the required
2434                            // hash algorithm.
2435                            if ! cookie.sig_group().hashes.iter()
2436                                .any(|mode| {
2437                                    mode.map(|ctx| ctx.algo()) == need_hash
2438                                })
2439                            {
2440                                let mut ctx = hash_algo.context()?
2441                                    .for_signature(sig_version);
2442
2443                                ctx.update(&salt);
2444                                cookie.sig_group_mut().hashes.push(
2445                                    HashingMode::for_salt_and_type(
2446                                        ctx, salt, typ));
2447                            }
2448                            break;
2449                        }
2450                } else {
2451                    break;
2452                }
2453            }
2454            reader = r.get_mut();
2455        }
2456
2457        Ok(())
2458    }
2459}
2460
2461#[test]
2462fn one_pass_sig3_parser_test () {
2463    use crate::SignatureType;
2464    use crate::PublicKeyAlgorithm;
2465
2466    // This test assumes that the first packet is a OnePassSig packet.
2467    let data = crate::tests::message("signed-1.pgp");
2468    let mut pp = PacketParser::from_bytes(data).unwrap().unwrap();
2469    let p = pp.finish().unwrap();
2470    // eprintln!("packet: {:?}", p);
2471
2472    if let &Packet::OnePassSig(ref p) = p {
2473        assert_eq!(p.version(), 3);
2474        assert_eq!(p.typ(), SignatureType::Binary);
2475        assert_eq!(p.hash_algo(), HashAlgorithm::SHA512);
2476        assert_eq!(p.pk_algo(), PublicKeyAlgorithm::RSAEncryptSign);
2477        assert_eq!(format!("{:X}", p.issuer()), "7223B56678E02528");
2478        assert_eq!(p.last_raw(), 1);
2479    } else {
2480        panic!("Wrong packet!");
2481    }
2482}
2483
2484impl_parse_with_buffered_reader!(
2485    OnePassSig3,
2486    |reader| -> Result<Self> {
2487        OnePassSig::from_buffered_reader(reader).and_then(|p| match p {
2488            OnePassSig::V3(p) => Ok(p),
2489            p => Err(Error::InvalidOperation(
2490                format!("Not a OnePassSig::V3 packet: {:?}", p)).into()),
2491        })
2492    });
2493
2494impl OnePassSig6 {
2495    #[allow(clippy::blocks_in_conditions)]
2496    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
2497        let indent = php.recursion_depth();
2498        tracer!(TRACE, "OnePassSig6", indent);
2499
2500        make_php_try!(php);
2501
2502        let typ = php_try!(php.parse_u8("type"));
2503        let hash_algo = php_try!(php.parse_u8("hash_algo"));
2504        let pk_algo = php_try!(php.parse_u8("pk_algo"));
2505        let salt_len = php_try!(php.parse_u8("salt_len"));
2506        let salt = php_try!(php.parse_bytes("salt", salt_len.into()));
2507        let mut issuer = [0u8; 32];
2508        issuer.copy_from_slice(&php_try!(php.parse_bytes("issuer", 32)));
2509        let last = php_try!(php.parse_u8("last"));
2510
2511        let hash_algo = hash_algo.into();
2512        let typ = typ.into();
2513        let mut sig =
2514            OnePassSig6::new(typ, Fingerprint::from_bytes(6, &issuer)?);
2515        sig.set_salt(salt.clone());
2516        sig.set_hash_algo(hash_algo);
2517        sig.set_pk_algo(pk_algo.into());
2518        sig.set_last_raw(last);
2519        let need_hash = HashingMode::for_salt_and_type(hash_algo, &salt, typ);
2520
2521        let recursion_depth = php.recursion_depth();
2522
2523        // Check if we are processing a cleartext signed message.
2524        let want_hashes_for = if Cookie::processing_csf_message(&php.reader) {
2525            HashesFor::CleartextSignature
2526        } else {
2527            HashesFor::Signature
2528        };
2529
2530        // Walk up the reader chain to see if there is already a
2531        // hashed reader on level recursion_depth - 1.
2532        let done = {
2533            let mut done = false;
2534            let mut reader : Option<&mut dyn BufferedReader<Cookie>>
2535                = Some(&mut php.reader);
2536            while let Some(r) = reader {
2537                {
2538                    let cookie = r.cookie_mut();
2539                    if let Some(br_level) = cookie.level {
2540                        if br_level < recursion_depth - 1 {
2541                            break;
2542                        }
2543                        if br_level == recursion_depth - 1
2544                            && cookie.hashes_for == want_hashes_for {
2545                                // We found a suitable hashed reader.
2546                                if cookie.saw_last {
2547                                    cookie.sig_group_push();
2548                                    cookie.saw_last = false;
2549                                    cookie.hash_stash =
2550                                        Some(php.header_bytes.clone());
2551                                }
2552
2553                                // Make sure that it uses the required
2554                                // hash algorithm.
2555                                if php.state.settings.automatic_hashing
2556                                    && ! cookie.sig_group().hashes.iter()
2557                                    .any(|mode| {
2558                                        mode.map(|ctx| ctx.algo()) == need_hash
2559                                    })
2560                                {
2561                                    if let Ok(ctx) = hash_algo.context() {
2562                                        let mut ctx = ctx.for_signature(6);
2563                                        ctx.update(&salt);
2564                                        cookie.sig_group_mut().hashes.push(
2565                                            HashingMode::for_salt_and_type(
2566                                                ctx, &salt, typ)
2567                                        );
2568                                    }
2569                                }
2570
2571                                // Account for this OPS packet.
2572                                cookie.sig_group_mut().ops_count += 1;
2573
2574                                // Keep track of the last flag.
2575                                cookie.saw_last = last > 0;
2576
2577                                // We're done.
2578                                done = true;
2579                                break;
2580                            }
2581                    } else {
2582                        break;
2583                    }
2584                }
2585                reader = r.get_mut();
2586            }
2587            done
2588        };
2589        // Commit here after potentially pushing a signature group.
2590        let mut pp = php.ok(Packet::OnePassSig(sig.into()))?;
2591        if done {
2592            return Ok(pp);
2593        }
2594
2595        // We create an empty hashed reader even if we don't support
2596        // the hash algorithm so that we have something to match
2597        // against when we get to the Signature packet.
2598        let mut algos = Vec::new();
2599        if pp.state.settings.automatic_hashing && hash_algo.is_supported() {
2600            algos.push(HashingMode::for_salt_and_type(hash_algo, &salt, typ));
2601        }
2602
2603        // We can't push the HashedReader on the BufferedReader stack:
2604        // when we finish processing this OnePassSig packet, it will
2605        // be popped.  Instead, we need to insert it at the next
2606        // higher level.  Unfortunately, this isn't possible.  But,
2607        // since we're done reading the current packet, we can pop the
2608        // readers associated with it, and then push the HashedReader.
2609        // This is a bit of a layering violation, but I (Neal) can't
2610        // think of a more elegant solution.
2611
2612        assert!(pp.reader.cookie_ref().level <= Some(recursion_depth));
2613        let (fake_eof, reader)
2614            = buffered_reader_stack_pop(Box::new(pp.take_reader()),
2615                                        recursion_depth)?;
2616        // We only pop the buffered readers for the OPS, and we
2617        // (currently) never use a fake eof for OPS packets.
2618        assert!(! fake_eof);
2619
2620        let mut reader = HashedReader::new(
2621            reader, want_hashes_for, algos)?;
2622        reader.cookie_mut().level = Some(recursion_depth - 1);
2623        // Account for this OPS packet.
2624        reader.cookie_mut().sig_group_mut().ops_count += 1;
2625        // Keep track of the last flag.
2626        reader.cookie_mut().saw_last = last > 0;
2627
2628        t!("Pushed a hashed reader, level {:?}", reader.cookie_mut().level);
2629
2630        // We add an empty limitor on top of the hashed reader,
2631        // because when we are done processing a packet,
2632        // PacketParser::finish discards any unread data from the top
2633        // reader.  Since the top reader is the HashedReader, this
2634        // discards any following packets.  To prevent this, we push a
2635        // Limitor on the reader stack.
2636        let mut reader = buffered_reader::Limitor::with_cookie(
2637            reader, 0, Cookie::default());
2638        reader.cookie_mut().level = Some(recursion_depth);
2639
2640        pp.reader = Box::new(reader);
2641
2642        Ok(pp)
2643    }
2644}
2645
2646impl_parse_with_buffered_reader!(
2647    OnePassSig6,
2648    |reader| -> Result<Self> {
2649        OnePassSig::from_buffered_reader(reader).and_then(|p| match p {
2650            OnePassSig::V6(p) => Ok(p),
2651            p => Err(Error::InvalidOperation(
2652                format!("Not a OnePassSig::V6 packet: {:?}", p)).into()),
2653        })
2654    });
2655
2656#[test]
2657fn one_pass_sig_test () {
2658    struct Test<'a> {
2659        filename: &'a str,
2660        digest_prefix: Vec<[u8; 2]>,
2661    }
2662
2663    let tests = [
2664            Test {
2665                filename: "signed-1.pgp",
2666                digest_prefix: vec![ [ 0x83, 0xF5 ] ],
2667            },
2668            Test {
2669                filename: "signed-2-partial-body.pgp",
2670                digest_prefix: vec![ [ 0x2F, 0xBE ] ],
2671            },
2672            Test {
2673                filename: "signed-3-partial-body-multiple-sigs.pgp",
2674                digest_prefix: vec![ [ 0x29, 0x64 ], [ 0xff, 0x7d ] ],
2675            },
2676    ];
2677
2678    for test in tests.iter() {
2679        eprintln!("Trying {}...", test.filename);
2680        let mut ppr = PacketParserBuilder::from_bytes(
2681            crate::tests::message(test.filename))
2682            .unwrap_or_else(|_| panic!("Error reading {}", test.filename))
2683            .build().unwrap();
2684
2685        let mut one_pass_sigs = 0;
2686        let mut sigs = 0;
2687
2688        while let PacketParserResult::Some(pp) = ppr {
2689            if let Packet::OnePassSig(_) = pp.packet {
2690                one_pass_sigs += 1;
2691            } else if let Packet::Signature(ref sig) = pp.packet {
2692                eprintln!("  {}:\n  prefix: expected: {}, in sig: {}",
2693                          test.filename,
2694                          crate::fmt::to_hex(&test.digest_prefix[sigs][..], false),
2695                          crate::fmt::to_hex(sig.digest_prefix(), false));
2696                eprintln!("  computed hash: {}",
2697                          crate::fmt::to_hex(sig.computed_digest().unwrap(),
2698                                             false));
2699
2700                assert_eq!(&test.digest_prefix[sigs], sig.digest_prefix());
2701                assert_eq!(&test.digest_prefix[sigs][..],
2702                           &sig.computed_digest().unwrap()[..2]);
2703
2704                sigs += 1;
2705            } else if one_pass_sigs > 0 {
2706                assert_eq!(one_pass_sigs, test.digest_prefix.len(),
2707                           "Number of OnePassSig packets does not match \
2708                            number of expected OnePassSig packets.");
2709            }
2710
2711            ppr = pp.recurse().expect("Parsing message").1;
2712        }
2713        assert_eq!(one_pass_sigs, sigs,
2714                   "Number of OnePassSig packets does not match \
2715                    number of signature packets.");
2716
2717        eprintln!("done.");
2718    }
2719}
2720
2721// Key::parse doesn't actually use the Key type parameters.  So, we
2722// can just set them to anything.  This avoids the caller having to
2723// set them to something.
2724impl Key<key::UnspecifiedParts, key::UnspecifiedRole>
2725{
2726    /// Parses the body of a public key, public subkey, secret key or
2727    /// secret subkey packet.
2728    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
2729        tracer!(TRACE, "Key::parse", php.recursion_depth());
2730        make_php_try!(php);
2731        let tag = php.header.ctb().tag();
2732        assert!(tag == Tag::Reserved
2733                || tag == Tag::PublicKey
2734                || tag == Tag::PublicSubkey
2735                || tag == Tag::SecretKey
2736                || tag == Tag::SecretSubkey);
2737        let version = php_try!(php.parse_u8("version"));
2738
2739        match version {
2740            4 => Key4::parse(php),
2741            6 => Key6::parse(php),
2742            _ => php.fail("unknown version"),
2743        }
2744    }
2745
2746    /// Returns whether the data appears to be a key (no promises).
2747    fn plausible(bio: &mut dyn BufferedReader<Cookie>, header: &Header)
2748        -> Result<()>
2749    {
2750        // The packet's header is 6 bytes.
2751        if let BodyLength::Full(len) = header.length() {
2752            if *len < 6 {
2753                // Much too short.
2754                return Err(Error::MalformedPacket(
2755                    format!("Packet too short ({} bytes)", len)).into());
2756            }
2757        } else {
2758            return Err(
2759                Error::MalformedPacket(
2760                    format!("Unexpected body length encoding: {:?}",
2761                            header.length())).into());
2762        }
2763
2764        // Make sure we have a minimum header.
2765        let data = bio.data(6)?;
2766        if data.len() < 6 {
2767            return Err(
2768                Error::MalformedPacket("Short read".into()).into());
2769        }
2770
2771        // Assume unknown == bad.
2772        let version = data[0];
2773        match version {
2774            4 => Key4::plausible(bio, header),
2775            6 => Key6::plausible(bio, header),
2776            n => Err(Error::MalformedPacket(
2777                format!("Unknown version {}", n)).into()),
2778        }
2779    }
2780}
2781
2782// Key4::parse doesn't actually use the Key4 type parameters.  So, we
2783// can just set them to anything.  This avoids the caller having to
2784// set them to something.
2785impl Key4<key::UnspecifiedParts, key::UnspecifiedRole>
2786{
2787    /// Parses the body of a public key, public subkey, secret key or
2788    /// secret subkey packet.
2789    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
2790        tracer!(TRACE, "Key4::parse", php.recursion_depth());
2791        make_php_try!(php);
2792        let tag = php.header.ctb().tag();
2793        assert!(tag == Tag::Reserved
2794                || tag == Tag::PublicKey
2795                || tag == Tag::PublicSubkey
2796                || tag == Tag::SecretKey
2797                || tag == Tag::SecretSubkey);
2798
2799        let creation_time = php_try!(php.parse_be_u32("creation_time"));
2800        let pk_algo: PublicKeyAlgorithm = php_try!(php.parse_u8("pk_algo")).into();
2801        let mpis = php_try!(PublicKey::_parse(pk_algo, &mut php));
2802        let secret = if let Ok(s2k_usage) = php.parse_u8("s2k_usage") {
2803            use crypto::mpi;
2804            let sec = match s2k_usage {
2805                // Unencrypted
2806                0 => {
2807                    let sec = php_try!(
2808                        mpi::SecretKeyMaterial::_parse(
2809                            pk_algo, &mut php,
2810                            Some(mpi::SecretKeyChecksum::Sum16)));
2811                    sec.into()
2812                }
2813
2814                // AEAD encrypted secrets.
2815                253 => {
2816                    let sym_algo: SymmetricAlgorithm =
2817                        php_try!(php.parse_u8("sym_algo")).into();
2818
2819                    let aead_algo: AEADAlgorithm =
2820                        php_try!(php.parse_u8("aead_algo")).into();
2821
2822                    let s2k = php_try!(S2K::parse_v4(&mut php));
2823
2824                    let aead_iv = php_try!(php.parse_bytes(
2825                        "aead_iv",
2826                        // If we don't know the AEAD mode, we won't
2827                        // know the nonce size, and all the IV will
2828                        // end up in the ciphertext.  This is an
2829                        // inherent limitation of the v4 packet
2830                        // format.
2831                        aead_algo.nonce_size().unwrap_or(0)))
2832                        .into();
2833
2834                    let cipher =
2835                        php_try!(php.parse_bytes_eof("encrypted_mpis"))
2836                        .into_boxed_slice();
2837
2838                    crate::packet::key::Encrypted::new_aead(
2839                        s2k, sym_algo, aead_algo, aead_iv, cipher).into()
2840                },
2841
2842                // Encrypted, whether we support the S2K method or not.
2843                _ => {
2844                    let sk: SymmetricAlgorithm = match s2k_usage {
2845                        254 | 255 =>
2846                            php_try!(php.parse_u8("sym_algo")).into(),
2847                        _ => s2k_usage.into(),
2848                    };
2849                    let s2k = match s2k_usage {
2850                        254 | 255 => php_try!(S2K::parse_v4(&mut php)),
2851                        _ => {
2852                            #[allow(deprecated)] S2K::Implicit
2853                        },
2854                    };
2855                    let s2k_supported = s2k.is_supported();
2856                    let cipher =
2857                        php_try!(php.parse_bytes_eof("encrypted_mpis"))
2858                        .into_boxed_slice();
2859
2860                    crate::packet::key::Encrypted::new_raw(
2861                        s2k, sk,
2862                        match s2k_usage {
2863                            254 => Some(mpi::SecretKeyChecksum::SHA1),
2864                            255 => Some(mpi::SecretKeyChecksum::Sum16),
2865                            _ => Some(mpi::SecretKeyChecksum::Sum16),
2866                        },
2867                        if s2k_supported {
2868                            Ok((0, cipher))
2869                        } else {
2870                            Err(cipher)
2871                        },
2872                    ).into()
2873                }
2874            };
2875
2876            Some(sec)
2877        } else {
2878            None
2879        };
2880
2881        let have_secret = secret.is_some();
2882        if have_secret {
2883            if tag == Tag::PublicKey || tag == Tag::PublicSubkey {
2884                return php.error(Error::MalformedPacket(
2885                    format!("Unexpected secret key found in {:?} packet", tag)
2886                ).into());
2887            }
2888        } else if tag == Tag::SecretKey || tag == Tag::SecretSubkey {
2889            return php.error(Error::MalformedPacket(
2890                format!("Expected secret key in {:?} packet", tag)
2891            ).into());
2892        }
2893
2894        fn k<R>(creation_time: u32,
2895                pk_algo: PublicKeyAlgorithm,
2896                mpis: PublicKey)
2897            -> Result<Key4<key::PublicParts, R>>
2898            where R: key::KeyRole
2899        {
2900            Key4::make(creation_time.into(), pk_algo, mpis, None)
2901        }
2902        fn s<R>(creation_time: u32,
2903                pk_algo: PublicKeyAlgorithm,
2904                mpis: PublicKey,
2905                secret: SecretKeyMaterial)
2906            -> Result<Key4<key::SecretParts, R>>
2907            where R: key::KeyRole
2908        {
2909            Key4::make(creation_time.into(), pk_algo, mpis, Some(secret))
2910        }
2911
2912        let tag = php.header.ctb().tag();
2913
2914        let p : Packet = match tag {
2915            // For the benefit of Key::from_bytes.
2916            Tag::Reserved => if have_secret {
2917                Packet::SecretKey(
2918                    php_try!(s(creation_time, pk_algo, mpis, secret.unwrap()))
2919                        .into())
2920            } else {
2921                Packet::PublicKey(
2922                    php_try!(k(creation_time, pk_algo, mpis)).into())
2923            },
2924            Tag::PublicKey => Packet::PublicKey(
2925                php_try!(k(creation_time, pk_algo, mpis)).into()),
2926            Tag::PublicSubkey => Packet::PublicSubkey(
2927                php_try!(k(creation_time, pk_algo, mpis)).into()),
2928            Tag::SecretKey => Packet::SecretKey(
2929                php_try!(s(creation_time, pk_algo, mpis, secret.unwrap()))
2930                    .into()),
2931            Tag::SecretSubkey => Packet::SecretSubkey(
2932                php_try!(s(creation_time, pk_algo, mpis, secret.unwrap()))
2933                    .into()),
2934            _ => unreachable!(),
2935        };
2936
2937        php.ok(p)
2938    }
2939
2940    /// Returns whether the data appears to be a version 4 key (no
2941    /// promises).
2942    fn plausible<C>(bio: &mut dyn BufferedReader<C>, _: &Header)
2943                    -> Result<()>
2944    where
2945        C: fmt::Debug + Send + Sync,
2946    {
2947        // Make sure we have a minimum header.
2948        let data = bio.data(6)?;
2949        if data.len() < 6 {
2950            return Err(
2951                Error::MalformedPacket("Short read".into()).into());
2952        }
2953
2954        // Assume unknown == bad.
2955        let version = data[0];
2956        let pk_algo : PublicKeyAlgorithm = data[5].into();
2957
2958        if version == 4 && !matches!(pk_algo, PublicKeyAlgorithm::Unknown(_)) {
2959            Ok(())
2960        } else {
2961            Err(Error::MalformedPacket("Invalid or unsupported data".into())
2962                .into())
2963        }
2964    }
2965}
2966
2967// Key6::parse doesn't actually use the Key6 type parameters.  So, we
2968// can just set them to anything.  This avoids the caller having to
2969// set them to something.
2970impl Key6<key::UnspecifiedParts, key::UnspecifiedRole>
2971{
2972    /// Parses the body of a public key, public subkey, secret key or
2973    /// secret subkey packet.
2974    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
2975        tracer!(TRACE, "Key6::parse", php.recursion_depth());
2976        make_php_try!(php);
2977        let tag = php.header.ctb().tag();
2978        assert!(tag == Tag::Reserved
2979                || tag == Tag::PublicKey
2980                || tag == Tag::PublicSubkey
2981                || tag == Tag::SecretKey
2982                || tag == Tag::SecretSubkey);
2983
2984        let creation_time = php_try!(php.parse_be_u32("creation_time"));
2985        let pk_algo: PublicKeyAlgorithm = php_try!(php.parse_u8("pk_algo")).into();
2986
2987        let public_len = php_try!(php.parse_be_u32("public_len"));
2988        let public_mpis =
2989            php.variable_sized_field_start("public_mpis", public_len);
2990        let mpis = php_try!(PublicKey::_parse(pk_algo, &mut php));
2991        php_try!(php.variable_sized_field_end(public_mpis));
2992
2993        let secret = if let Ok(s2k_usage) = php.parse_u8("s2k_usage") {
2994            use crypto::mpi;
2995            let sec = match s2k_usage {
2996                // Unencrypted secrets.
2997                0 => {
2998                    let sec = php_try!(
2999                        mpi::SecretKeyMaterial::_parse(
3000                            pk_algo, &mut php, None));
3001                    sec.into()
3002                },
3003
3004                // Encrypted & MD5 for key derivation: unsupported.
3005                //
3006                // XXX: Technically, we could/should parse them, then
3007                // fail later.  But, this limitation has been with us
3008                // since the beginning, and no-one complained.
3009                1..=252 => {
3010                    return php.fail("unsupported secret key encryption");
3011                },
3012
3013                // AEAD encrypted secrets.
3014                253 => {
3015                    let parameters_len =
3016                        php_try!(php.parse_u8("parameters_len"));
3017                    let parameters =
3018                        php.variable_sized_field_start("parameters",
3019                                                       parameters_len);
3020                    let sym_algo: SymmetricAlgorithm =
3021                        php_try!(php.parse_u8("sym_algo")).into();
3022
3023                    let aead_algo: AEADAlgorithm =
3024                        php_try!(php.parse_u8("aead_algo")).into();
3025
3026                    let s2k_len = php_try!(php.parse_u8("s2k_len"));
3027                    let s2k_params =
3028                        php.variable_sized_field_start("s2k_params", s2k_len);
3029                    let s2k = php_try!(S2K::parse_v6(&mut php, s2k_len as _));
3030                    php_try!(php.variable_sized_field_end(s2k_params));
3031
3032                    let aead_iv = php_try!(php.parse_bytes(
3033                        "aead_iv",
3034                        php.variable_sized_field_remaining(&parameters)))
3035                        .into();
3036                    php_try!(php.variable_sized_field_end(parameters));
3037
3038                    let cipher =
3039                        php_try!(php.parse_bytes_eof("encrypted_mpis"))
3040                        .into_boxed_slice();
3041
3042                    crate::packet::key::Encrypted::new_aead(
3043                        s2k, sym_algo, aead_algo, aead_iv, cipher).into()
3044                },
3045
3046                // Encrypted secrets.
3047                254 | 255 => {
3048                    let parameters_len =
3049                        php_try!(php.parse_u8("parameters_len"));
3050                    let parameters =
3051                        php.variable_sized_field_start("parameters",
3052                                                       parameters_len);
3053                    let sym_algo: SymmetricAlgorithm =
3054                        php_try!(php.parse_u8("sym_algo")).into();
3055
3056                    let s2k_len = php_try!(php.parse_u8("s2k_len"));
3057                    let s2k_params =
3058                        php.variable_sized_field_start("s2k_params", s2k_len);
3059                    let s2k = php_try!(S2K::parse_v6(&mut php, s2k_len as _));
3060                    php_try!(php.variable_sized_field_end(s2k_params));
3061
3062                    // The "IV" is part of the sized parameter field.
3063                    let cfb_iv = php_try!(php.parse_bytes(
3064                        "cfb_iv",
3065                        php.variable_sized_field_remaining(&parameters)));
3066                    php_try!(php.variable_sized_field_end(parameters));
3067
3068                    let cipher =
3069                        php_try!(php.parse_bytes_eof("encrypted_mpis"));
3070
3071                    // But we store "IV" and ciphertext as one.
3072                    let cfb_iv_len = cfb_iv.len();
3073                    let mut combined_ciphertext = cfb_iv;
3074                    combined_ciphertext.extend_from_slice(&cipher);
3075
3076                    crate::packet::key::Encrypted::new_raw(
3077                        s2k, sym_algo,
3078                        if s2k_usage == 254 {
3079                            Some(mpi::SecretKeyChecksum::SHA1)
3080                        } else {
3081                            Some(mpi::SecretKeyChecksum::Sum16)
3082                        },
3083                        Ok((cfb_iv_len, combined_ciphertext.into())))
3084                        .into()
3085                },
3086            };
3087
3088            Some(sec)
3089        } else {
3090            None
3091        };
3092
3093        let have_secret = secret.is_some();
3094        if have_secret {
3095            if tag == Tag::PublicKey || tag == Tag::PublicSubkey {
3096                return php.error(Error::MalformedPacket(
3097                    format!("Unexpected secret key found in {:?} packet", tag)
3098                ).into());
3099            }
3100        } else if tag == Tag::SecretKey || tag == Tag::SecretSubkey {
3101            return php.error(Error::MalformedPacket(
3102                format!("Expected secret key in {:?} packet", tag)
3103            ).into());
3104        }
3105
3106        fn k<R>(creation_time: u32,
3107                pk_algo: PublicKeyAlgorithm,
3108                mpis: PublicKey)
3109            -> Result<Key6<key::PublicParts, R>>
3110            where R: key::KeyRole
3111        {
3112            Key6::make(creation_time.into(), pk_algo, mpis, None)
3113        }
3114        fn s<R>(creation_time: u32,
3115                pk_algo: PublicKeyAlgorithm,
3116                mpis: PublicKey,
3117                secret: SecretKeyMaterial)
3118            -> Result<Key6<key::SecretParts, R>>
3119            where R: key::KeyRole
3120        {
3121            Key6::make(creation_time.into(), pk_algo, mpis, Some(secret))
3122        }
3123
3124        let tag = php.header.ctb().tag();
3125
3126        let p : Packet = match tag {
3127            // For the benefit of Key::from_bytes.
3128            Tag::Reserved => if have_secret {
3129                Packet::SecretKey(
3130                    php_try!(s(creation_time, pk_algo, mpis, secret.unwrap()))
3131                        .into())
3132            } else {
3133                Packet::PublicKey(
3134                    php_try!(k(creation_time, pk_algo, mpis)).into())
3135            },
3136            Tag::PublicKey => Packet::PublicKey(
3137                php_try!(k(creation_time, pk_algo, mpis)).into()),
3138            Tag::PublicSubkey => Packet::PublicSubkey(
3139                php_try!(k(creation_time, pk_algo, mpis)).into()),
3140            Tag::SecretKey => Packet::SecretKey(
3141                php_try!(s(creation_time, pk_algo, mpis, secret.unwrap()))
3142                    .into()),
3143            Tag::SecretSubkey => Packet::SecretSubkey(
3144                php_try!(s(creation_time, pk_algo, mpis, secret.unwrap()))
3145                    .into()),
3146            _ => unreachable!(),
3147        };
3148
3149        php.ok(p)
3150    }
3151
3152    /// Returns whether the data appears to be a version 6 key (no
3153    /// promises).
3154    fn plausible<C>(bio: &mut dyn BufferedReader<C>, header: &Header)
3155                    -> Result<()>
3156    where
3157        C: fmt::Debug + Send + Sync,
3158    {
3159        // Make sure we have a minimum header.
3160        const MIN: usize = 10;
3161        let data = bio.data(MIN)?;
3162        if data.len() < MIN {
3163            return Err(
3164                Error::MalformedPacket("Short read".into()).into());
3165        }
3166
3167        // Assume unknown == bad.
3168        let version = data[0];
3169        let creation_time =
3170            u32::from_be_bytes(data[1..5].try_into().unwrap());
3171        let pk_algo: PublicKeyAlgorithm = data[5].into();
3172        let public_len =
3173            u32::from_be_bytes(data[6..10].try_into().unwrap());
3174
3175        /// The unix time at which RFC9580 was published, 2024-07-31.
3176        const RFC9580_PUBLICATION_TIME: u32 = 1722376800;
3177
3178        if version == 6
3179            && !matches!(pk_algo, PublicKeyAlgorithm::Unknown(_))
3180            && creation_time >= RFC9580_PUBLICATION_TIME
3181            && match header.length() {
3182                BodyLength::Full(len) => public_len < *len,
3183                _ => false,
3184            }
3185        {
3186            Ok(())
3187        } else {
3188            Err(Error::MalformedPacket("Invalid or unsupported data".into())
3189                .into())
3190        }
3191    }
3192}
3193
3194use key::UnspecifiedKey;
3195impl_parse_with_buffered_reader!(
3196    UnspecifiedKey,
3197    |br| -> Result<Self> {
3198        let parser = PacketHeaderParser::new_naked(br);
3199
3200        let mut pp = Self::parse(parser)?;
3201        pp.buffer_unread_content()?;
3202
3203        match pp.next()? {
3204            (Packet::PublicKey(o), PacketParserResult::EOF(_)) => Ok(o.into()),
3205            (Packet::PublicSubkey(o), PacketParserResult::EOF(_)) => Ok(o.into()),
3206            (Packet::SecretKey(o), PacketParserResult::EOF(_)) => Ok(o.into()),
3207            (Packet::SecretSubkey(o), PacketParserResult::EOF(_)) => Ok(o.into()),
3208            (Packet::Unknown(u), PacketParserResult::EOF(_)) =>
3209                Err(u.into_error()),
3210            (p, PacketParserResult::EOF(_)) =>
3211                Err(Error::InvalidOperation(
3212                    format!("Not a Key packet: {:?}", p)).into()),
3213            (_, PacketParserResult::Some(_)) =>
3214                Err(Error::InvalidOperation(
3215                    "Excess data after packet".into()).into()),
3216        }
3217    });
3218
3219impl Trust {
3220    /// Parses the body of a trust packet.
3221    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
3222        tracer!(TRACE, "Trust::parse", php.recursion_depth());
3223        make_php_try!(php);
3224        let value = php_try!(php.parse_bytes_eof("value"));
3225        php.ok(Packet::Trust(Trust::from(value)))
3226    }
3227}
3228
3229impl_parse_with_buffered_reader!(Trust);
3230
3231impl UserID {
3232    /// Parses the body of a user id packet.
3233    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
3234        tracer!(TRACE, "UserID::parse", php.recursion_depth());
3235        make_php_try!(php);
3236
3237        let value = php_try!(php.parse_bytes_eof("value"));
3238
3239        php.ok(Packet::UserID(UserID::from(value)))
3240    }
3241}
3242
3243impl_parse_with_buffered_reader!(UserID);
3244
3245impl UserAttribute {
3246    /// Parses the body of a user attribute packet.
3247    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
3248        tracer!(TRACE, "UserAttribute::parse", php.recursion_depth());
3249        make_php_try!(php);
3250
3251        let value = php_try!(php.parse_bytes_eof("value"));
3252
3253        php.ok(Packet::UserAttribute(UserAttribute::from(value)))
3254    }
3255}
3256
3257impl_parse_with_buffered_reader!(UserAttribute);
3258
3259impl Marker {
3260    /// Parses the body of a marker packet.
3261    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser>
3262    {
3263        tracer!(TRACE, "Marker::parse", php.recursion_depth());
3264        make_php_try!(php);
3265        let marker = php_try!(php.parse_bytes("marker", Marker::BODY.len()));
3266        if &marker[..] == Marker::BODY {
3267            php.ok(Marker::default().into())
3268        } else {
3269            php.fail("invalid marker")
3270        }
3271    }
3272
3273    /// Returns whether the data is a marker packet.
3274    fn plausible(bio: &mut dyn BufferedReader<Cookie>, header: &Header)
3275                    -> Result<()>
3276    {
3277        if let BodyLength::Full(len) = header.length() {
3278            let len = *len;
3279            if len as usize != Marker::BODY.len() {
3280                return Err(Error::MalformedPacket(
3281                    format!("Unexpected packet length {}", len)).into());
3282            }
3283        } else {
3284            return Err(Error::MalformedPacket(
3285                format!("Unexpected body length encoding: {:?}",
3286                        header.length())).into());
3287        }
3288
3289        // Check the body.
3290        let data = bio.data(Marker::BODY.len())?;
3291        if data.len() < Marker::BODY.len() {
3292            return Err(Error::MalformedPacket("Short read".into()).into());
3293        }
3294
3295        if data == Marker::BODY {
3296            Ok(())
3297        } else {
3298            Err(Error::MalformedPacket("Invalid or unsupported data".into())
3299                .into())
3300        }
3301    }
3302}
3303
3304impl_parse_with_buffered_reader!(Marker);
3305
3306impl Literal {
3307    /// Parses the body of a literal packet.
3308    ///
3309    /// Condition: Hashing has been disabled by the callee.
3310    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser>
3311    {
3312        tracer!(TRACE, "Literal::parse", php.recursion_depth());
3313        make_php_try!(php);
3314
3315        // Directly hashing a literal data packet is... strange.
3316        // Neither the packet's header, the packet's meta-data nor the
3317        // length encoding information is included in the hash.
3318
3319        let format = php_try!(php.parse_u8("format"));
3320        let filename_len = php_try!(php.parse_u8("filename_len"));
3321
3322        let filename = if filename_len > 0 {
3323            Some(php_try!(php.parse_bytes("filename", filename_len as usize)))
3324        } else {
3325            None
3326        };
3327
3328        let date = php_try!(php.parse_be_u32("date"));
3329
3330        // The header is consumed while hashing is disabled.
3331        let recursion_depth = php.recursion_depth();
3332
3333        let mut literal = Literal::new(format.into());
3334        if let Some(filename) = filename {
3335            literal.set_filename(&filename)
3336                .expect("length checked above");
3337        }
3338        literal.set_date(
3339            Some(std::time::SystemTime::from(Timestamp::from(date))))?;
3340        let mut pp = php.ok(Packet::Literal(literal))?;
3341
3342        // Enable hashing of the body.
3343        Cookie::hashing(pp.mut_reader(), Hashing::Enabled,
3344                        recursion_depth - 1);
3345
3346        Ok(pp)
3347    }
3348}
3349
3350impl_parse_with_buffered_reader!(Literal);
3351
3352#[test]
3353fn literal_parser_test () {
3354    use crate::types::DataFormat;
3355    {
3356        let data = crate::tests::message("literal-mode-b.pgp");
3357        let mut pp = PacketParser::from_bytes(data).unwrap().unwrap();
3358        assert_eq!(pp.header.length(), &BodyLength::Full(18));
3359        let content = pp.steal_eof().unwrap();
3360        let p = pp.finish().unwrap();
3361        // eprintln!("{:?}", p);
3362        if let &Packet::Literal(ref p) = p {
3363            assert_eq!(p.format(), DataFormat::Binary);
3364            assert_eq!(p.filename().unwrap()[..], b"foobar"[..]);
3365            assert_eq!(p.date().unwrap(), Timestamp::from(1507458744).into());
3366            assert_eq!(content, b"FOOBAR");
3367        } else {
3368            panic!("Wrong packet!");
3369        }
3370    }
3371
3372    {
3373        let data = crate::tests::message("literal-mode-t-partial-body.pgp");
3374        let mut pp = PacketParser::from_bytes(data).unwrap().unwrap();
3375        assert_eq!(pp.header.length(), &BodyLength::Partial(4096));
3376        let content = pp.steal_eof().unwrap();
3377        let p = pp.finish().unwrap();
3378        if let &Packet::Literal(ref p) = p {
3379            #[allow(deprecated)] {
3380                assert_eq!(p.format(), DataFormat::Text);
3381            }
3382            assert_eq!(p.filename().unwrap()[..],
3383                       b"manifesto.txt"[..]);
3384            assert_eq!(p.date().unwrap(), Timestamp::from(1508000649).into());
3385
3386            let expected = crate::tests::manifesto();
3387
3388            assert_eq!(&content[..], expected);
3389        } else {
3390            panic!("Wrong packet!");
3391        }
3392    }
3393}
3394
3395impl CompressedData {
3396    /// Parses the body of a compressed data packet.
3397    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
3398        let recursion_depth = php.recursion_depth();
3399        tracer!(TRACE, "CompressedData::parse", recursion_depth);
3400
3401        make_php_try!(php);
3402        let algo: CompressionAlgorithm =
3403            php_try!(php.parse_u8("algo")).into();
3404
3405        let recursion_depth = php.recursion_depth();
3406        let mut pp = php.ok(Packet::CompressedData(CompressedData::new(algo)))?;
3407
3408        #[allow(unreachable_patterns)]
3409        match algo {
3410            CompressionAlgorithm::Uncompressed => (),
3411            #[cfg(feature = "compression-deflate")]
3412            CompressionAlgorithm::Zip
3413                | CompressionAlgorithm::Zlib => (),
3414            #[cfg(feature = "compression-bzip2")]
3415            CompressionAlgorithm::BZip2 => (),
3416            _ => {
3417                // We don't know or support this algorithm.  Return a
3418                // CompressedData packet without pushing a filter, so
3419                // that it has an opaque body.
3420                t!("Algorithm {} unknown or unsupported.", algo);
3421                return Ok(pp.set_processed(false));
3422            },
3423        }
3424
3425        t!("Pushing a decompressor for {}, recursion depth = {:?}.",
3426           algo, recursion_depth);
3427
3428        let reader = pp.take_reader();
3429        let reader = match algo {
3430            CompressionAlgorithm::Uncompressed => {
3431                if TRACE {
3432                    eprintln!("CompressedData::parse(): Actually, no need \
3433                               for a compression filter: this is an \
3434                               \"uncompressed compression packet\".");
3435                }
3436                let _ = recursion_depth;
3437                reader
3438            },
3439            #[cfg(feature = "compression-deflate")]
3440            CompressionAlgorithm::Zip =>
3441                Box::new(buffered_reader::Deflate::with_cookie(
3442                    reader, Cookie::new(recursion_depth))),
3443            #[cfg(feature = "compression-deflate")]
3444            CompressionAlgorithm::Zlib =>
3445                Box::new(buffered_reader::Zlib::with_cookie(
3446                    reader, Cookie::new(recursion_depth))),
3447            #[cfg(feature = "compression-bzip2")]
3448            CompressionAlgorithm::BZip2 =>
3449                Box::new(buffered_reader::Bzip::with_cookie(
3450                    reader, Cookie::new(recursion_depth))),
3451            _ => unreachable!(), // Validated above.
3452        };
3453        pp.set_reader(reader);
3454
3455        Ok(pp)
3456    }
3457}
3458
3459impl_parse_with_buffered_reader!(CompressedData);
3460
3461#[cfg(any(feature = "compression-deflate", feature = "compression-bzip2"))]
3462#[test]
3463fn compressed_data_parser_test () {
3464    use crate::types::DataFormat;
3465
3466    let expected = crate::tests::manifesto();
3467
3468    for i in 1..4 {
3469        match CompressionAlgorithm::from(i) {
3470            #[cfg(feature = "compression-deflate")]
3471            CompressionAlgorithm::Zip | CompressionAlgorithm::Zlib => (),
3472            #[cfg(feature = "compression-bzip2")]
3473            CompressionAlgorithm::BZip2 => (),
3474            _ => continue,
3475        }
3476        let pp = PacketParser::from_bytes(crate::tests::message(
3477            &format!("compressed-data-algo-{}.pgp", i))).unwrap().unwrap();
3478
3479        // We expect a compressed packet containing a literal data
3480        // packet, and that is it.
3481        if let Packet::CompressedData(ref compressed) = pp.packet {
3482            assert_eq!(compressed.algo(), i.into());
3483        } else {
3484            panic!("Wrong packet!");
3485        }
3486
3487        let ppr = pp.recurse().unwrap().1;
3488
3489        // ppr should be the literal data packet.
3490        let mut pp = ppr.unwrap();
3491
3492        // It is a child.
3493        assert_eq!(pp.recursion_depth(), 1);
3494
3495        let content = pp.steal_eof().unwrap();
3496
3497        let (literal, ppr) = pp.recurse().unwrap();
3498
3499        if let Packet::Literal(literal) = literal {
3500            assert_eq!(literal.filename(), None);
3501            assert_eq!(literal.format(), DataFormat::Binary);
3502            assert_eq!(literal.date().unwrap(),
3503                       Timestamp::from(1509219866).into());
3504            assert_eq!(content, expected.to_vec());
3505        } else {
3506            panic!("Wrong packet!");
3507        }
3508
3509        // And, we're done...
3510        assert!(ppr.is_eof());
3511    }
3512}
3513
3514impl SKESK {
3515    /// Parses the body of an SK-ESK packet.
3516    fn parse(mut php: PacketHeaderParser)
3517             -> Result<PacketParser>
3518    {
3519        tracer!(TRACE, "SKESK::parse", php.recursion_depth());
3520        make_php_try!(php);
3521        let version = php_try!(php.parse_u8("version"));
3522        match version {
3523            4 => SKESK4::parse(php),
3524            6 => SKESK6::parse(php),
3525            _ => php.fail("unknown version"),
3526        }
3527    }
3528}
3529
3530impl SKESK4 {
3531    /// Parses the body of an SK-ESK packet.
3532    fn parse(mut php: PacketHeaderParser)
3533             -> Result<PacketParser>
3534    {
3535        tracer!(TRACE, "SKESK4::parse", php.recursion_depth());
3536        make_php_try!(php);
3537        let sym_algo = php_try!(php.parse_u8("sym_algo"));
3538        let s2k = php_try!(S2K::parse_v4(&mut php));
3539        let s2k_supported = s2k.is_supported();
3540        let esk = php_try!(php.parse_bytes_eof("esk"));
3541
3542        let skesk = php_try!(SKESK4::new_raw(
3543            sym_algo.into(),
3544            s2k,
3545            if s2k_supported || esk.is_empty() {
3546                Ok(if ! esk.is_empty() {
3547                    Some(esk.into())
3548                } else {
3549                    None
3550                })
3551            } else {
3552                Err(esk.into())
3553            },
3554        ));
3555
3556        php.ok(skesk.into())
3557    }
3558}
3559
3560impl SKESK6 {
3561    /// Parses the body of an SK-ESK packet.
3562    fn parse(mut php: PacketHeaderParser)
3563             -> Result<PacketParser>
3564    {
3565        tracer!(TRACE, "SKESK6::parse", php.recursion_depth());
3566        make_php_try!(php);
3567
3568        // Octet count of the following 5 fields.
3569        let parameter_len = php_try!(php.parse_u8_len("parameter_len"));
3570        if parameter_len < 1 + 1 + 1 + 1 /* S2K */ + 12 /* IV */ {
3571            return php.fail("expected at least 16 parameter octets");
3572        }
3573
3574        let sym_algo: SymmetricAlgorithm =
3575            php_try!(php.parse_u8("sym_algo")).into();
3576        let aead_algo: AEADAlgorithm =
3577            php_try!(php.parse_u8("aead_algo")).into();
3578
3579        // The S2K object's length and the S2K.
3580        let s2k_len = php_try!(php.parse_u8_len("s2k_len"));
3581        if parameter_len < 1 + 1 + 1 + s2k_len + 12 /* IV */ {
3582            return php.fail("S2K overflows parameter count");
3583        }
3584
3585        let s2k = php_try!(S2K::parse_v6(&mut php, s2k_len as u8));
3586
3587        // And the IV.
3588        let iv =
3589            if let Some(iv_len) = parameter_len.checked_sub(1 + 1 + 1 + s2k_len) {
3590                php_try!(php.parse_bytes("iv", iv_len as usize)).into()
3591            } else {
3592                return php.fail("IV overflows parameter count");
3593            };
3594
3595        // Finally, the ESK including the AEAD tag.
3596        let esk = php_try!(php.parse_bytes_eof("esk")).into();
3597
3598        let skesk = php_try!(SKESK6::new(
3599            sym_algo,
3600            aead_algo,
3601            s2k,
3602            iv,
3603            esk,
3604        ));
3605
3606        php.ok(skesk.into())
3607    }
3608}
3609
3610impl_parse_with_buffered_reader!(SKESK);
3611
3612#[test]
3613fn skesk_parser_test() {
3614    use crate::crypto::Password;
3615    struct Test<'a> {
3616        filename: &'a str,
3617        s2k: S2K,
3618        cipher_algo: SymmetricAlgorithm,
3619        password: Password,
3620        key_hex: &'a str,
3621    }
3622
3623    let tests = [
3624        Test {
3625            filename: "s2k/mode-3-encrypted-key-password-bgtyhn.pgp",
3626            cipher_algo: SymmetricAlgorithm::AES128,
3627            s2k: S2K::Iterated {
3628                hash: HashAlgorithm::SHA1,
3629                salt: [0x82, 0x59, 0xa0, 0x6e, 0x98, 0xda, 0x94, 0x1c],
3630                hash_bytes: S2K::decode_count(238),
3631            },
3632            password: "bgtyhn".into(),
3633            key_hex: "474E5C373BA18AF0A499FCAFE6093F131DF636F6A3812B9A8AE707F1F0214AE9",
3634        },
3635    ];
3636
3637    for test in tests.iter() {
3638        let pp = PacketParser::from_bytes(
3639            crate::tests::message(test.filename)).unwrap().unwrap();
3640        if let Packet::SKESK(SKESK::V4(ref skesk)) = pp.packet {
3641            eprintln!("{:?}", skesk);
3642
3643            assert_eq!(skesk.symmetric_algo(), test.cipher_algo);
3644            assert_eq!(skesk.s2k(), &test.s2k);
3645
3646            match skesk.decrypt(&test.password) {
3647                Ok((_sym_algo, key)) => {
3648                    let key = crate::fmt::to_hex(&key[..], false);
3649                    assert_eq!(&key[..], test.key_hex);
3650                }
3651                Err(e) => {
3652                    panic!("No session key, got: {:?}", e);
3653                }
3654            }
3655        } else {
3656            panic!("Wrong packet!");
3657        }
3658    }
3659}
3660
3661impl SEIP {
3662    /// Parses the body of a SEIP packet.
3663    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
3664        tracer!(TRACE, "SEIP::parse", php.recursion_depth());
3665        make_php_try!(php);
3666        let version = php_try!(php.parse_u8("version"));
3667        match version {
3668            1 => SEIP1::parse(php),
3669            2 => SEIP2::parse(php),
3670            _ => php.fail("unknown version"),
3671        }
3672    }
3673}
3674
3675impl_parse_with_buffered_reader!(SEIP);
3676
3677impl SEIP1 {
3678    /// Parses the body of a SEIP1 packet.
3679    fn parse(php: PacketHeaderParser) -> Result<PacketParser> {
3680        php.ok(SEIP1::new().into())
3681            .map(|pp| pp.set_processed(false))
3682    }
3683}
3684
3685impl SEIP2 {
3686    /// Parses the body of a SEIP2 packet.
3687    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
3688        tracer!(TRACE, "SEIP2::parse", php.recursion_depth());
3689        make_php_try!(php);
3690        let cipher: SymmetricAlgorithm =
3691            php_try!(php.parse_u8("sym_algo")).into();
3692        let aead: AEADAlgorithm =
3693            php_try!(php.parse_u8("aead_algo")).into();
3694        let chunk_size = php_try!(php.parse_u8("chunk_size"));
3695
3696        // An implementation MUST accept chunk size octets with values
3697        // from 0 to 16. An implementation MUST NOT create data with a
3698        // chunk size octet value larger than 16 (4 MiB chunks).
3699        if chunk_size > 16 {
3700            return php.fail("unsupported chunk size");
3701        }
3702        let chunk_size: u64 = 1 << (chunk_size + 6);
3703        let salt_v = php_try!(php.parse_bytes("salt", 32));
3704        let mut salt = [0u8; 32];
3705        salt.copy_from_slice(&salt_v);
3706
3707        let seip2 = php_try!(Self::new(cipher, aead, chunk_size, salt));
3708        php.ok(seip2.into()).map(|pp| pp.set_processed(false))
3709    }
3710}
3711
3712impl MDC {
3713    /// Parses the body of an MDC packet.
3714    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
3715        tracer!(TRACE, "MDC::parse", php.recursion_depth());
3716        make_php_try!(php);
3717
3718        // Find the HashedReader pushed by the containing SEIP packet.
3719        // In a well-formed message, this will be the outermost
3720        // HashedReader on the BufferedReader stack: we pushed it
3721        // there when we started decrypting the SEIP packet, and an
3722        // MDC packet is the last packet in a SEIP container.
3723        // Nevertheless, we take some basic precautions to check
3724        // whether it is really the matching HashedReader.
3725
3726        let mut computed_digest : [u8; 20] = Default::default();
3727        {
3728            let mut r : Option<&mut dyn BufferedReader<Cookie>>
3729                = Some(&mut php.reader);
3730            while let Some(bio) = r {
3731                {
3732                    let state = bio.cookie_mut();
3733                    if state.hashes_for == HashesFor::MDC {
3734                        if !state.sig_group().hashes.is_empty() {
3735                            let h = state.sig_group_mut().hashes
3736                                .iter_mut().find_map(
3737                                    |mode|
3738                                    if matches!(mode.map(|ctx| ctx.algo()),
3739                                        HashingMode::Binary(_, HashAlgorithm::SHA1))
3740                                    {
3741                                        Some(mode.as_mut())
3742                                    } else {
3743                                        None
3744                                    }).unwrap();
3745                            let _ = h.digest(&mut computed_digest);
3746                        }
3747
3748                        // If the outermost HashedReader is not the
3749                        // matching HashedReader, then the message is
3750                        // malformed.
3751                        break;
3752                    }
3753                }
3754
3755                r = bio.get_mut();
3756            }
3757        }
3758
3759        let mut digest: [u8; 20] = Default::default();
3760        digest.copy_from_slice(&php_try!(php.parse_bytes("digest", 20)));
3761
3762        #[allow(deprecated)]
3763        php.ok(Packet::MDC(MDC::new(digest, computed_digest)))
3764    }
3765}
3766
3767impl_parse_with_buffered_reader!(MDC);
3768
3769impl Padding {
3770    /// Parses the body of a padding packet.
3771    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
3772        tracer!(TRACE, "Padding::parse", php.recursion_depth());
3773        make_php_try!(php);
3774        // XXX: I don't think we should capture the body.
3775        let value = php_try!(php.parse_bytes_eof("value"));
3776        php.ok(Packet::Padding(Padding::from(value)))
3777    }
3778}
3779
3780impl_parse_with_buffered_reader!(Padding);
3781
3782impl MPI {
3783    /// Parses an OpenPGP MPI.
3784    ///
3785    /// See [Section 3.2 of RFC 9580] for details.
3786    ///
3787    ///   [Section 3.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3.2
3788    fn parse(name_len: &'static str,
3789             name: &'static str,
3790             php: &mut PacketHeaderParser<'_>) -> Result<Self> {
3791        Ok(MPI::parse_common(name_len, name, false, false, php)?.into())
3792    }
3793
3794    /// Parses an OpenPGP MPI.
3795    ///
3796    /// If `parsing_secrets` is `true`, errors are normalized as not
3797    /// to reveal parts of the plaintext to the caller.
3798    ///
3799    /// If `lenient_parsing` is `true`, this function will accept MPIs
3800    /// that are not well-formed (notably, issues related to leading
3801    /// zeros).
3802    fn parse_common(
3803        name_len: &'static str,
3804        name: &'static str,
3805        parsing_secrets: bool,
3806        lenient_parsing: bool,
3807        php: &mut PacketHeaderParser<'_>)
3808                 -> Result<Vec<u8>> {
3809        // When we are parsing secrets, we don't want to leak it
3810        // accidentally by revealing it in error messages, or indeed
3811        // by the kind of error.
3812        //
3813        // All errors returned by this function that are depend on
3814        // secret data must be uniform and return the following error.
3815        // We make an exception for i/o errors, which may reveal
3816        // truncation, because swallowing i/o errors may be very
3817        // confusing when diagnosing errors, and we don't consider the
3818        // length of the value to be confidential as it can also be
3819        // inferred from the size of the ciphertext.
3820        let uniform_error_for_secrets = |e: Error| {
3821            if parsing_secrets {
3822                Err(Error::MalformedMPI("Details omitted, \
3823                                         parsing secret".into()).into())
3824            } else {
3825                Err(e.into())
3826            }
3827        };
3828
3829        // This function is used to parse MPIs from unknown
3830        // algorithms, which may use an encoding unknown to us.
3831        // Therefore, we need to be extra careful only to consume the
3832        // data once we found a well-formed MPI.
3833        let bits = {
3834            let buf = php.reader.data_hard(2)?;
3835            u16::from_be_bytes([buf[0], buf[1]]) as usize
3836        };
3837        if bits == 0 {
3838            // Now consume the data.
3839            php.parse_be_u16(name_len).expect("worked before");
3840            return Ok(vec![]);
3841        }
3842
3843        let bytes = (bits + 7) / 8;
3844        let value = {
3845            let buf = php.reader.data_hard(2 + bytes)?;
3846            Vec::from(&buf[2..2 + bytes])
3847        };
3848
3849        let unused_bits = bytes * 8 - bits;
3850        assert_eq!(bytes * 8 - unused_bits, bits);
3851
3852        // Make sure the unused bits are zeroed.
3853        if unused_bits > 0 {
3854            let mask = !((1 << (8 - unused_bits)) - 1);
3855            let unused_value = value[0] & mask;
3856
3857            if unused_value != 0 && ! lenient_parsing {
3858                return uniform_error_for_secrets(
3859                    Error::MalformedMPI(
3860                        format!("{} unused bits not zeroed: ({:x})",
3861                                unused_bits, unused_value)
3862                    ));
3863            }
3864        }
3865
3866        let first_used_bit = 8 - unused_bits;
3867        if value[0] & (1 << (first_used_bit - 1)) == 0 && ! lenient_parsing {
3868            return uniform_error_for_secrets(
3869                Error::MalformedMPI(
3870                    format!("leading bit is not set: \
3871                             expected bit {} to be set in {:8b} ({:x})",
3872                            first_used_bit, value[0], value[0])
3873                ));
3874        }
3875
3876        // Now consume the data.  Note: we avoid using parse_bytes
3877        // here because MPIs may contain secrets, and we don't want to
3878        // casually leak them into the heap.  Also, we avoid doing a
3879        // heap allocation.
3880        php.reader.consume(2 + bytes);
3881        // Now fix the map.
3882        php.field(name_len, 2);
3883        php.field(name, bytes);
3884
3885        Ok(value)
3886    }
3887}
3888
3889impl_parse_with_buffered_reader!(
3890    MPI,
3891    |bio: Box<dyn BufferedReader<Cookie>>| -> Result<Self> {
3892        let mut parser = PacketHeaderParser::new_naked(bio.into_boxed());
3893        Self::parse("(none_len)", "(none)", &mut parser)
3894    });
3895
3896impl ProtectedMPI {
3897    /// Parses an OpenPGP MPI containing secrets.
3898    ///
3899    /// See [Section 3.2 of RFC 9580] for details.
3900    ///
3901    ///   [Section 3.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3.2
3902    fn parse(name_len: &'static str,
3903             name: &'static str,
3904             php: &mut PacketHeaderParser<'_>) -> Result<Self> {
3905        // XXX: While lenient parsing seemed like the right thing to
3906        // do, this breaks equality and round-tripping: we normalize
3907        // the non-canonical encoding, so two distinct wire
3908        // representations are folded into one in-core representation.
3909        Ok(MPI::parse_common(name_len, name, true, false, php)?.into())
3910    }
3911}
3912impl PKESK {
3913    /// Parses the body of an PK-ESK packet.
3914    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
3915        tracer!(TRACE, "PKESK::parse", php.recursion_depth());
3916        make_php_try!(php);
3917        let version = php_try!(php.parse_u8("version"));
3918        match version {
3919            3 => PKESK3::parse(php),
3920            6 => PKESK6::parse(php),
3921            _ => php.fail("unknown version"),
3922        }
3923    }
3924}
3925
3926impl_parse_with_buffered_reader!(PKESK);
3927
3928impl PKESK3 {
3929    /// Parses the body of an PK-ESK packet.
3930    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
3931        tracer!(TRACE, "PKESK3::parse", php.recursion_depth());
3932        make_php_try!(php);
3933
3934        let keyid = {
3935            let mut keyid = [0u8; 8];
3936            keyid.copy_from_slice(&php_try!(php.parse_bytes("keyid", 8)));
3937
3938            let keyid = KeyID::from_bytes(&keyid);
3939            if keyid.is_wildcard() {
3940                None
3941            } else {
3942                Some(keyid)
3943            }
3944        };
3945
3946        let pk_algo: PublicKeyAlgorithm = php_try!(php.parse_u8("pk_algo")).into();
3947        if ! pk_algo.for_encryption() {
3948            return php.fail("not an encryption algorithm");
3949        }
3950        let mpis = crypto::mpi::Ciphertext::_parse(pk_algo, &mut php)?;
3951
3952        let pkesk = php_try!(PKESK3::new(keyid, pk_algo, mpis));
3953        php.ok(pkesk.into())
3954    }
3955}
3956
3957impl_parse_with_buffered_reader!(
3958    PKESK3,
3959    |reader| -> Result<Self> {
3960        PKESK::from_buffered_reader(reader).and_then(|p| match p {
3961            PKESK::V3(p) => Ok(p),
3962            p => Err(Error::InvalidOperation(
3963                 format!("Not a PKESKv3 packet: {:?}", p)).into()),
3964        })
3965    });
3966
3967impl PKESK6 {
3968    /// Parses the body of an PKESKv6 packet.
3969    fn parse(mut php: PacketHeaderParser) -> Result<PacketParser> {
3970        tracer!(TRACE, "PKESK6::parse", php.recursion_depth());
3971        make_php_try!(php);
3972        let fp_len = php_try!(php.parse_u8("recipient_len"));
3973        let fingerprint = if fp_len == 0 {
3974            None
3975        } else {
3976            // Get the version and sanity check the length.
3977            let fp_version = php_try!(php.parse_u8("recipient_version"));
3978            if let Some(expected_length) = match fp_version {
3979                4 => Some(20),
3980                6 => Some(32),
3981                _ => None,
3982            } {
3983                if fp_len - 1 != expected_length {
3984                    return php.fail("bad fingerprint length");
3985                }
3986            }
3987            Some(Fingerprint::from_bytes(
3988                fp_version,
3989                &php_try!(php.parse_bytes("recipient", (fp_len - 1).into())))?)
3990        };
3991
3992        let pk_algo: PublicKeyAlgorithm =
3993            php_try!(php.parse_u8("pk_algo")).into();
3994        if ! pk_algo.for_encryption() { // XXX
3995            return php.fail("not an encryption algorithm");
3996        }
3997        let mpis = crypto::mpi::Ciphertext::_parse(pk_algo, &mut php)?;
3998
3999        let pkesk = php_try!(PKESK6::new(fingerprint, pk_algo, mpis));
4000        php.ok(pkesk.into())
4001    }
4002}
4003
4004impl_parse_with_buffered_reader!(
4005    PKESK6,
4006    |reader| -> Result<Self> {
4007        PKESK::from_buffered_reader(reader).and_then(|p| match p {
4008            PKESK::V6(p) => Ok(p),
4009            p => Err(Error::InvalidOperation(
4010                 format!("Not a PKESKv6 packet: {:?}", p)).into()),
4011        })
4012    });
4013
4014impl_parse_with_buffered_reader!(
4015    Packet,
4016    |br| -> Result<Self> {
4017        let ppr =
4018            PacketParserBuilder::from_buffered_reader(br)
4019            ?.buffer_unread_content().build()?;
4020
4021        let (p, ppr) = match ppr {
4022            PacketParserResult::Some(pp) => {
4023                pp.next()?
4024            },
4025            PacketParserResult::EOF(_) =>
4026                return Err(Error::InvalidOperation(
4027                    "Unexpected EOF".into()).into()),
4028        };
4029
4030        match (p, ppr) {
4031            (p, PacketParserResult::EOF(_)) =>
4032                Ok(p),
4033            (_, PacketParserResult::Some(_)) =>
4034                Err(Error::InvalidOperation(
4035                    "Excess data after packet".into()).into()),
4036        }
4037    });
4038
4039// State that lives for the life of the packet parser, not the life of
4040// an individual packet.
4041#[derive(Debug)]
4042struct PacketParserState {
4043    // The `PacketParser`'s settings
4044    settings: PacketParserSettings,
4045
4046    /// Whether the packet sequence is a valid OpenPGP Message.
4047    message_validator: MessageValidator,
4048
4049    /// Whether the packet sequence is a valid OpenPGP keyring.
4050    keyring_validator: KeyringValidator,
4051
4052    /// Whether the packet sequence is a valid OpenPGP Cert.
4053    cert_validator: CertValidator,
4054
4055    // Whether this is the first packet in the packet sequence.
4056    first_packet: bool,
4057
4058    // Whether PacketParser::parse encountered an unrecoverable error.
4059    pending_error: Option<anyhow::Error>,
4060}
4061
4062impl PacketParserState {
4063    fn new(settings: PacketParserSettings) -> Self {
4064        PacketParserState {
4065            settings,
4066            message_validator: Default::default(),
4067            keyring_validator: Default::default(),
4068            cert_validator: Default::default(),
4069            first_packet: true,
4070            pending_error: None,
4071        }
4072    }
4073}
4074
4075/// A low-level OpenPGP message parser.
4076///
4077/// A `PacketParser` provides a low-level, iterator-like interface to
4078/// parse OpenPGP messages.
4079///
4080/// For each iteration, the user is presented with a [`Packet`]
4081/// corresponding to the last packet, a `PacketParser` for the next
4082/// packet, and their positions within the message.
4083///
4084/// Using the `PacketParser`, the user is able to configure how the
4085/// new packet will be parsed.  For instance, it is possible to stream
4086/// the packet's contents (a `PacketParser` implements the
4087/// [`std::io::Read`] and the [`BufferedReader`] traits), buffer them
4088/// within the [`Packet`], or drop them.  The user can also decide to
4089/// recurse into the packet, if it is a container, instead of getting
4090/// the following packet.
4091///
4092/// See the [`PacketParser::next`] and [`PacketParser::recurse`]
4093/// methods for more details.
4094///
4095///   [`Packet`]: super::Packet
4096///   [`BufferedReader`]: https://docs.rs/buffered-reader/*/buffered_reader/trait.BufferedReader.html
4097///   [`PacketParser::next`]: PacketParser::next()
4098///   [`PacketParser::recurse`]: PacketParser::recurse()
4099///
4100/// # Examples
4101///
4102/// These examples demonstrate how to process packet bodies by parsing
4103/// the simplest possible OpenPGP message containing just a single
4104/// literal data packet with the body "Hello world.".  There are three
4105/// options.  First, the body can be dropped.  Second, it can be
4106/// buffered.  Lastly, the body can be streamed.  In general,
4107/// streaming should be preferred, because it avoids buffering in
4108/// Sequoia.
4109///
4110/// This example demonstrates simply ignoring the packet body:
4111///
4112/// ```rust
4113/// # fn main() -> sequoia_openpgp::Result<()> {
4114/// use sequoia_openpgp as openpgp;
4115/// use openpgp::Packet;
4116/// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4117///
4118/// // By default, the `PacketParser` will drop packet bodies.
4119/// let mut ppr =
4120///     PacketParser::from_bytes(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.")?;
4121/// while let PacketParserResult::Some(pp) = ppr {
4122///     // Get the packet out of the parser and start parsing the next
4123///     // packet, recursing.
4124///     let (packet, next_ppr) = pp.recurse()?;
4125///     ppr = next_ppr;
4126///
4127///     // Process the packet.
4128///     if let Packet::Literal(literal) = packet {
4129///         // The body was dropped.
4130///         assert_eq!(literal.body(), b"");
4131///     } else {
4132///         unreachable!("We know it is a literal packet.");
4133///     }
4134/// }
4135/// # Ok(()) }
4136/// ```
4137///
4138/// This example demonstrates how the body can be buffered by
4139/// configuring the `PacketParser` to buffer all packet bodies:
4140///
4141/// ```rust
4142/// # fn main() -> sequoia_openpgp::Result<()> {
4143/// use sequoia_openpgp as openpgp;
4144/// use openpgp::Packet;
4145/// use openpgp::parse::{Parse, PacketParserResult, PacketParserBuilder};
4146///
4147/// // By default, the `PacketParser` will drop packet bodies.  Use a
4148/// // `PacketParserBuilder` to change that.
4149/// let mut ppr =
4150///     PacketParserBuilder::from_bytes(
4151///         b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.")?
4152///     .buffer_unread_content()
4153///     .build()?;
4154/// while let PacketParserResult::Some(pp) = ppr {
4155///     // Get the packet out of the parser and start parsing the next
4156///     // packet, recursing.
4157///     let (packet, next_ppr) = pp.recurse()?;
4158///     ppr = next_ppr;
4159///
4160///     // Process the packet.
4161///     if let Packet::Literal(literal) = packet {
4162///         // The body was buffered.
4163///         assert_eq!(literal.body(), b"Hello world.");
4164///     } else {
4165///         unreachable!("We know it is a literal packet.");
4166///     }
4167/// }
4168/// # Ok(()) }
4169/// ```
4170///
4171/// This example demonstrates how the body can be buffered by
4172/// buffering an individual packet:
4173///
4174/// ```rust
4175/// # fn main() -> sequoia_openpgp::Result<()> {
4176/// use sequoia_openpgp as openpgp;
4177/// use openpgp::Packet;
4178/// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4179///
4180/// // By default, the `PacketParser` will drop packet bodies.
4181/// let mut ppr =
4182///     PacketParser::from_bytes(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.")?;
4183/// while let PacketParserResult::Some(mut pp) = ppr {
4184///     if let Packet::Literal(_) = pp.packet {
4185///         // Buffer this packet's body.
4186///         pp.buffer_unread_content()?;
4187///     }
4188///
4189///     // Get the packet out of the parser and start parsing the next
4190///     // packet, recursing.
4191///     let (packet, next_ppr) = pp.recurse()?;
4192///     ppr = next_ppr;
4193///
4194///     // Process the packet.
4195///     if let Packet::Literal(literal) = packet {
4196///         // The body was buffered.
4197///         assert_eq!(literal.body(), b"Hello world.");
4198///     } else {
4199///         unreachable!("We know it is a literal packet.");
4200///     }
4201/// }
4202/// # Ok(()) }
4203/// ```
4204///
4205/// This example demonstrates how to stream the packet body:
4206///
4207/// ```rust
4208/// # fn main() -> sequoia_openpgp::Result<()> {
4209/// use std::io::Read;
4210///
4211/// use sequoia_openpgp as openpgp;
4212/// use openpgp::Packet;
4213/// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4214///
4215/// let mut ppr =
4216///     PacketParser::from_bytes(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.")?;
4217/// while let PacketParserResult::Some(mut pp) = ppr {
4218///     if let Packet::Literal(_) = pp.packet {
4219///         // Stream the body.
4220///         let mut buf = Vec::new();
4221///         pp.read_to_end(&mut buf)?;
4222///         assert_eq!(buf, b"Hello world.");
4223///     } else {
4224///         unreachable!("We know it is a literal packet.");
4225///     }
4226///
4227///     // Get the packet out of the parser and start parsing the next
4228///     // packet, recursing.
4229///     let (packet, next_ppr) = pp.recurse()?;
4230///     ppr = next_ppr;
4231///
4232///     // Process the packet.
4233///     if let Packet::Literal(literal) = packet {
4234///         // The body was streamed, not buffered.
4235///         assert_eq!(literal.body(), b"");
4236///     } else {
4237///         unreachable!("We know it is a literal packet.");
4238///     }
4239/// }
4240/// # Ok(()) }
4241/// ```
4242///
4243/// # Packet Parser Design
4244///
4245/// There are two major concerns that inform the design of the parsing
4246/// API.
4247///
4248/// First, when processing a container, it is possible to either
4249/// recurse into the container, and process its children, or treat the
4250/// contents of the container as an opaque byte stream, and process
4251/// the packet following the container.  The low-level
4252/// [`PacketParser`] and mid-level [`PacketPileParser`] abstractions
4253/// allow the caller to choose the behavior by either calling the
4254/// [`PacketParser::recurse`] method or the [`PacketParser::next`]
4255/// method, as appropriate.  OpenPGP doesn't impose any restrictions
4256/// on the amount of nesting.  So, to prevent a denial-of-service
4257/// attack, the parsers don't recurse more than
4258/// [`DEFAULT_MAX_RECURSION_DEPTH`] times, by default.
4259///
4260///
4261/// Second, packets can contain an effectively unbounded amount of
4262/// data.  To avoid errors due to memory exhaustion, the
4263/// `PacketParser` and [`PacketPileParser`] abstractions support
4264/// parsing packets in a streaming manner, i.e., never buffering more
4265/// than O(1) bytes of data.  To do this, the parsers initially only
4266/// parse a packet's header (which is rarely more than a few kilobytes
4267/// of data), and return control to the caller.  After inspecting that
4268/// data, the caller can decide how to handle the packet's contents.
4269/// If the content is deemed interesting, it can be streamed or
4270/// buffered.  Otherwise, it can be dropped.  Streaming is possible
4271/// not only for literal data packets, but also containers (other
4272/// packets also support the interface, but just return EOF).  For
4273/// instance, encryption can be stripped by saving the decrypted
4274/// content of an encryption packet, which is just an OpenPGP message.
4275///
4276/// ## Iterator Design
4277///
4278/// We explicitly chose to not use a callback-based API, but something
4279/// that is closer to Rust's iterator API.  Unfortunately, because a
4280/// `PacketParser` needs mutable access to the input stream (so that
4281/// the content can be streamed), only a single `PacketParser` item
4282/// can be live at a time (without a fair amount of unsafe nastiness).
4283/// This is incompatible with Rust's iterator concept, which allows
4284/// any number of items to be live at any time.  For instance:
4285///
4286/// ```rust
4287/// let mut v = vec![1, 2, 3, 4];
4288/// let mut iter = v.iter_mut();
4289///
4290/// let x = iter.next().unwrap();
4291/// let y = iter.next().unwrap();
4292///
4293/// *x += 10; // This does not cause an error!
4294/// *y += 10;
4295/// ```
4296pub struct PacketParser<'a> {
4297    /// The current packet's header.
4298    header: Header,
4299
4300    /// The packet that is being parsed.
4301    pub packet: Packet,
4302
4303    // The path of the packet that is currently being parsed.
4304    path: Vec<usize>,
4305    // The path of the packet that was most recently returned by
4306    // `next()` or `recurse()`.
4307    last_path: Vec<usize>,
4308
4309    reader: Box<dyn BufferedReader<Cookie> + 'a>,
4310
4311    // Whether the caller read the packet's content.  If so, then we
4312    // can't recurse, because we're missing some of the packet!
4313    content_was_read: bool,
4314
4315    // Whether PacketParser::finish has been called.
4316    finished: bool,
4317
4318    // Whether the content has been processed.
4319    processed: bool,
4320
4321    /// A map of this packet.
4322    map: Option<map::Map>,
4323
4324    /// We compute a hashsum over the body to implement comparison on
4325    /// containers that have been streamed.
4326    body_hash: Option<Box<Xxh3>>,
4327
4328    state: PacketParserState,
4329}
4330assert_send_and_sync!(PacketParser<'_>);
4331
4332impl<'a> std::fmt::Display for PacketParser<'a> {
4333    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
4334        write!(f, "PacketParser")
4335    }
4336}
4337
4338impl<'a> std::fmt::Debug for PacketParser<'a> {
4339    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
4340        f.debug_struct("PacketParser")
4341            .field("header", &self.header)
4342            .field("packet", &self.packet)
4343            .field("path", &self.path)
4344            .field("last_path", &self.last_path)
4345            .field("processed", &self.processed)
4346            .field("content_was_read", &self.content_was_read)
4347            .field("settings", &self.state.settings)
4348            .field("map", &self.map)
4349            .finish()
4350    }
4351}
4352
4353/// The return value of PacketParser::parse.
4354enum ParserResult<'a> {
4355    Success(PacketParser<'a>),
4356    EOF((Box<dyn BufferedReader<Cookie> + 'a>, PacketParserState, Vec<usize>)),
4357}
4358
4359/// Information about the stream of packets parsed by the
4360/// `PacketParser`.
4361///
4362/// Once the [`PacketParser`] reaches the end of the input stream, it
4363/// returns a [`PacketParserResult::EOF`] with a `PacketParserEOF`.
4364/// This object provides information about the parsed stream, notably
4365/// whether the packet stream was a well-formed [`Message`],
4366/// [`Cert`] or keyring.
4367///
4368///   [`Message`]: super::Message
4369///   [`Cert`]: crate::cert::Cert
4370///
4371/// # Examples
4372///
4373/// Parse some OpenPGP stream using a [`PacketParser`] and detects the
4374/// kind of data:
4375///
4376/// ```rust
4377/// # fn main() -> sequoia_openpgp::Result<()> {
4378/// use sequoia_openpgp as openpgp;
4379/// use openpgp::Packet;
4380/// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4381///
4382/// let openpgp_data: &[u8] = // ...
4383/// #    include_bytes!("../tests/data/keys/public-key.pgp");
4384/// let mut ppr = PacketParser::from_bytes(openpgp_data)?;
4385/// while let PacketParserResult::Some(mut pp) = ppr {
4386///     // Start parsing the next packet, recursing.
4387///     ppr = pp.recurse()?.1;
4388/// }
4389///
4390/// if let PacketParserResult::EOF(eof) = ppr {
4391///     if eof.is_message().is_ok() {
4392///         // ...
4393///     } else if eof.is_cert().is_ok() {
4394///         // ...
4395///     } else if eof.is_keyring().is_ok() {
4396///         // ...
4397///     } else {
4398///         // ...
4399///     }
4400/// }
4401/// # Ok(()) }
4402/// ```
4403#[derive(Debug)]
4404pub struct PacketParserEOF<'a> {
4405    state: PacketParserState,
4406    reader: Box<dyn BufferedReader<Cookie> + 'a>,
4407    last_path: Vec<usize>,
4408}
4409assert_send_and_sync!(PacketParserEOF<'_>);
4410
4411impl<'a> PacketParserEOF<'a> {
4412    /// Copies the important information in `pp` into a new
4413    /// `PacketParserEOF` instance.
4414    fn new(mut state: PacketParserState,
4415           reader: Box<dyn BufferedReader<Cookie> + 'a>)
4416           -> Self {
4417        state.message_validator.finish();
4418        state.keyring_validator.finish();
4419        state.cert_validator.finish();
4420
4421        PacketParserEOF {
4422            state,
4423            reader,
4424            last_path: vec![],
4425        }
4426    }
4427
4428    /// Creates a placeholder instance for PacketParserResult::take.
4429    fn empty() -> Self {
4430        Self::new(
4431            PacketParserState::new(Default::default()),
4432            buffered_reader::Memory::with_cookie(b"", Default::default())
4433                .into_boxed())
4434    }
4435
4436    /// Returns whether the stream is an OpenPGP Message.
4437    ///
4438    /// A [`Message`] has a very specific structure.  Returns `true`
4439    /// if the stream is of that form, as opposed to a [`Cert`] or
4440    /// just a bunch of packets.
4441    ///
4442    ///   [`Message`]: super::Message
4443    ///   [`Cert`]: crate::cert::Cert
4444    ///
4445    /// # Examples
4446    ///
4447    /// Parse some OpenPGP stream using a [`PacketParser`] and detects the
4448    /// kind of data:
4449    ///
4450    ///
4451    /// ```rust
4452    /// # fn main() -> sequoia_openpgp::Result<()> {
4453    /// use sequoia_openpgp as openpgp;
4454    /// use openpgp::Packet;
4455    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4456    ///
4457    /// let openpgp_data: &[u8] = // ...
4458    /// #    include_bytes!("../tests/data/keys/public-key.pgp");
4459    /// let mut ppr = PacketParser::from_bytes(openpgp_data)?;
4460    /// while let PacketParserResult::Some(mut pp) = ppr {
4461    ///     // Start parsing the next packet, recursing.
4462    ///     ppr = pp.recurse()?.1;
4463    /// }
4464    ///
4465    /// if let PacketParserResult::EOF(eof) = ppr {
4466    ///     if eof.is_message().is_ok() {
4467    ///         // ...
4468    ///     }
4469    /// }
4470    /// # Ok(()) }
4471    /// ```
4472    pub fn is_message(&self) -> Result<()> {
4473        use crate::message::MessageValidity;
4474
4475        match self.state.message_validator.check() {
4476            MessageValidity::Message => Ok(()),
4477            MessageValidity::MessagePrefix => unreachable!(),
4478            MessageValidity::Error(err) => Err(err),
4479        }
4480    }
4481
4482    /// Returns whether the message is an OpenPGP keyring.
4483    ///
4484    /// A keyring has a very specific structure.  Returns `true` if
4485    /// the stream is of that form, as opposed to a [`Message`] or
4486    /// just a bunch of packets.
4487    ///
4488    ///   [`Message`]: super::Message
4489    ///
4490    /// # Examples
4491    ///
4492    /// Parse some OpenPGP stream using a [`PacketParser`] and detects the
4493    /// kind of data:
4494    ///
4495    ///
4496    /// ```rust
4497    /// # fn main() -> sequoia_openpgp::Result<()> {
4498    /// use sequoia_openpgp as openpgp;
4499    /// use openpgp::Packet;
4500    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4501    ///
4502    /// let openpgp_data: &[u8] = // ...
4503    /// #    include_bytes!("../tests/data/keys/public-key.pgp");
4504    /// let mut ppr = PacketParser::from_bytes(openpgp_data)?;
4505    /// while let PacketParserResult::Some(mut pp) = ppr {
4506    ///     // Start parsing the next packet, recursing.
4507    ///     ppr = pp.recurse()?.1;
4508    /// }
4509    ///
4510    /// if let PacketParserResult::EOF(eof) = ppr {
4511    ///     if eof.is_keyring().is_ok() {
4512    ///         // ...
4513    ///     }
4514    /// }
4515    /// # Ok(()) }
4516    /// ```
4517    pub fn is_keyring(&self) -> Result<()> {
4518        match self.state.keyring_validator.check() {
4519            KeyringValidity::Keyring => Ok(()),
4520            KeyringValidity::KeyringPrefix => unreachable!(),
4521            KeyringValidity::Error(err) => Err(err),
4522        }
4523    }
4524
4525    /// Returns whether the message is an OpenPGP Cert.
4526    ///
4527    /// A [`Cert`] has a very specific structure.  Returns `true` if
4528    /// the stream is of that form, as opposed to a [`Message`] or
4529    /// just a bunch of packets.
4530    ///
4531    ///   [`Message`]: super::Message
4532    ///   [`Cert`]: crate::cert::Cert
4533    ///
4534    /// # Examples
4535    ///
4536    /// Parse some OpenPGP stream using a [`PacketParser`] and detects the
4537    /// kind of data:
4538    ///
4539    ///
4540    /// ```rust
4541    /// # fn main() -> sequoia_openpgp::Result<()> {
4542    /// use sequoia_openpgp as openpgp;
4543    /// use openpgp::Packet;
4544    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4545    ///
4546    /// let openpgp_data: &[u8] = // ...
4547    /// #    include_bytes!("../tests/data/keys/public-key.pgp");
4548    /// let mut ppr = PacketParser::from_bytes(openpgp_data)?;
4549    /// while let PacketParserResult::Some(mut pp) = ppr {
4550    ///     // Start parsing the next packet, recursing.
4551    ///     ppr = pp.recurse()?.1;
4552    /// }
4553    ///
4554    /// if let PacketParserResult::EOF(eof) = ppr {
4555    ///     if eof.is_cert().is_ok() {
4556    ///         // ...
4557    ///     }
4558    /// }
4559    /// # Ok(()) }
4560    /// ```
4561    pub fn is_cert(&self) -> Result<()> {
4562        match self.state.cert_validator.check() {
4563            CertValidity::Cert => Ok(()),
4564            CertValidity::CertPrefix => unreachable!(),
4565            CertValidity::Error(err) => Err(err),
4566        }
4567    }
4568
4569    /// Returns the path of the last packet.
4570    ///
4571    /// # Examples
4572    ///
4573    /// Parse some OpenPGP stream using a [`PacketParser`] and returns
4574    /// the path (see [`PacketPile::path_ref`]) of the last packet:
4575    ///
4576    ///   [`PacketPile::path_ref`]: super::PacketPile::path_ref()
4577    ///
4578    /// ```rust
4579    /// # fn main() -> sequoia_openpgp::Result<()> {
4580    /// use sequoia_openpgp as openpgp;
4581    /// use openpgp::Packet;
4582    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4583    ///
4584    /// let openpgp_data: &[u8] = // ...
4585    /// #    include_bytes!("../tests/data/keys/public-key.pgp");
4586    /// let mut ppr = PacketParser::from_bytes(openpgp_data)?;
4587    /// while let PacketParserResult::Some(mut pp) = ppr {
4588    ///     // Start parsing the next packet, recursing.
4589    ///     ppr = pp.recurse()?.1;
4590    /// }
4591    ///
4592    /// if let PacketParserResult::EOF(eof) = ppr {
4593    ///     let _ = eof.last_path();
4594    /// }
4595    /// # Ok(()) }
4596    /// ```
4597    pub fn last_path(&self) -> &[usize] {
4598        &self.last_path[..]
4599    }
4600
4601    /// The last packet's recursion depth.
4602    ///
4603    /// A top-level packet has a recursion depth of 0.  Packets in a
4604    /// top-level container have a recursion depth of 1, etc.
4605    ///
4606    /// # Examples
4607    ///
4608    /// Parse some OpenPGP stream using a [`PacketParser`] and returns
4609    /// the recursion depth of the last packet:
4610    ///
4611    ///
4612    /// ```rust
4613    /// # fn main() -> sequoia_openpgp::Result<()> {
4614    /// use sequoia_openpgp as openpgp;
4615    /// use openpgp::Packet;
4616    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4617    ///
4618    /// let openpgp_data: &[u8] = // ...
4619    /// #    include_bytes!("../tests/data/keys/public-key.pgp");
4620    /// let mut ppr = PacketParser::from_bytes(openpgp_data)?;
4621    /// while let PacketParserResult::Some(mut pp) = ppr {
4622    ///     // Start parsing the next packet, recursing.
4623    ///     ppr = pp.recurse()?.1;
4624    /// }
4625    ///
4626    /// if let PacketParserResult::EOF(eof) = ppr {
4627    ///     let _ = eof.last_recursion_depth();
4628    /// }
4629    /// # Ok(()) }
4630    /// ```
4631    pub fn last_recursion_depth(&self) -> Option<isize> {
4632        if self.last_path.is_empty() {
4633            None
4634        } else {
4635            Some(self.last_path.len() as isize - 1)
4636        }
4637    }
4638
4639    /// Returns the exhausted reader.
4640    pub fn into_reader(self) -> Box<dyn BufferedReader<Cookie> + 'a> {
4641        self.reader
4642    }
4643}
4644
4645/// The result of parsing a packet.
4646///
4647/// This type is returned by [`PacketParser::next`],
4648/// [`PacketParser::recurse`], [`PacketParserBuilder::build`], and the
4649/// implementation of [`PacketParser`]'s [`Parse` trait].  The result
4650/// is either `Some(PacketParser)`, indicating successful parsing of a
4651/// packet, or `EOF(PacketParserEOF)` if the end of the input stream
4652/// has been reached.
4653///
4654///   [`PacketParser::next`]: PacketParser::next()
4655///   [`PacketParser::recurse`]: PacketParser::recurse()
4656///   [`PacketParserBuilder::build`]: PacketParserBuilder::build()
4657///   [`Parse` trait]: struct.PacketParser.html#impl-Parse%3C%27a%2C%20PacketParserResult%3C%27a%3E%3E
4658#[derive(Debug)]
4659pub enum PacketParserResult<'a> {
4660    /// A `PacketParser` for the next packet.
4661    Some(PacketParser<'a>),
4662    /// Information about a fully parsed packet sequence.
4663    EOF(PacketParserEOF<'a>),
4664}
4665assert_send_and_sync!(PacketParserResult<'_>);
4666
4667impl<'a> PacketParserResult<'a> {
4668    /// Returns `true` if the result is `EOF`.
4669    pub fn is_eof(&self) -> bool {
4670        matches!(self, PacketParserResult::EOF(_))
4671    }
4672
4673    /// Returns `true` if the result is `Some`.
4674    pub fn is_some(&self) -> bool {
4675        ! Self::is_eof(self)
4676    }
4677
4678    /// Unwraps a result, yielding the content of an `Some`.
4679    ///
4680    /// # Panics
4681    ///
4682    /// Panics if the value is an `EOF`, with a panic message
4683    /// including the passed message, and the information in the
4684    /// [`PacketParserEOF`] object.
4685    ///
4686    pub fn expect(self, msg: &str) -> PacketParser<'a> {
4687        if let PacketParserResult::Some(pp) = self {
4688            pp
4689        } else {
4690            panic!("{}", msg);
4691        }
4692    }
4693
4694    /// Unwraps a result, yielding the content of an `Some`.
4695    ///
4696    /// # Panics
4697    ///
4698    /// Panics if the value is an `EOF`, with a panic message
4699    /// including the information in the [`PacketParserEOF`] object.
4700    ///
4701    pub fn unwrap(self) -> PacketParser<'a> {
4702        self.expect("called `PacketParserResult::unwrap()` on a \
4703                     `PacketParserResult::PacketParserEOF` value")
4704    }
4705
4706    /// Converts from `PacketParserResult` to `Result<&PacketParser,
4707    /// &PacketParserEOF>`.
4708    ///
4709    /// Produces a new `Result`, containing references into the
4710    /// original `PacketParserResult`, leaving the original in place.
4711    pub fn as_ref(&self)
4712                  -> StdResult<&PacketParser<'a>, &PacketParserEOF<'a>> {
4713        match self {
4714            PacketParserResult::Some(pp) => Ok(pp),
4715            PacketParserResult::EOF(eof) => Err(eof),
4716        }
4717    }
4718
4719    /// Converts from `PacketParserResult` to `Result<&mut
4720    /// PacketParser, &mut PacketParserEOF>`.
4721    ///
4722    /// Produces a new `Result`, containing mutable references into the
4723    /// original `PacketParserResult`, leaving the original in place.
4724    pub fn as_mut(&mut self)
4725                  -> StdResult<&mut PacketParser<'a>, &mut PacketParserEOF<'a>>
4726    {
4727        match self {
4728            PacketParserResult::Some(pp) => Ok(pp),
4729            PacketParserResult::EOF(eof) => Err(eof),
4730        }
4731    }
4732
4733    /// Takes the value out of the `PacketParserResult`, leaving a
4734    /// `EOF` in its place.
4735    ///
4736    /// The `EOF` left in place carries a [`PacketParserEOF`] with
4737    /// default values.
4738    ///
4739    pub fn take(&mut self) -> Self {
4740        mem::replace(
4741            self,
4742            PacketParserResult::EOF(PacketParserEOF::empty()))
4743    }
4744
4745    /// Maps a `PacketParserResult` to `Result<PacketParser,
4746    /// PacketParserEOF>` by applying a function to a contained `Some`
4747    /// value, leaving an `EOF` value untouched.
4748    pub fn map<U, F>(self, f: F) -> StdResult<U, PacketParserEOF<'a>>
4749        where F: FnOnce(PacketParser<'a>) -> U
4750    {
4751        match self {
4752            PacketParserResult::Some(x) => Ok(f(x)),
4753            PacketParserResult::EOF(e) => Err(e),
4754        }
4755    }
4756}
4757
4758impl<'a> Parse<'a, PacketParserResult<'a>> for PacketParser<'a> {
4759    /// Starts parsing an OpenPGP object stored in a `BufferedReader` object.
4760    ///
4761    /// This function returns a `PacketParser` for the first packet in
4762    /// the stream.
4763    fn from_buffered_reader<R>(reader: R) -> Result<PacketParserResult<'a>>
4764    where
4765        R: BufferedReader<Cookie> + 'a,
4766    {
4767        PacketParserBuilder::from_buffered_reader(reader.into_boxed())?.build()
4768    }
4769}
4770
4771impl<'a> crate::seal::Sealed for PacketParser<'a> {}
4772
4773impl <'a> PacketParser<'a> {
4774    /// Starts parsing an OpenPGP message stored in a `BufferedReader`
4775    /// object.
4776    ///
4777    /// This function returns a `PacketParser` for the first packet in
4778    /// the stream.
4779    pub(crate) fn from_cookie_reader(bio: Box<dyn BufferedReader<Cookie> + 'a>)
4780            -> Result<PacketParserResult<'a>> {
4781        PacketParserBuilder::from_cookie_reader(bio)?.build()
4782    }
4783
4784    /// Returns the reader stack, replacing it with a
4785    /// `buffered_reader::EOF` reader.
4786    ///
4787    /// This function may only be called when the `PacketParser` is in
4788    /// State::Body.
4789    fn take_reader(&mut self) -> Box<dyn BufferedReader<Cookie> + 'a> {
4790        self.set_reader(
4791            Box::new(buffered_reader::EOF::with_cookie(Default::default())))
4792    }
4793
4794    /// Replaces the reader stack.
4795    ///
4796    /// This function may only be called when the `PacketParser` is in
4797    /// State::Body.
4798    fn set_reader(&mut self, reader: Box<dyn BufferedReader<Cookie> + 'a>)
4799        -> Box<dyn BufferedReader<Cookie> + 'a>
4800    {
4801        mem::replace(&mut self.reader, reader)
4802    }
4803
4804    /// Returns a mutable reference to the reader stack.
4805    fn mut_reader(&mut self) -> &mut dyn BufferedReader<Cookie> {
4806        &mut self.reader
4807    }
4808
4809    /// Marks the packet's contents as processed or not.
4810    fn set_processed(mut self, v: bool) -> Self {
4811        self.processed = v;
4812        self
4813    }
4814
4815    /// Returns whether the packet's contents have been processed.
4816    ///
4817    /// This function returns `true` while processing an encryption
4818    /// container before it is decrypted using
4819    /// [`PacketParser::decrypt`].  Once successfully decrypted, it
4820    /// returns `false`.
4821    ///
4822    ///   [`PacketParser::decrypt`]: PacketParser::decrypt()
4823    ///
4824    /// # Examples
4825    ///
4826    /// ```rust
4827    /// # fn main() -> sequoia_openpgp::Result<()> {
4828    /// use sequoia_openpgp as openpgp;
4829    /// use openpgp::Packet;
4830    /// use openpgp::fmt::hex;
4831    /// use openpgp::types::SymmetricAlgorithm;
4832    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4833    ///
4834    /// // Parse an encrypted message.
4835    /// let message_data: &[u8] = // ...
4836    /// #    include_bytes!("../tests/data/messages/encrypted-aes256-password-123.pgp");
4837    /// let mut ppr = PacketParser::from_bytes(message_data)?;
4838    /// while let PacketParserResult::Some(mut pp) = ppr {
4839    ///     if let Packet::SEIP(_) = pp.packet {
4840    ///         assert!(!pp.processed());
4841    ///         pp.decrypt(SymmetricAlgorithm::AES256,
4842    ///                    &hex::decode("7EF4F08C44F780BEA866961423306166\
4843    ///                                  B8912C43352F3D9617F745E4E3939710")?
4844    ///                        .into())?;
4845    ///         assert!(pp.processed());
4846    ///     }
4847    ///
4848    ///     // Start parsing the next packet, recursing.
4849    ///     ppr = pp.recurse()?.1;
4850    /// }
4851    /// # Ok(()) }
4852    /// ```
4853    pub fn processed(&self) -> bool {
4854        self.processed
4855    }
4856
4857    /// Returns the path of the last packet.
4858    ///
4859    /// This function returns the path (see [`PacketPile::path_ref`]
4860    /// for a description of paths) of the packet last returned by a
4861    /// call to [`PacketParser::recurse`] or [`PacketParser::next`].
4862    /// If no packet has been returned (i.e. the current packet is the
4863    /// first packet), this returns the empty slice.
4864    ///
4865    ///   [`PacketPile::path_ref`]: super::PacketPile::path_ref()
4866    ///   [`PacketParser::recurse`]: PacketParser::recurse()
4867    ///   [`PacketParser::next`]: PacketParser::next()
4868    ///
4869    /// # Examples
4870    ///
4871    /// ```rust
4872    /// # fn main() -> sequoia_openpgp::Result<()> {
4873    /// use sequoia_openpgp as openpgp;
4874    /// use openpgp::Packet;
4875    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4876    ///
4877    /// // Parse a compressed message.
4878    /// let message_data: &[u8] = // ...
4879    /// #    include_bytes!("../tests/data/messages/compressed-data-algo-0.pgp");
4880    /// let mut ppr = PacketParser::from_bytes(message_data)?;
4881    /// while let PacketParserResult::Some(mut pp) = ppr {
4882    ///     match pp.packet {
4883    ///         Packet::CompressedData(_) => assert_eq!(pp.last_path(), &[] as &[usize]),
4884    ///         Packet::Literal(_) => assert_eq!(pp.last_path(), &[0usize]),
4885    ///         _ => (),
4886    ///     }
4887    ///
4888    ///     // Start parsing the next packet, recursing.
4889    ///     ppr = pp.recurse()?.1;
4890    /// }
4891    /// # Ok(()) }
4892    /// ```
4893    pub fn last_path(&self) -> &[usize] {
4894        &self.last_path[..]
4895    }
4896
4897    /// Returns the path of the current packet.
4898    ///
4899    /// This function returns the path (see [`PacketPile::path_ref`]
4900    /// for a description of paths) of the packet currently being
4901    /// processed (see [`PacketParser::packet`]).
4902    ///
4903    ///   [`PacketPile::path_ref`]: super::PacketPile::path_ref()
4904    ///
4905    /// # Examples
4906    ///
4907    /// ```rust
4908    /// # fn main() -> sequoia_openpgp::Result<()> {
4909    /// use sequoia_openpgp as openpgp;
4910    /// use openpgp::Packet;
4911    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4912    ///
4913    /// // Parse a compressed message.
4914    /// let message_data: &[u8] = // ...
4915    /// #    include_bytes!("../tests/data/messages/compressed-data-algo-0.pgp");
4916    /// let mut ppr = PacketParser::from_bytes(message_data)?;
4917    /// while let PacketParserResult::Some(mut pp) = ppr {
4918    ///     match pp.packet {
4919    ///         Packet::CompressedData(_) => assert_eq!(pp.path(), &[0]),
4920    ///         Packet::Literal(_) => assert_eq!(pp.path(), &[0, 0]),
4921    ///         _ => (),
4922    ///     }
4923    ///
4924    ///     // Start parsing the next packet, recursing.
4925    ///     ppr = pp.recurse()?.1;
4926    /// }
4927    /// # Ok(()) }
4928    /// ```
4929    pub fn path(&self) -> &[usize] {
4930        &self.path[..]
4931    }
4932
4933    /// The current packet's recursion depth.
4934    ///
4935    /// A top-level packet has a recursion depth of 0.  Packets in a
4936    /// top-level container have a recursion depth of 1, etc.
4937    ///
4938    /// # Examples
4939    ///
4940    /// ```rust
4941    /// # fn main() -> sequoia_openpgp::Result<()> {
4942    /// use sequoia_openpgp as openpgp;
4943    /// use openpgp::Packet;
4944    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4945    ///
4946    /// // Parse a compressed message.
4947    /// let message_data: &[u8] = // ...
4948    /// #    include_bytes!("../tests/data/messages/compressed-data-algo-0.pgp");
4949    /// let mut ppr = PacketParser::from_bytes(message_data)?;
4950    /// while let PacketParserResult::Some(mut pp) = ppr {
4951    ///     match pp.packet {
4952    ///         Packet::CompressedData(_) => assert_eq!(pp.recursion_depth(), 0),
4953    ///         Packet::Literal(_) => assert_eq!(pp.recursion_depth(), 1),
4954    ///         _ => (),
4955    ///     }
4956    ///
4957    ///     // Start parsing the next packet, recursing.
4958    ///     ppr = pp.recurse()?.1;
4959    /// }
4960    /// # Ok(()) }
4961    /// ```
4962    pub fn recursion_depth(&self) -> isize {
4963        self.path.len() as isize - 1
4964    }
4965
4966    /// The last packet's recursion depth.
4967    ///
4968    /// A top-level packet has a recursion depth of 0.  Packets in a
4969    /// top-level container have a recursion depth of 1, etc.
4970    ///
4971    /// Note: if no packet has been returned yet, this returns None.
4972    ///
4973    /// # Examples
4974    ///
4975    /// ```rust
4976    /// # fn main() -> sequoia_openpgp::Result<()> {
4977    /// use sequoia_openpgp as openpgp;
4978    /// use openpgp::Packet;
4979    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
4980    ///
4981    /// // Parse a compressed message.
4982    /// let message_data: &[u8] = // ...
4983    /// #    include_bytes!("../tests/data/messages/compressed-data-algo-0.pgp");
4984    /// let mut ppr = PacketParser::from_bytes(message_data)?;
4985    /// while let PacketParserResult::Some(mut pp) = ppr {
4986    ///     match pp.packet {
4987    ///         Packet::CompressedData(_) => assert_eq!(pp.last_recursion_depth(), None),
4988    ///         Packet::Literal(_) => assert_eq!(pp.last_recursion_depth(), Some(0)),
4989    ///         _ => (),
4990    ///     }
4991    ///
4992    ///     // Start parsing the next packet, recursing.
4993    ///     ppr = pp.recurse()?.1;
4994    /// }
4995    /// # Ok(()) }
4996    /// ```
4997    pub fn last_recursion_depth(&self) -> Option<isize> {
4998        if self.last_path.is_empty() {
4999            assert_eq!(&self.path[..], &[ 0 ]);
5000            None
5001        } else {
5002            Some(self.last_path.len() as isize - 1)
5003        }
5004    }
5005
5006    /// Returns whether the message appears to be an OpenPGP Message.
5007    ///
5008    /// Only when the whole message has been processed is it possible
5009    /// to say whether the message is definitely an OpenPGP Message.
5010    /// Before that, it is only possible to say that the message is a
5011    /// valid prefix or definitely not an OpenPGP message (see
5012    /// [`PacketParserEOF::is_message`]).
5013    ///
5014    ///   [`PacketParserEOF::is_message`]: PacketParserEOF::is_message()
5015    ///
5016    /// # Examples
5017    ///
5018    /// ```rust
5019    /// # fn main() -> sequoia_openpgp::Result<()> {
5020    /// use sequoia_openpgp as openpgp;
5021    /// use openpgp::Packet;
5022    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
5023    ///
5024    /// // Parse a compressed message.
5025    /// let message_data: &[u8] = // ...
5026    /// #    include_bytes!("../tests/data/messages/compressed-data-algo-0.pgp");
5027    /// let mut ppr = PacketParser::from_bytes(message_data)?;
5028    /// while let PacketParserResult::Some(mut pp) = ppr {
5029    ///     pp.possible_message()?;
5030    ///
5031    ///     // Start parsing the next packet, recursing.
5032    ///     ppr = pp.recurse()?.1;
5033    /// }
5034    /// # Ok(()) }
5035    /// ```
5036    pub fn possible_message(&self) -> Result<()> {
5037        use crate::message::MessageValidity;
5038
5039        match self.state.message_validator.check() {
5040            MessageValidity::Message => unreachable!(),
5041            MessageValidity::MessagePrefix => Ok(()),
5042            MessageValidity::Error(err) => Err(err),
5043        }
5044    }
5045
5046    /// Returns whether the message appears to be an OpenPGP keyring.
5047    ///
5048    /// Only when the whole message has been processed is it possible
5049    /// to say whether the message is definitely an OpenPGP keyring.
5050    /// Before that, it is only possible to say that the message is a
5051    /// valid prefix or definitely not an OpenPGP keyring (see
5052    /// [`PacketParserEOF::is_keyring`]).
5053    ///
5054    ///   [`PacketParserEOF::is_keyring`]: PacketParserEOF::is_keyring()
5055    ///
5056    /// # Examples
5057    ///
5058    /// ```rust
5059    /// # fn main() -> sequoia_openpgp::Result<()> {
5060    /// use sequoia_openpgp as openpgp;
5061    /// use openpgp::Packet;
5062    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
5063    ///
5064    /// // Parse a certificate.
5065    /// let message_data: &[u8] = // ...
5066    /// #    include_bytes!("../tests/data/keys/testy.pgp");
5067    /// let mut ppr = PacketParser::from_bytes(message_data)?;
5068    /// while let PacketParserResult::Some(mut pp) = ppr {
5069    ///     pp.possible_keyring()?;
5070    ///
5071    ///     // Start parsing the next packet, recursing.
5072    ///     ppr = pp.recurse()?.1;
5073    /// }
5074    /// # Ok(()) }
5075    /// ```
5076    pub fn possible_keyring(&self) -> Result<()> {
5077        match self.state.keyring_validator.check() {
5078            KeyringValidity::Keyring => unreachable!(),
5079            KeyringValidity::KeyringPrefix => Ok(()),
5080            KeyringValidity::Error(err) => Err(err),
5081        }
5082    }
5083
5084    /// Returns whether the message appears to be an OpenPGP Cert.
5085    ///
5086    /// Only when the whole message has been processed is it possible
5087    /// to say whether the message is definitely an OpenPGP Cert.
5088    /// Before that, it is only possible to say that the message is a
5089    /// valid prefix or definitely not an OpenPGP Cert (see
5090    /// [`PacketParserEOF::is_cert`]).
5091    ///
5092    ///   [`PacketParserEOF::is_cert`]: PacketParserEOF::is_cert()
5093    ///
5094    /// # Examples
5095    ///
5096    /// ```rust
5097    /// # fn main() -> sequoia_openpgp::Result<()> {
5098    /// use sequoia_openpgp as openpgp;
5099    /// use openpgp::Packet;
5100    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
5101    ///
5102    /// // Parse a certificate.
5103    /// let message_data: &[u8] = // ...
5104    /// #    include_bytes!("../tests/data/keys/testy.pgp");
5105    /// let mut ppr = PacketParser::from_bytes(message_data)?;
5106    /// while let PacketParserResult::Some(mut pp) = ppr {
5107    ///     pp.possible_cert()?;
5108    ///
5109    ///     // Start parsing the next packet, recursing.
5110    ///     ppr = pp.recurse()?.1;
5111    /// }
5112    /// # Ok(()) }
5113    /// ```
5114    pub fn possible_cert(&self) -> Result<()> {
5115        match self.state.cert_validator.check() {
5116            CertValidity::Cert => unreachable!(),
5117            CertValidity::CertPrefix => Ok(()),
5118            CertValidity::Error(err) => Err(err),
5119        }
5120    }
5121
5122    /// Tests whether the data appears to be a legal cert packet.
5123    ///
5124    /// This is just a heuristic.  It can be used for recovering from
5125    /// garbage.
5126    ///
5127    /// Successfully reading the header only means that the top bit of
5128    /// the ptag is 1.  Assuming a uniform distribution, there's a 50%
5129    /// chance that that is the case.
5130    ///
5131    /// To improve our chances of a correct recovery, we make sure the
5132    /// tag is known (for new format CTBs, there are 64 possible tags,
5133    /// but only a third of them are reasonable; for old format
5134    /// packets, there are only 16 and nearly all are plausible), and
5135    /// we make sure the packet contents are reasonable.
5136    ///
5137    /// Currently, we only try to recover the most interesting
5138    /// packets.
5139    pub(crate) fn plausible_cert(bio: &mut dyn BufferedReader<Cookie>,
5140                                 header: &Header)
5141        -> Result<()>
5142    {
5143        let bad = Err(
5144            Error::MalformedPacket("Can't make an educated case".into()).into());
5145
5146        match header.ctb().tag() {
5147            Tag::Reserved
5148            | Tag::Unknown(_) | Tag::Private(_) =>
5149                Err(Error::MalformedPacket("Looks like garbage".into()).into()),
5150
5151            Tag::Marker => Marker::plausible(bio, header),
5152            Tag::Padding => {
5153                // Even though a padding packet may occur here, it has
5154                // so little structure, that we're likely better off
5155                // trying to find the next packet.
5156                //
5157                // XXX: We could optimize that though, by using the
5158                // potential padding packet's length to see if the
5159                // next packet is plausible.
5160                bad
5161            },
5162            Tag::Signature => Signature::plausible(bio, header),
5163
5164            Tag::SecretKey => Key::plausible(bio, header),
5165            Tag::PublicKey => Key::plausible(bio, header),
5166            Tag::SecretSubkey => Key::plausible(bio, header),
5167            Tag::PublicSubkey => Key::plausible(bio, header),
5168
5169            Tag::UserID => bad,
5170            Tag::UserAttribute => bad,
5171
5172            // It is reasonable to try and ignore garbage in Certs,
5173            // because who knows what the keyservers return, etc.
5174            // But, if we have what appears to be an OpenPGP message,
5175            // then, ignore.
5176            Tag::PKESK => bad,
5177            Tag::SKESK => bad,
5178            Tag::OnePassSig => bad,
5179            Tag::CompressedData => bad,
5180            Tag::SED => bad,
5181            Tag::Literal => bad,
5182            Tag::Trust => bad,
5183            Tag::SEIP => bad,
5184            Tag::MDC => bad,
5185            Tag::AED => bad,
5186        }
5187    }
5188
5189    /// Returns a `PacketParser` for the next OpenPGP packet in the
5190    /// stream.  If there are no packets left, this function returns
5191    /// `bio`.
5192    fn parse(mut bio: Box<dyn BufferedReader<Cookie> + 'a>,
5193             mut state: PacketParserState,
5194             path: Vec<usize>)
5195        -> Result<ParserResult<'a>>
5196    {
5197        assert!(!path.is_empty());
5198
5199        let indent = path.len() as isize - 1;
5200        tracer!(TRACE, "PacketParser::parse", indent);
5201
5202        if let Some(err) = state.pending_error.take() {
5203            t!("Returning pending error: {}", err);
5204            return Err(err);
5205        }
5206        t!("Parsing packet at {:?}", path);
5207
5208        let recursion_depth = path.len() as isize - 1;
5209
5210        // When header encounters an EOF, it returns an error.  But,
5211        // we want to return None.  Try a one byte read.
5212        if bio.data(1)?.is_empty() {
5213            t!("No packet at {:?} (EOF).", path);
5214            return Ok(ParserResult::EOF((bio, state, path)));
5215        }
5216
5217        // When computing a hash for a signature, most of the
5218        // signature packet should not be included in the hash.  That
5219        // is:
5220        //
5221        //    [ one pass sig ] [ ... message ... ] [ sig ]
5222        //                     ^^^^^^^^^^^^^^^^^^^
5223        //                        hash only this
5224        //
5225        // (The special logic for the Signature packet is in
5226        // Signature::parse.)
5227        //
5228        // To avoid this, we use a Dup reader to figure out if the
5229        // next packet is a sig packet without consuming the headers,
5230        // which would cause the headers to be hashed.  If so, we
5231        // extract the hash context.
5232
5233        let mut bio = buffered_reader::Dup::with_cookie(bio, Cookie::default());
5234        let header;
5235
5236        // Read the header.
5237        let mut skip = 0;
5238        let mut orig_error : Option<anyhow::Error> = None;
5239        loop {
5240            bio.rewind();
5241            if let Err(_err) = bio.data_consume_hard(skip) {
5242                // EOF.  We checked for EOF above when skip was 0, so
5243                // we must have skipped something.
5244                assert!(skip > 0);
5245
5246                // Fabricate a header.
5247                header = Header::new(CTB::new(Tag::Reserved),
5248                                     BodyLength::Full(skip as u32));
5249
5250                break;
5251            }
5252
5253            match Header::parse(&mut bio) {
5254                Ok(header_) => {
5255                    if skip == 0 {
5256                        header = header_;
5257                        break;
5258                    }
5259
5260                    match Self::plausible_cert(&mut bio, &header_) {
5261                        Ok(()) => {
5262                            header = Header::new(CTB::new(Tag::Reserved),
5263                                                 BodyLength::Full(skip as u32));
5264                            break;
5265                        }
5266                        Err(err_) => {
5267                            t!("{} not plausible @ {}: {}",
5268                               header_.ctb().tag(), skip, err_);
5269                        },
5270                    }
5271                }
5272                Err(err) => {
5273                    t!("Failed to read a header after skipping {} bytes: {}",
5274                       skip, err);
5275                    if orig_error.is_none() {
5276                        orig_error = Some(err);
5277                    }
5278
5279                    if state.first_packet {
5280                        // We don't try to recover if we haven't seen
5281                        // any packets.
5282                        return Err(orig_error.unwrap());
5283                    }
5284
5285                    if skip > RECOVERY_THRESHOLD {
5286                        // Limit the search space.  This should be
5287                        // enough to find a reasonable recovery point
5288                        // in a Cert.
5289                        state.pending_error = orig_error;
5290
5291                        // Fabricate a header.
5292                        header = Header::new(CTB::new(Tag::Reserved),
5293                                             BodyLength::Full(skip as u32));
5294                        break;
5295                    }
5296                }
5297            }
5298
5299            skip += 1;
5300        }
5301
5302        // Prepare to actually consume the header or garbage.
5303        let consumed = if skip == 0 {
5304            bio.total_out()
5305        } else {
5306            t!("turning {} bytes of junk into an Unknown packet", skip);
5307            bio.rewind();
5308            0
5309        };
5310
5311        let tag = header.ctb().tag();
5312        t!("Packet's tag is {}", tag);
5313
5314        // A buffered_reader::Dup always has an inner.
5315        let mut bio = Box::new(bio).into_inner().unwrap();
5316
5317        // Disable hashing for literal packets, Literal::parse will
5318        // enable it for the body.  Signatures and OnePassSig packets
5319        // are only hashed by notarizing signatures.
5320        if tag == Tag::Literal {
5321            Cookie::hashing(
5322                &mut bio, Hashing::Disabled, recursion_depth - 1);
5323        } else if tag == Tag::OnePassSig || tag == Tag::Signature {
5324            if Cookie::processing_csf_message(&bio) {
5325                // When processing a CSF message, the hashing reader
5326                // is not peeled off, because the number of signature
5327                // packets cannot be known from the number of OPS
5328                // packets.  Instead, we simply disable hashing.
5329                //
5330                // XXX: It would be nice to peel off the hashing
5331                // reader and drop this workaround.
5332                Cookie::hashing(
5333                    &mut bio, Hashing::Disabled, recursion_depth - 1);
5334            } else {
5335                Cookie::hashing(
5336                    &mut bio, Hashing::Notarized, recursion_depth - 1);
5337            }
5338        }
5339
5340        // Save header for the map or nested signatures.
5341        let header_bytes =
5342            Vec::from(&bio.data_consume_hard(consumed)?[..consumed]);
5343
5344        let bio : Box<dyn BufferedReader<Cookie>>
5345            = match header.length() {
5346                &BodyLength::Full(len) => {
5347                    t!("Pushing a limitor ({} bytes), level: {}.",
5348                       len, recursion_depth);
5349                    Box::new(buffered_reader::Limitor::with_cookie(
5350                        bio, len as u64,
5351                        Cookie::new(recursion_depth)))
5352                },
5353                &BodyLength::Partial(len) => {
5354                    t!("Pushing a partial body chunk decoder, level: {}.",
5355                       recursion_depth);
5356                    Box::new(BufferedReaderPartialBodyFilter::with_cookie(
5357                        bio, len,
5358                        // When hashing a literal data packet, we only
5359                        // hash the packet's contents; we don't hash
5360                        // the literal data packet's meta-data or the
5361                        // length information, which includes the
5362                        // partial body headers.
5363                        tag != Tag::Literal,
5364                        Cookie::new(recursion_depth)))
5365                },
5366                BodyLength::Indeterminate => {
5367                    t!("Indeterminate length packet, not adding a limitor.");
5368                    bio
5369                },
5370        };
5371
5372        // Our parser should not accept packets that fail our header
5373        // syntax check.  Doing so breaks roundtripping, and seems
5374        // like a bad idea anyway.
5375        let mut header_syntax_error = header.valid(true).err();
5376
5377        // Check packet size.
5378        if header_syntax_error.is_none() {
5379            let max_size = state.settings.max_packet_size;
5380            match tag {
5381                // Don't check the size for container packets, those
5382                // can be safely streamed.
5383                Tag::Literal | Tag::CompressedData | Tag::SED | Tag::SEIP
5384                    | Tag::AED => (),
5385                _ => match header.length() {
5386                    BodyLength::Full(l) => if *l > max_size {
5387                        header_syntax_error = Some(
5388                            Error::PacketTooLarge(tag, *l, max_size).into());
5389                    },
5390                    _ => unreachable!("non-data packets have full length, \
5391                                       syntax check above"),
5392                }
5393            }
5394        }
5395
5396        let parser = PacketHeaderParser::new(bio, state, path,
5397                                             header, header_bytes);
5398
5399        let mut result = match tag {
5400            Tag::Reserved if skip > 0 => Unknown::parse(
5401                parser, Error::MalformedPacket(format!(
5402                    "Skipped {} bytes of junk", skip)).into()),
5403            _ if header_syntax_error.is_some() =>
5404                Unknown::parse(parser, header_syntax_error.unwrap()),
5405            Tag::Signature =>           Signature::parse(parser),
5406            Tag::OnePassSig =>          OnePassSig::parse(parser),
5407            Tag::PublicSubkey =>        Key::parse(parser),
5408            Tag::PublicKey =>           Key::parse(parser),
5409            Tag::SecretKey =>           Key::parse(parser),
5410            Tag::SecretSubkey =>        Key::parse(parser),
5411            Tag::Trust =>               Trust::parse(parser),
5412            Tag::UserID =>              UserID::parse(parser),
5413            Tag::UserAttribute =>       UserAttribute::parse(parser),
5414            Tag::Marker =>              Marker::parse(parser),
5415            Tag::Literal =>             Literal::parse(parser),
5416            Tag::CompressedData =>      CompressedData::parse(parser),
5417            Tag::SKESK =>               SKESK::parse(parser),
5418            Tag::SEIP =>                SEIP::parse(parser),
5419            Tag::MDC =>                 MDC::parse(parser),
5420            Tag::PKESK =>               PKESK::parse(parser),
5421            Tag::Padding =>             Padding::parse(parser),
5422            _ => Unknown::parse(parser,
5423                                Error::UnsupportedPacketType(tag).into()),
5424        }?;
5425
5426        if tag == Tag::OnePassSig {
5427            Cookie::hashing(
5428                &mut result, Hashing::Enabled, recursion_depth - 1);
5429        }
5430
5431        result.state.first_packet = false;
5432
5433        t!(" -> {:?}, path: {:?}, level: {:?}.",
5434           result.packet.tag(), result.path, result.cookie_ref().level);
5435
5436        return Ok(ParserResult::Success(result));
5437    }
5438
5439    /// Finishes parsing the current packet and starts parsing the
5440    /// next one.
5441    ///
5442    /// This function finishes parsing the current packet.  By
5443    /// default, any unread content is dropped.  (See
5444    /// [`PacketParsererBuilder`] for how to configure this.)  It then
5445    /// creates a new packet parser for the next packet.  If the
5446    /// current packet is a container, this function does *not*
5447    /// recurse into the container, but skips any packets it contains.
5448    /// To recurse into the container, use the [`recurse()`] method.
5449    ///
5450    ///   [`PacketParsererBuilder`]: PacketParserBuilder
5451    ///   [`recurse()`]: PacketParser::recurse()
5452    ///
5453    /// The return value is a tuple containing:
5454    ///
5455    ///   - A `Packet` holding the fully processed old packet;
5456    ///
5457    ///   - A `PacketParser` holding the new packet;
5458    ///
5459    /// To determine the two packet's position within the parse tree,
5460    /// you can use `last_path()` and `path()`, respectively.  To
5461    /// determine their depth, you can use `last_recursion_depth()`
5462    /// and `recursion_depth()`, respectively.
5463    ///
5464    /// Note: A recursion depth of 0 means that the packet is a
5465    /// top-level packet, a recursion depth of 1 means that the packet
5466    /// is an immediate child of a top-level-packet, etc.
5467    ///
5468    /// Since the packets are serialized in depth-first order and all
5469    /// interior nodes are visited, we know that if the recursion
5470    /// depth is the same, then the packets are siblings (they have a
5471    /// common parent) and not, e.g., cousins (they have a common
5472    /// grandparent).  This is because, if we move up the tree, the
5473    /// only way to move back down is to first visit a new container
5474    /// (e.g., an aunt).
5475    ///
5476    /// Using the two positions, we can compute the change in depth as
5477    /// new_depth - old_depth.  Thus, if the change in depth is 0, the
5478    /// two packets are siblings.  If the value is 1, the old packet
5479    /// is a container, and the new packet is its first child.  And,
5480    /// if the value is -1, the new packet is contained in the old
5481    /// packet's grandparent.  The idea is illustrated below:
5482    ///
5483    /// ```text
5484    ///             ancestor
5485    ///             |       \
5486    ///            ...      -n
5487    ///             |
5488    ///           grandparent
5489    ///           |          \
5490    ///         parent       -1
5491    ///         |      \
5492    ///      packet    0
5493    ///         |
5494    ///         1
5495    /// ```
5496    ///
5497    /// Note: since this function does not automatically recurse into
5498    /// a container, the change in depth will always be non-positive.
5499    /// If the current container is empty, this function DOES pop that
5500    /// container off the container stack, and returns the following
5501    /// packet in the parent container.
5502    ///
5503    /// # Examples
5504    ///
5505    /// ```rust
5506    /// # fn main() -> sequoia_openpgp::Result<()> {
5507    /// use sequoia_openpgp as openpgp;
5508    /// use openpgp::Packet;
5509    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
5510    ///
5511    /// // Parse a message.
5512    /// let message_data: &[u8] = // ...
5513    /// #    include_bytes!("../tests/data/messages/compressed-data-algo-0.pgp");
5514    /// let mut ppr = PacketParser::from_bytes(message_data)?;
5515    /// while let PacketParserResult::Some(mut pp) = ppr {
5516    ///     // Start parsing the next packet.
5517    ///     ppr = pp.next()?.1;
5518    /// }
5519    /// # Ok(()) }
5520    /// ```
5521    pub fn next(mut self)
5522        -> Result<(Packet, PacketParserResult<'a>)>
5523    {
5524        let indent = self.recursion_depth();
5525        tracer!(TRACE, "PacketParser::next", indent);
5526        t!("({:?}, path: {:?}, level: {:?}).",
5527           self.packet.tag(), self.path, self.cookie_ref().level);
5528
5529        self.finish()?;
5530
5531        let (mut fake_eof, mut reader) = buffered_reader_stack_pop(
5532            mem::replace(&mut self.reader,
5533                         Box::new(buffered_reader::EOF::with_cookie(
5534                             Default::default()))),
5535            self.recursion_depth())?;
5536
5537        self.last_path.clear();
5538        self.last_path.extend_from_slice(&self.path[..]);
5539
5540        // Assume that we succeed in parsing the next packet.  If not,
5541        // then we'll adjust the path.
5542        *self.path.last_mut().expect("A path is never empty") += 1;
5543
5544        // Now read the next packet.
5545        loop {
5546            // Parse the next packet.
5547            t!("Reading packet at {:?}", self.path);
5548
5549            let recursion_depth = self.recursion_depth();
5550
5551            let ppr = PacketParser::parse(reader, self.state, self.path)?;
5552            match ppr {
5553                ParserResult::EOF((reader_, state_, path_)) => {
5554                    // We got EOF on the current container.  The
5555                    // container at recursion depth n is empty.  Pop
5556                    // it and any filters for it, i.e., those at level
5557                    // n (e.g., the limitor that caused us to hit
5558                    // EOF), and then try again.
5559
5560                    t!("depth: {}, got EOF trying to read the next packet",
5561                       recursion_depth);
5562
5563                    self.path = path_;
5564
5565                    if ! fake_eof && recursion_depth == 0 {
5566                        t!("Popped top-level container, done reading message.");
5567                        // Pop topmost filters (e.g. the armor::Reader).
5568                        let (_, reader_) = buffered_reader_stack_pop(
5569                            reader_, ARMOR_READER_LEVEL)?;
5570                        let mut eof = PacketParserEOF::new(state_, reader_);
5571                        eof.last_path = self.last_path;
5572                        return Ok((self.packet,
5573                                   PacketParserResult::EOF(eof)));
5574                    } else {
5575                        self.state = state_;
5576                        self.finish()?;
5577                        let (fake_eof_, reader_) = buffered_reader_stack_pop(
5578                            reader_, recursion_depth - 1)?;
5579                        fake_eof = fake_eof_;
5580                        if ! fake_eof {
5581                            self.path.pop().unwrap();
5582                            *self.path.last_mut()
5583                                .expect("A path is never empty") += 1;
5584                        }
5585                        reader = reader_;
5586                    }
5587                },
5588                ParserResult::Success(mut pp) => {
5589                    let path = pp.path().to_vec();
5590                    pp.state.message_validator.push(
5591                        pp.packet.tag(), pp.packet.version(),
5592                        &path);
5593                    pp.state.keyring_validator.push(pp.packet.tag());
5594                    pp.state.cert_validator.push(pp.packet.tag());
5595
5596                    pp.last_path = self.last_path;
5597
5598                    return Ok((self.packet, PacketParserResult::Some(pp)));
5599                }
5600            }
5601        }
5602    }
5603
5604    /// Finishes parsing the current packet and starts parsing the
5605    /// next one, recursing if possible.
5606    ///
5607    /// This method is similar to the [`next()`] method (see that
5608    /// method for more details), but if the current packet is a
5609    /// container (and we haven't reached the maximum recursion depth,
5610    /// and the user hasn't started reading the packet's contents), we
5611    /// recurse into the container, and return a `PacketParser` for
5612    /// its first child.  Otherwise, we return the next packet in the
5613    /// packet stream.  If this function recurses, then the new
5614    /// packet's recursion depth will be `last_recursion_depth() + 1`;
5615    /// because we always visit interior nodes, we can't recurse more
5616    /// than one level at a time.
5617    ///
5618    ///   [`next()`]: PacketParser::next()
5619    ///
5620    /// # Examples
5621    ///
5622    /// ```rust
5623    /// # fn main() -> sequoia_openpgp::Result<()> {
5624    /// use sequoia_openpgp as openpgp;
5625    /// use openpgp::Packet;
5626    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
5627    ///
5628    /// // Parse a message.
5629    /// let message_data: &[u8] = // ...
5630    /// #    include_bytes!("../tests/data/messages/compressed-data-algo-0.pgp");
5631    /// let mut ppr = PacketParser::from_bytes(message_data)?;
5632    /// while let PacketParserResult::Some(mut pp) = ppr {
5633    ///     // Start parsing the next packet, recursing.
5634    ///     ppr = pp.recurse()?.1;
5635    /// }
5636    /// # Ok(()) }
5637    /// ```
5638    pub fn recurse(self) -> Result<(Packet, PacketParserResult<'a>)> {
5639        let indent = self.recursion_depth();
5640        tracer!(TRACE, "PacketParser::recurse", indent);
5641        t!("({:?}, path: {:?}, level: {:?})",
5642           self.packet.tag(), self.path, self.cookie_ref().level);
5643
5644        match self.packet {
5645            // Packets that recurse.
5646            Packet::CompressedData(_) | Packet::SEIP(_)
5647                if self.processed =>
5648            {
5649                if self.recursion_depth() as u8
5650                    >= self.state.settings.max_recursion_depth
5651                {
5652                    t!("Not recursing into the {:?} packet, maximum recursion \
5653                        depth ({}) reached.",
5654                       self.packet.tag(),
5655                       self.state.settings.max_recursion_depth);
5656
5657                    // Drop through.
5658                } else if self.content_was_read {
5659                    t!("Not recursing into the {:?} packet, some data was \
5660                        already read.",
5661                       self.packet.tag());
5662
5663                    // Drop through.
5664                } else {
5665                    let mut last_path = self.last_path;
5666                    last_path.clear();
5667                    last_path.extend_from_slice(&self.path[..]);
5668
5669                    let mut path = self.path;
5670                    path.push(0);
5671
5672                    match PacketParser::parse(self.reader, self.state,
5673                                              path.clone())?
5674                    {
5675                        ParserResult::Success(mut pp) => {
5676                            t!("Recursed into the {:?} packet, got a {:?}.",
5677                               self.packet.tag(), pp.packet.tag());
5678
5679                            pp.state.message_validator.push(
5680                                pp.packet.tag(),
5681                                pp.packet.version(),
5682                                &path);
5683                            pp.state.keyring_validator.push(pp.packet.tag());
5684                            pp.state.cert_validator.push(pp.packet.tag());
5685
5686                            pp.last_path = last_path;
5687
5688                            return Ok((self.packet,
5689                                       PacketParserResult::Some(pp)));
5690                        },
5691                        ParserResult::EOF(_) => {
5692                            return Err(Error::MalformedPacket(
5693                                "Container is truncated".into()).into());
5694                        },
5695                    }
5696                }
5697            },
5698            // Packets that don't recurse.
5699            #[allow(deprecated)]
5700            Packet::Unknown(_) | Packet::Signature(_) | Packet::OnePassSig(_)
5701                | Packet::PublicKey(_) | Packet::PublicSubkey(_)
5702                | Packet::SecretKey(_) | Packet::SecretSubkey(_)
5703                | Packet::Marker(_) | Packet::Trust(_)
5704                | Packet::UserID(_) | Packet::UserAttribute(_)
5705                | Packet::Literal(_) | Packet::PKESK(_) | Packet::SKESK(_)
5706                | Packet::SEIP(_) | Packet::MDC(_)
5707                | Packet::CompressedData(_)
5708                | Packet::Padding(_) => {
5709                // Drop through.
5710                t!("A {:?} packet is not a container, not recursing.",
5711                   self.packet.tag());
5712            },
5713        }
5714
5715        // No recursion.
5716        self.next()
5717    }
5718
5719    /// Causes the PacketParser to buffer the packet's contents.
5720    ///
5721    /// The packet's contents can be retrieved using
5722    /// e.g. [`Container::body`].  In general, you should avoid
5723    /// buffering a packet's content and prefer streaming its content
5724    /// unless you are certain that the content is small.
5725    ///
5726    ///   [`Container::body`]: crate::packet::Container::body()
5727    ///
5728    /// ```rust
5729    /// # fn main() -> sequoia_openpgp::Result<()> {
5730    /// use sequoia_openpgp as openpgp;
5731    /// use openpgp::Packet;
5732    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
5733    ///
5734    /// // Parse a message.
5735    /// let message_data: &[u8] = // ...
5736    /// #   include_bytes!("../tests/data/messages/literal-mode-t-partial-body.pgp");
5737    /// let mut ppr = PacketParser::from_bytes(message_data)?;
5738    /// while let PacketParserResult::Some(mut pp) = ppr {
5739    ///     // Process the packet.
5740    ///
5741    ///     if let Packet::Literal(_) = pp.packet {
5742    ///         assert!(pp.buffer_unread_content()?
5743    ///                     .starts_with(b"A Cypherpunk's Manifesto"));
5744    /// #       assert!(pp.buffer_unread_content()?
5745    /// #                   .starts_with(b"A Cypherpunk's Manifesto"));
5746    ///         if let Packet::Literal(l) = &pp.packet {
5747    ///             assert!(l.body().starts_with(b"A Cypherpunk's Manifesto"));
5748    ///             assert_eq!(l.body().len(), 5158);
5749    ///         } else {
5750    ///             unreachable!();
5751    ///         }
5752    ///     }
5753    ///
5754    ///     // Start parsing the next packet, recursing.
5755    ///     ppr = pp.recurse()?.1;
5756    /// }
5757    /// # Ok(()) }
5758    /// ```
5759    pub fn buffer_unread_content(&mut self) -> Result<&[u8]> {
5760        let rest = self.steal_eof()?;
5761
5762        fn set_or_extend(rest: Vec<u8>, c: &mut Container, processed: bool)
5763                         -> Result<&[u8]> {
5764            if !rest.is_empty() {
5765                let current = match c.body() {
5766                    Body::Unprocessed(bytes) => &bytes[..],
5767                    Body::Processed(bytes) => &bytes[..],
5768                    Body::Structured(packets) if packets.is_empty() => &[][..],
5769                    Body::Structured(_) => return Err(Error::InvalidOperation(
5770                        "cannot append unread bytes to parsed packets"
5771                            .into()).into()),
5772                };
5773                let rest = if !current.is_empty() {
5774                    let mut new =
5775                        Vec::with_capacity(current.len() + rest.len());
5776                    new.extend_from_slice(current);
5777                    new.extend_from_slice(&rest);
5778                    new
5779                } else {
5780                    rest
5781                };
5782
5783                c.set_body(if processed {
5784                    Body::Processed(rest)
5785                } else {
5786                    Body::Unprocessed(rest)
5787                });
5788            }
5789
5790            match c.body() {
5791                Body::Unprocessed(bytes) => Ok(bytes),
5792                Body::Processed(bytes) => Ok(bytes),
5793                Body::Structured(packets) if packets.is_empty() => Ok(&[][..]),
5794                Body::Structured(_) => Err(Error::InvalidOperation(
5795                    "cannot append unread bytes to parsed packets"
5796                        .into()).into()),
5797            }
5798        }
5799
5800        match &mut self.packet {
5801            Packet::Literal(p) => set_or_extend(rest, p.container_mut(), false),
5802            Packet::Unknown(p) => set_or_extend(rest, p.container_mut(), false),
5803            Packet::CompressedData(p) =>
5804                set_or_extend(rest, p.container_mut(), self.processed),
5805            Packet::SEIP(SEIP::V1(p)) =>
5806                set_or_extend(rest, p.container_mut(), self.processed),
5807            Packet::SEIP(SEIP::V2(p)) =>
5808                set_or_extend(rest, p.container_mut(), self.processed),
5809            p => {
5810                if !rest.is_empty() {
5811                    Err(Error::MalformedPacket(
5812                        format!("Unexpected body data for {:?}: {}",
5813                                p, crate::fmt::hex::encode_pretty(rest)))
5814                        .into())
5815                } else {
5816                    Ok(&b""[..])
5817                }
5818            },
5819        }
5820    }
5821
5822    /// Finishes parsing the current packet.
5823    ///
5824    /// By default, this drops any unread content.  Use, for instance,
5825    /// [`PacketParserBuilder`] to customize the default behavior.
5826    ///
5827    ///
5828    /// # Examples
5829    ///
5830    /// ```rust
5831    /// # fn main() -> sequoia_openpgp::Result<()> {
5832    /// use sequoia_openpgp as openpgp;
5833    /// use openpgp::Packet;
5834    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
5835    ///
5836    /// // Parse a message.
5837    /// let message_data: &[u8] = // ...
5838    /// #    include_bytes!("../tests/data/messages/compressed-data-algo-0.pgp");
5839    /// let mut ppr = PacketParser::from_bytes(message_data)?;
5840    /// while let PacketParserResult::Some(mut pp) = ppr {
5841    ///     let p = pp.finish()?;
5842    /// #   let _ = p;
5843    ///
5844    ///     // Start parsing the next packet, recursing.
5845    ///     ppr = pp.recurse()?.1;
5846    /// }
5847    /// # Ok(()) }
5848    // Note: this function is public and may be called multiple times!
5849    pub fn finish(&mut self) -> Result<&Packet> {
5850        let indent = self.recursion_depth();
5851        tracer!(TRACE, "PacketParser::finish", indent);
5852
5853        if self.finished {
5854            return Ok(&self.packet);
5855        }
5856
5857        let recursion_depth = self.recursion_depth();
5858
5859        let unread_content = if self.state.settings.buffer_unread_content {
5860            t!("({:?} at depth {}): buffering {} bytes of unread content",
5861               self.packet.tag(), recursion_depth,
5862               self.data_eof().unwrap_or(&[]).len());
5863
5864            !self.buffer_unread_content()?.is_empty()
5865        } else {
5866            t!("({:?} at depth {}): dropping {} bytes of unread content",
5867               self.packet.tag(), recursion_depth,
5868               self.data_eof().unwrap_or(&[]).len());
5869
5870            self.drop_eof()?
5871        };
5872
5873        if unread_content {
5874            match self.packet.tag() {
5875                Tag::SEIP | Tag::AED | Tag::SED | Tag::CompressedData => {
5876                    // We didn't (fully) process a container's content.  Add
5877                    // this as opaque content to the message validator.
5878                    let mut path = self.path().to_vec();
5879                    path.push(0);
5880                    self.state.message_validator.push_token(
5881                        message::Token::OpaqueContent, &path);
5882                }
5883                _ => {},
5884            }
5885        }
5886
5887        if let Some(c) = self.packet.container_mut() {
5888            let h = self.body_hash.take()
5889                .expect("body_hash is Some");
5890            c.set_body_hash(h);
5891        }
5892
5893        self.finished = true;
5894
5895        Ok(&self.packet)
5896    }
5897
5898    /// Hashes content that has been streamed.
5899    fn hash_read_content(&mut self, b: &[u8]) {
5900        if !b.is_empty() {
5901            assert!(self.body_hash.is_some());
5902            if let Some(h) = self.body_hash.as_mut() {
5903                h.update(b);
5904            }
5905            self.content_was_read = true;
5906        }
5907    }
5908
5909    /// Returns a reference to the current packet's header.
5910    ///
5911    /// # Examples
5912    ///
5913    /// ```rust
5914    /// # fn main() -> sequoia_openpgp::Result<()> {
5915    /// use sequoia_openpgp as openpgp;
5916    /// use openpgp::Packet;
5917    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
5918    ///
5919    /// // Parse a message.
5920    /// let message_data: &[u8] = // ...
5921    /// #    include_bytes!("../tests/data/messages/compressed-data-algo-0.pgp");
5922    /// let mut ppr = PacketParser::from_bytes(message_data)?;
5923    /// while let PacketParserResult::Some(mut pp) = ppr {
5924    ///     pp.header().valid(false)?;
5925    ///
5926    ///     // Start parsing the next packet, recursing.
5927    ///     ppr = pp.recurse()?.1;
5928    /// }
5929    /// # Ok(()) }
5930    /// ```
5931    pub fn header(&self) -> &Header {
5932        &self.header
5933    }
5934
5935    /// Returns a reference to the map (if any is written).
5936    ///
5937    /// # Examples
5938    ///
5939    /// ```
5940    /// # fn main() -> sequoia_openpgp::Result<()> {
5941    /// use sequoia_openpgp as openpgp;
5942    /// use openpgp::parse::{Parse, PacketParserBuilder};
5943    ///
5944    /// let message_data = b"\xcb\x12t\x00\x00\x00\x00\x00Hello world.";
5945    /// let pp = PacketParserBuilder::from_bytes(message_data)?
5946    ///     .map(true) // Enable mapping.
5947    ///     .build()?
5948    ///     .expect("One packet, not EOF");
5949    /// let map = pp.map().expect("Mapping is enabled");
5950    ///
5951    /// assert_eq!(map.iter().nth(0).unwrap().name(), "CTB");
5952    /// assert_eq!(map.iter().nth(0).unwrap().offset(), 0);
5953    /// assert_eq!(map.iter().nth(0).unwrap().as_bytes(), &[0xcb]);
5954    /// # Ok(()) }
5955    /// ```
5956    pub fn map(&self) -> Option<&map::Map> {
5957        self.map.as_ref()
5958    }
5959
5960    /// Takes the map (if any is written).
5961    ///
5962    /// # Examples
5963    ///
5964    /// ```
5965    /// # fn main() -> sequoia_openpgp::Result<()> {
5966    /// use sequoia_openpgp as openpgp;
5967    /// use openpgp::parse::{Parse, PacketParserBuilder};
5968    ///
5969    /// let message_data = b"\xcb\x12t\x00\x00\x00\x00\x00Hello world.";
5970    /// let mut pp = PacketParserBuilder::from_bytes(message_data)?
5971    ///     .map(true) // Enable mapping.
5972    ///     .build()?
5973    ///     .expect("One packet, not EOF");
5974    /// let map = pp.take_map().expect("Mapping is enabled");
5975    ///
5976    /// assert_eq!(map.iter().nth(0).unwrap().name(), "CTB");
5977    /// assert_eq!(map.iter().nth(0).unwrap().offset(), 0);
5978    /// assert_eq!(map.iter().nth(0).unwrap().as_bytes(), &[0xcb]);
5979    /// # Ok(()) }
5980    /// ```
5981    pub fn take_map(&mut self) -> Option<map::Map> {
5982        self.map.take()
5983    }
5984
5985    /// Checks if we are processing a message encoded using the
5986    /// Cleartext Signature Framework.
5987    ///
5988    /// By default, the `PacketParser` does not parse messages encoded
5989    /// using the signature framework.  (If it encounters such a
5990    /// message, it only returns the `Signature`).  Use
5991    /// [`PacketParserBuilder::process_csf_message`] to enable parsing
5992    /// messages encoded using the [cleartext signature
5993    /// framework](https://www.rfc-editor.org/rfc/rfc9580.html#name-cleartext-signature-framew).
5994    pub fn processing_csf_message(&self) -> bool {
5995        Cookie::processing_csf_message(&self.reader)
5996    }
5997}
5998
5999/// This interface allows a caller to read the content of a
6000/// `PacketParser` using the `Read` interface.  This is essential to
6001/// supporting streaming operation.
6002///
6003/// Note: it is safe to mix the use of the `std::io::Read` and
6004/// `BufferedReader` interfaces.
6005impl<'a> io::Read for PacketParser<'a> {
6006    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
6007        // The BufferedReader interface takes care of hashing the read
6008        // values.
6009        buffered_reader_generic_read_impl(self, buf)
6010    }
6011}
6012
6013/// This interface allows a caller to read the content of a
6014/// `PacketParser` using the `BufferedReader` interface.  This is
6015/// essential to supporting streaming operation.
6016///
6017/// Note: it is safe to mix the use of the `std::io::Read` and
6018/// `BufferedReader` interfaces.
6019impl<'a> BufferedReader<Cookie> for PacketParser<'a> {
6020    fn buffer(&self) -> &[u8] {
6021        self.reader.buffer()
6022    }
6023
6024    fn data(&mut self, amount: usize) -> io::Result<&[u8]> {
6025        // There is no need to set `content_was_read`, because this
6026        // doesn't actually consume any data.
6027        self.reader.data(amount)
6028    }
6029
6030    fn data_hard(&mut self, amount: usize) -> io::Result<&[u8]> {
6031        // There is no need to set `content_was_read`, because this
6032        // doesn't actually consume any data.
6033        self.reader.data_hard(amount)
6034    }
6035
6036    fn data_eof(&mut self) -> io::Result<&[u8]> {
6037        // There is no need to set `content_was_read`, because this
6038        // doesn't actually consume any data.
6039        self.reader.data_eof()
6040    }
6041
6042    fn consume(&mut self, amount: usize) -> &[u8] {
6043        // This is awkward.  Juggle mutable references around.
6044        if let Some(mut body_hash) = self.body_hash.take() {
6045            let data = self.data_hard(amount)
6046                .expect("It is an error to consume more than data returns");
6047            body_hash.update(&data[..amount]);
6048            self.body_hash = Some(body_hash);
6049            self.content_was_read |= amount > 0;
6050        } else {
6051            panic!("body_hash is None");
6052        }
6053
6054        self.reader.consume(amount)
6055    }
6056
6057    fn data_consume(&mut self, mut amount: usize) -> io::Result<&[u8]> {
6058        // This is awkward.  Juggle mutable references around.
6059        if let Some(mut body_hash) = self.body_hash.take() {
6060            let data = self.data(amount)?;
6061            amount = cmp::min(data.len(), amount);
6062            body_hash.update(&data[..amount]);
6063            self.body_hash = Some(body_hash);
6064            self.content_was_read |= amount > 0;
6065        } else {
6066            panic!("body_hash is None");
6067        }
6068
6069        self.reader.data_consume(amount)
6070    }
6071
6072    fn data_consume_hard(&mut self, amount: usize) -> io::Result<&[u8]> {
6073        // This is awkward.  Juggle mutable references around.
6074        if let Some(mut body_hash) = self.body_hash.take() {
6075            let data = self.data_hard(amount)?;
6076            body_hash.update(&data[..amount]);
6077            self.body_hash = Some(body_hash);
6078            self.content_was_read |= amount > 0;
6079        } else {
6080            panic!("body_hash is None");
6081        }
6082
6083        self.reader.data_consume_hard(amount)
6084    }
6085
6086    fn steal(&mut self, amount: usize) -> io::Result<Vec<u8>> {
6087        let v = self.reader.steal(amount)?;
6088        self.hash_read_content(&v);
6089        Ok(v)
6090    }
6091
6092    fn steal_eof(&mut self) -> io::Result<Vec<u8>> {
6093        let v = self.reader.steal_eof()?;
6094        self.hash_read_content(&v);
6095        Ok(v)
6096    }
6097
6098    fn get_mut(&mut self) -> Option<&mut dyn BufferedReader<Cookie>> {
6099        None
6100    }
6101
6102    fn get_ref(&self) -> Option<&dyn BufferedReader<Cookie>> {
6103        None
6104    }
6105
6106    fn into_inner<'b>(self: Box<Self>)
6107            -> Option<Box<dyn BufferedReader<Cookie> + 'b>>
6108            where Self: 'b {
6109        None
6110    }
6111
6112    fn cookie_set(&mut self, cookie: Cookie)
6113            -> Cookie {
6114        self.reader.cookie_set(cookie)
6115    }
6116
6117    fn cookie_ref(&self) -> &Cookie {
6118        self.reader.cookie_ref()
6119    }
6120
6121    fn cookie_mut(&mut self) -> &mut Cookie {
6122        self.reader.cookie_mut()
6123    }
6124}
6125
6126// Check that we can use the read interface to stream the contents of
6127// a packet.
6128#[cfg(feature = "compression-deflate")]
6129#[test]
6130fn packet_parser_reader_interface() {
6131    // We need the Read trait.
6132    use std::io::Read;
6133
6134    let expected = crate::tests::manifesto();
6135
6136    // A message containing a compressed packet that contains a
6137    // literal packet.
6138    let pp = PacketParser::from_bytes(
6139        crate::tests::message("compressed-data-algo-1.pgp")).unwrap().unwrap();
6140
6141    // The message has the form:
6142    //
6143    //   [ compressed data [ literal data ] ]
6144    //
6145    // packet is the compressed data packet; ppo is the literal data
6146    // packet.
6147    let packet_depth = pp.recursion_depth();
6148    let (packet, ppr) = pp.recurse().unwrap();
6149    let pp_depth = ppr.as_ref().unwrap().recursion_depth();
6150    if let Packet::CompressedData(_) = packet {
6151    } else {
6152        panic!("Expected a compressed data packet.");
6153    }
6154
6155    let relative_position = pp_depth - packet_depth;
6156    assert_eq!(relative_position, 1);
6157
6158    let mut pp = ppr.unwrap();
6159
6160    if let Packet::Literal(_) = pp.packet {
6161    } else {
6162        panic!("Expected a literal data packet.");
6163    }
6164
6165    // Check that we can read the packet's contents.  We do this one
6166    // byte at a time to exercise the cursor implementation.
6167    for i in 0..expected.len() {
6168        let mut buf = [0u8; 1];
6169        let r = pp.read(&mut buf).unwrap();
6170        assert_eq!(r, 1);
6171        assert_eq!(buf[0], expected[i]);
6172    }
6173    // And, now an EOF.
6174    let mut buf = [0u8; 1];
6175    let r = pp.read(&mut buf).unwrap();
6176    assert_eq!(r, 0);
6177
6178    // Make sure we can still get the next packet (which in this case
6179    // is just EOF).
6180    let (packet, ppr) = pp.recurse().unwrap();
6181    assert!(ppr.is_eof());
6182    // Since we read all the data, we expect content to be None.
6183    assert_eq!(packet.unprocessed_body().unwrap().len(), 0);
6184}
6185
6186impl<'a> PacketParser<'a> {
6187    /// Tries to decrypt the current packet.
6188    ///
6189    /// On success, this function pushes one or more readers onto the
6190    /// `PacketParser`'s reader stack, and sets the packet parser's
6191    /// `processed` flag (see [`PacketParser::processed`]).
6192    ///
6193    ///   [`PacketParser::processed`]: PacketParser::processed()
6194    ///
6195    /// If this function is called on a packet that does not contain
6196    /// encrypted data, or some of the data was already read, then it
6197    /// returns [`Error::InvalidOperation`].
6198    ///
6199    ///   [`Error::InvalidOperation`]: super::Error::InvalidOperation
6200    ///
6201    /// # Examples
6202    ///
6203    /// ```rust
6204    /// # fn main() -> sequoia_openpgp::Result<()> {
6205    /// use sequoia_openpgp as openpgp;
6206    /// use openpgp::Packet;
6207    /// use openpgp::fmt::hex;
6208    /// use openpgp::types::SymmetricAlgorithm;
6209    /// use openpgp::parse::{Parse, PacketParserResult, PacketParser};
6210    ///
6211    /// // Parse an encrypted message.
6212    /// let message_data: &[u8] = // ...
6213    /// #    include_bytes!("../tests/data/messages/encrypted-aes256-password-123.pgp");
6214    /// let mut ppr = PacketParser::from_bytes(message_data)?;
6215    /// while let PacketParserResult::Some(mut pp) = ppr {
6216    ///     if let Packet::SEIP(_) = pp.packet {
6217    ///         pp.decrypt(SymmetricAlgorithm::AES256,
6218    ///                    &hex::decode("7EF4F08C44F780BEA866961423306166\
6219    ///                                  B8912C43352F3D9617F745E4E3939710")?
6220    ///                        .into())?;
6221    ///     }
6222    ///
6223    ///     // Start parsing the next packet, recursing.
6224    ///     ppr = pp.recurse()?.1;
6225    /// }
6226    /// # Ok(()) }
6227    /// ```
6228    ///
6229    /// # Security Considerations
6230    ///
6231    /// This functions returns rich errors in case the decryption
6232    /// fails.  In combination with certain asymmetric algorithms
6233    /// (RSA), this may lead to compromise of secret key material or
6234    /// (partial) recovery of the message's plain text.  See [Section
6235    /// 13 of RFC 9580].
6236    ///
6237    ///   [Section 13 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-13
6238    ///
6239    /// DO NOT relay these errors in situations where an attacker can
6240    /// request decryption of messages in an automated fashion.  The
6241    /// API of the streaming [`Decryptor`] prevents leaking rich
6242    /// decryption errors.
6243    ///
6244    ///   [`Decryptor`]: stream::Decryptor
6245    ///
6246    /// Nevertheless, decrypting messages that do not use an
6247    /// authenticated encryption mode in an automated fashion that
6248    /// relays or leaks information to a third party is NEVER SAFE due
6249    /// to unavoidable format oracles, see [Format Oracles on
6250    /// OpenPGP].
6251    ///
6252    ///   [Format Oracles on OpenPGP]: https://www.ssi.gouv.fr/uploads/2015/05/format-Oracles-on-OpenPGP.pdf
6253    pub fn decrypt<A>(&mut self, algo: A, key: &SessionKey)
6254                      -> Result<()>
6255    where
6256        A: Into<Option<SymmetricAlgorithm>>,
6257    {
6258        self.decrypt_(algo.into(), key)
6259    }
6260
6261    fn decrypt_(&mut self,
6262                algo: Option<SymmetricAlgorithm>,
6263                key: &SessionKey)
6264                -> Result<()>
6265    {
6266        let indent = self.recursion_depth();
6267        tracer!(TRACE, "PacketParser::decrypt", indent);
6268
6269        if self.content_was_read {
6270            return Err(Error::InvalidOperation(
6271                "Packet's content has already been read.".to_string()).into());
6272        }
6273        if self.processed {
6274            return Err(Error::InvalidOperation(
6275                "Packet not encrypted.".to_string()).into());
6276        }
6277
6278        match self.packet.clone() {
6279            Packet::SEIP(SEIP::V1(_)) => {
6280                use crate::crypto::symmetric::{
6281                    BlockCipherMode,
6282                    UnpaddingMode,
6283                };
6284
6285                let algo = if let Some(a) = algo {
6286                    a
6287                } else {
6288                    return Err(Error::InvalidOperation(
6289                        "Trying to decrypt a SEIPDv1 packet: \
6290                         no symmetric algorithm given".into()).into());
6291                };
6292
6293                if algo.key_size()? != key.len () {
6294                    return Err(Error::InvalidOperation(
6295                        format!("Bad key size: {} expected: {}",
6296                                key.len(), algo.key_size()?)).into());
6297                }
6298
6299                // Get the first blocksize plus two bytes and check
6300                // whether we can decrypt them using the provided key.
6301                // Don't actually consume them in case we can't.
6302                let bl = algo.block_size()?;
6303
6304                {
6305                    let cur = buffered_reader::Memory::with_cookie(
6306                        &self.data_hard(bl + 2)?[..bl + 2],
6307                        Default::default());
6308                    let mut dec = InternalDecryptor::new(
6309                        algo, BlockCipherMode::CFB, UnpaddingMode::None,
6310                        key, None, cur)?;
6311                    let mut header = vec![ 0u8; bl + 2 ];
6312                    dec.read_exact(&mut header)?;
6313
6314                    if !(header[bl - 2] == header[bl]
6315                         && header[bl - 1] == header[bl + 1]) {
6316                        return Err(Error::InvalidSessionKey(
6317                            "Decryption failed".into()).into());
6318                    }
6319                }
6320
6321                // Ok, we can decrypt the data.  Push a Decryptor and
6322                // a HashedReader on the `BufferedReader` stack.
6323
6324                // This can't fail, because we create a decryptor
6325                // above with the same parameters.
6326                let reader = self.take_reader();
6327                let mut reader = Decryptor::with_cookie(
6328                    algo, BlockCipherMode::CFB, UnpaddingMode::None,
6329                    key, None, reader, Cookie::default())?;
6330                reader.cookie_mut().level = Some(self.recursion_depth());
6331
6332                t!("Pushing Decryptor, level {:?}.", reader.cookie_ref().level);
6333
6334                // And the hasher.
6335                let mut reader = HashedReader::new(
6336                    reader, HashesFor::MDC,
6337                    vec![HashingMode::Binary(vec![], HashAlgorithm::SHA1)])?;
6338                reader.cookie_mut().level = Some(self.recursion_depth());
6339
6340                t!("Pushing HashedReader, level {:?}.",
6341                   reader.cookie_ref().level);
6342
6343                // A SEIP packet is a container that always ends with
6344                // an MDC packet.  But, if the packet preceding the
6345                // MDC packet uses an indeterminate length encoding
6346                // (gpg generates these for compressed data packets,
6347                // for instance), the parser has to detect the EOF and
6348                // be careful to not read any further.  Unfortunately,
6349                // our decompressor buffers the data.  To stop the
6350                // decompressor from buffering the MDC packet, we use
6351                // a buffered_reader::Reserve.  Note: we do this
6352                // unconditionally, since it doesn't otherwise
6353                // interfere with parsing.
6354
6355                // An MDC consists of a 1-byte CTB, a 1-byte length
6356                // encoding, and a 20-byte hash.
6357                let mut reader = buffered_reader::Reserve::with_cookie(
6358                    reader, 1 + 1 + 20,
6359                    Cookie::new(self.recursion_depth()));
6360                reader.cookie_mut().fake_eof = true;
6361
6362                t!("Pushing buffered_reader::Reserve, level: {}.",
6363                   self.recursion_depth());
6364
6365                // Consume the header.  This shouldn't fail, because
6366                // it worked when reading the header.
6367                reader.data_consume_hard(bl + 2).unwrap();
6368
6369                self.reader = Box::new(reader);
6370                self.processed = true;
6371
6372                Ok(())
6373            },
6374
6375            Packet::SEIP(SEIP::V2(seip)) => {
6376                let chunk_size =
6377                    aead::chunk_size_usize(seip.chunk_size())?;
6378
6379                let schedule = aead::SEIPv2Schedule::new(
6380                    key,
6381                    seip.symmetric_algo(),
6382                    seip.aead(),
6383                    chunk_size,
6384                    seip.salt())?;
6385
6386                // Read the first chunk and check whether we can
6387                // decrypt it using the provided key.  Don't actually
6388                // consume them in case we can't.
6389                {
6390                    // We need a bit more than one chunk so that
6391                    // `aead::Decryptor` won't see EOF and think that
6392                    // it has a partial block and it needs to verify
6393                    // the final chunk.
6394                    let amount = aead::chunk_size_usize(
6395                        seip.chunk_digest_size()?
6396                        + seip.aead().digest_size()? as u64)?;
6397
6398                    let data = self.data(amount)?;
6399                    let cur = buffered_reader::Memory::with_cookie(
6400                        &data[..cmp::min(data.len(), amount)],
6401                        Default::default());
6402
6403                    let dec = aead::InternalDecryptor::new(
6404                        seip.symmetric_algo(), seip.aead(), chunk_size,
6405                        schedule.clone(),
6406                        cur)?;
6407                    let mut chunk = Vec::new();
6408                    dec.take(seip.chunk_size() as u64).read_to_end(&mut chunk)?;
6409                }
6410
6411                // Ok, we can decrypt the data.  Push a Decryptor and
6412                // a HashedReader on the `BufferedReader` stack.
6413
6414                let reader = self.take_reader();
6415                let mut reader = aead::Decryptor::with_cookie(
6416                    seip.symmetric_algo(), seip.aead(), chunk_size,
6417                    schedule, reader, Cookie::default()).unwrap();
6418                reader.cookie_mut().level = Some(self.recursion_depth());
6419
6420                t!("Pushing aead::Decryptor, level {:?}.",
6421                   reader.cookie_ref().level);
6422
6423                self.reader = Box::new(reader);
6424                self.processed = true;
6425
6426                Ok(())
6427            },
6428
6429            _ =>
6430                Err(Error::InvalidOperation(
6431                    format!("Can't decrypt {:?} packets.",
6432                            self.packet.tag())).into())
6433        }
6434    }
6435}
6436
6437#[cfg(test)]
6438mod test {
6439    use super::*;
6440    use crate::serialize::Serialize;
6441
6442    enum Data<'a> {
6443        File(&'a str),
6444        String(&'a [u8]),
6445    }
6446
6447    impl<'a> Data<'a> {
6448        fn content(&self) -> Vec<u8> {
6449            match self {
6450                Data::File(filename) => crate::tests::message(filename).to_vec(),
6451                Data::String(data) => data.to_vec(),
6452            }
6453        }
6454    }
6455
6456    struct DecryptTest<'a> {
6457        filename: &'a str,
6458        algo: SymmetricAlgorithm,
6459        aead_algo: Option<AEADAlgorithm>,
6460        key_hex: &'a str,
6461        plaintext: Data<'a>,
6462        paths: &'a[ (Tag, &'a[ usize ] ) ],
6463    }
6464    const DECRYPT_TESTS: &[DecryptTest] = &[
6465        // Messages with a relatively simple structure:
6466        //
6467        //   [ SKESK SEIP [ Literal MDC ] ].
6468        //
6469        // And simple length encodings (no indeterminate length
6470        // encodings).
6471        DecryptTest {
6472            filename: "encrypted-aes256-password-123.pgp",
6473            algo: SymmetricAlgorithm::AES256,
6474            aead_algo: None,
6475            key_hex: "7EF4F08C44F780BEA866961423306166B8912C43352F3D9617F745E4E3939710",
6476            plaintext: Data::File("a-cypherpunks-manifesto.txt"),
6477            paths: &[
6478                (Tag::SKESK, &[ 0 ]),
6479                (Tag::SEIP, &[ 1 ]),
6480                (Tag::Literal, &[ 1, 0 ]),
6481                (Tag::MDC, &[ 1, 1 ]),
6482            ],
6483        },
6484        DecryptTest {
6485            filename: "encrypted-aes192-password-123456.pgp",
6486            algo: SymmetricAlgorithm::AES192,
6487            aead_algo: None,
6488            key_hex: "B2F747F207EFF198A6C826F1D398DE037986218ED468DB61",
6489            plaintext: Data::File("a-cypherpunks-manifesto.txt"),
6490            paths: &[
6491                (Tag::SKESK, &[ 0 ]),
6492                (Tag::SEIP, &[ 1 ]),
6493                (Tag::Literal, &[ 1, 0 ]),
6494                (Tag::MDC, &[ 1, 1 ]),
6495            ],
6496        },
6497        DecryptTest {
6498            filename: "encrypted-aes128-password-123456789.pgp",
6499            algo: SymmetricAlgorithm::AES128,
6500            aead_algo: None,
6501            key_hex: "AC0553096429260B4A90B1CEC842D6A0",
6502            plaintext: Data::File("a-cypherpunks-manifesto.txt"),
6503            paths: &[
6504                (Tag::SKESK, &[ 0 ]),
6505                (Tag::SEIP, &[ 1 ]),
6506                (Tag::Literal, &[ 1, 0 ]),
6507                (Tag::MDC, &[ 1, 1 ]),
6508            ],
6509        },
6510
6511        // Created using:
6512        //
6513        //     gpg --compression-algo none \
6514        //         --s2k-digest-algo sha256 \
6515        //         --cipher-algo camellia256 \
6516        //         --s2k-cipher-algo camellia256 \
6517        //         --encrypt --symmetric \
6518        //         -o encrypted-camellia256-password-123.pgp \
6519        //         a-cypherpunks-manifesto.txt
6520        DecryptTest {
6521            filename: "encrypted-camellia256-password-123.pgp",
6522            algo: SymmetricAlgorithm::Camellia256,
6523            aead_algo: None,
6524            key_hex: "FC9644B500B9D0540880CB44B40F8C89\
6525                      A7D817F2EF7EF9DA0D34A574377E300A",
6526            plaintext: Data::File("a-cypherpunks-manifesto.txt"),
6527            paths: &[
6528                (Tag::SKESK, &[ 0 ]),
6529                (Tag::SEIP, &[ 1 ]),
6530                (Tag::Literal, &[ 1, 0 ]),
6531                (Tag::MDC, &[ 1, 1 ]),
6532            ],
6533        },
6534        DecryptTest {
6535            filename: "encrypted-camellia192-password-123.pgp",
6536            algo: SymmetricAlgorithm::Camellia192,
6537            aead_algo: None,
6538            key_hex: "EC941DB1C5F4D3605E3F3C10B30888DA3287256E55CC978B",
6539            plaintext: Data::File("a-cypherpunks-manifesto.txt"),
6540            paths: &[
6541                (Tag::SKESK, &[ 0 ]),
6542                (Tag::SEIP, &[ 1 ]),
6543                (Tag::Literal, &[ 1, 0 ]),
6544                (Tag::MDC, &[ 1, 1 ]),
6545            ],
6546        },
6547        DecryptTest {
6548            filename: "encrypted-camellia128-password-123.pgp",
6549            algo: SymmetricAlgorithm::Camellia128,
6550            aead_algo: None,
6551            key_hex: "E1CF87BF2E030CC89CBC0F03EC2B7DF5",
6552            plaintext: Data::File("a-cypherpunks-manifesto.txt"),
6553            paths: &[
6554                (Tag::SKESK, &[ 0 ]),
6555                (Tag::SEIP, &[ 1 ]),
6556                (Tag::Literal, &[ 1, 0 ]),
6557                (Tag::MDC, &[ 1, 1 ]),
6558            ],
6559        },
6560
6561        DecryptTest {
6562            filename: "encrypted-twofish-password-red-fish-blue-fish.pgp",
6563            algo: SymmetricAlgorithm::Twofish,
6564            aead_algo: None,
6565            key_hex: "96AFE1EDFA7C9CB7E8B23484C718015E5159CFA268594180D4DB68B2543393CB",
6566            plaintext: Data::File("a-cypherpunks-manifesto.txt"),
6567            paths: &[
6568                (Tag::SKESK, &[ 0 ]),
6569                (Tag::SEIP, &[ 1 ]),
6570                (Tag::Literal, &[ 1, 0 ]),
6571                (Tag::MDC, &[ 1, 1 ]),
6572            ],
6573        },
6574
6575        // More complex messages.  In particular, some of these
6576        // messages include compressed data packets, and some are
6577        // signed.  But what makes these particularly complex is the
6578        // use of an indeterminate length encoding, which checks the
6579        // buffered_reader::Reserve hack.
6580        #[cfg(feature = "compression-deflate")]
6581        DecryptTest {
6582            filename: "seip/msg-compression-not-signed-password-123.pgp",
6583            algo: SymmetricAlgorithm::AES128,
6584            aead_algo: None,
6585            key_hex: "86A8C1C7961F55A3BE181A990D0ABB2A",
6586            plaintext: Data::String(b"compression, not signed\n"),
6587            paths: &[
6588                (Tag::SKESK, &[ 0 ]),
6589                (Tag::SEIP, &[ 1 ]),
6590                (Tag::CompressedData, &[ 1, 0 ]),
6591                (Tag::Literal, &[ 1, 0, 0 ]),
6592                (Tag::MDC, &[ 1, 1 ]),
6593            ],
6594        },
6595        #[cfg(feature = "compression-deflate")]
6596        DecryptTest {
6597            filename: "seip/msg-compression-signed-password-123.pgp",
6598            algo: SymmetricAlgorithm::AES128,
6599            aead_algo: None,
6600            key_hex: "1B195CD35CAD4A99D9399B4CDA4CDA4E",
6601            plaintext: Data::String(b"compression, signed\n"),
6602            paths: &[
6603                (Tag::SKESK, &[ 0 ]),
6604                (Tag::SEIP, &[ 1 ]),
6605                (Tag::CompressedData, &[ 1, 0 ]),
6606                (Tag::OnePassSig, &[ 1, 0, 0 ]),
6607                (Tag::Literal, &[ 1, 0, 1 ]),
6608                (Tag::Signature, &[ 1, 0, 2 ]),
6609                (Tag::MDC, &[ 1, 1 ]),
6610            ],
6611        },
6612        DecryptTest {
6613            filename: "seip/msg-no-compression-not-signed-password-123.pgp",
6614            algo: SymmetricAlgorithm::AES128,
6615            aead_algo: None,
6616            key_hex: "AFB43B83A4B9D971E4B4A4C53749076A",
6617            plaintext: Data::String(b"no compression, not signed\n"),
6618            paths: &[
6619                (Tag::SKESK, &[ 0 ]),
6620                (Tag::SEIP, &[ 1 ]),
6621                (Tag::Literal, &[ 1, 0 ]),
6622                (Tag::MDC, &[ 1, 1 ]),
6623            ],
6624        },
6625        DecryptTest {
6626            filename: "seip/msg-no-compression-signed-password-123.pgp",
6627            algo: SymmetricAlgorithm::AES128,
6628            aead_algo: None,
6629            key_hex: "9D5DB92F77F0E4A356EE53813EF2C3DC",
6630            plaintext: Data::String(b"no compression, signed\n"),
6631            paths: &[
6632                (Tag::SKESK, &[ 0 ]),
6633                (Tag::SEIP, &[ 1 ]),
6634                (Tag::OnePassSig, &[ 1, 0 ]),
6635                (Tag::Literal, &[ 1, 1 ]),
6636                (Tag::Signature, &[ 1, 2 ]),
6637                (Tag::MDC, &[ 1, 3 ]),
6638            ],
6639        },
6640    ];
6641
6642    // Consume packets until we get to one in `keep`.
6643    fn consume_until<'a>(mut ppr: PacketParserResult<'a>,
6644                         ignore_first: bool, keep: &[Tag], skip: &[Tag])
6645        -> PacketParserResult<'a>
6646    {
6647        if ignore_first {
6648            ppr = ppr.unwrap().recurse().unwrap().1;
6649        }
6650
6651        while let PacketParserResult::Some(pp) = ppr {
6652            let tag = pp.packet.tag();
6653            for t in keep.iter() {
6654                if *t == tag {
6655                    return PacketParserResult::Some(pp);
6656                }
6657            }
6658
6659            let mut ok = false;
6660            for t in skip.iter() {
6661                if *t == tag {
6662                    ok = true;
6663                }
6664            }
6665            if !ok {
6666                panic!("Packet not in keep ({:?}) or skip ({:?}) set: {:?}",
6667                       keep, skip, pp.packet);
6668            }
6669
6670            ppr = pp.recurse().unwrap().1;
6671        }
6672        ppr
6673    }
6674
6675    #[test]
6676    fn decrypt_test() {
6677        decrypt_test_common(false);
6678    }
6679
6680    #[test]
6681    fn decrypt_test_stream() {
6682        decrypt_test_common(true);
6683    }
6684
6685    #[allow(deprecated)]
6686    fn decrypt_test_common(stream: bool) {
6687        for test in DECRYPT_TESTS.iter() {
6688            if !test.algo.is_supported() {
6689                eprintln!("Algorithm {} unsupported, skipping", test.algo);
6690                continue;
6691            }
6692
6693            if let Some(aead_algo) = test.aead_algo {
6694                if !aead_algo.is_supported() {
6695                    eprintln!("AEAD algorithm {} unsupported by
6696                               selected crypto backend, skipping", aead_algo);
6697                    continue;
6698                }
6699            }
6700
6701            eprintln!("Decrypting {}, streaming content: {}",
6702                      test.filename, stream);
6703
6704            let ppr = PacketParserBuilder::from_bytes(
6705                crate::tests::message(test.filename)).unwrap()
6706                .buffer_unread_content()
6707                .build()
6708                .unwrap_or_else(|_| panic!("Error reading {}", test.filename));
6709
6710            let mut ppr = consume_until(
6711                ppr, false, &[ Tag::SEIP, Tag::AED ][..],
6712                &[ Tag::SKESK, Tag::PKESK ][..] );
6713            if let PacketParserResult::Some(ref mut pp) = ppr {
6714                let key = crate::fmt::from_hex(test.key_hex, false)
6715                    .unwrap().into();
6716
6717                pp.decrypt(Some(test.algo), &key).unwrap();
6718            } else {
6719                panic!("Expected a SEIP packet.  Got: {:?}", ppr);
6720            }
6721
6722            let mut ppr = consume_until(
6723                ppr, true, &[ Tag::Literal ][..],
6724                &[ Tag::OnePassSig, Tag::CompressedData ][..]);
6725            if let PacketParserResult::Some(ref mut pp) = ppr {
6726                if stream {
6727                    let mut body = Vec::new();
6728                    loop {
6729                        let mut b = [0];
6730                        if pp.read(&mut b).unwrap() == 0 {
6731                            break;
6732                        }
6733                        body.push(b[0]);
6734                    }
6735
6736                    assert_eq!(&body[..],
6737                               &test.plaintext.content()[..],
6738                               "{:?}", pp.packet);
6739                } else {
6740                    pp.buffer_unread_content().unwrap();
6741                    if let Packet::Literal(l) = &pp.packet {
6742                        assert_eq!(l.body(), &test.plaintext.content()[..],
6743                                   "{:?}", pp.packet);
6744                    } else {
6745                        panic!("Expected literal, got: {:?}", pp.packet);
6746                    }
6747                }
6748            } else {
6749                panic!("Expected a Literal packet.  Got: {:?}", ppr);
6750            }
6751
6752            let ppr = consume_until(
6753                ppr, true, &[ Tag::MDC ][..], &[ Tag::Signature ][..]);
6754            if let PacketParserResult::Some(
6755                PacketParser { packet: Packet::MDC(ref mdc), .. }) = ppr
6756            {
6757                assert_eq!(mdc.computed_digest(), mdc.digest(),
6758                           "MDC doesn't match");
6759            }
6760
6761            if ppr.is_eof() {
6762                // AED packets don't have an MDC packet.
6763                continue;
6764            }
6765            let ppr = consume_until(
6766                ppr, true, &[][..], &[][..]);
6767            assert!(ppr.is_eof());
6768        }
6769    }
6770
6771    #[test]
6772    fn message_validator() {
6773      for marker in 0..4 {
6774        let marker_before = marker & 1 > 0;
6775        let marker_after = marker & 2 > 0;
6776
6777        for test in DECRYPT_TESTS.iter() {
6778            if !test.algo.is_supported() {
6779                eprintln!("Algorithm {} unsupported, skipping", test.algo);
6780                continue;
6781            }
6782
6783            if let Some(aead_algo) = test.aead_algo {
6784                if !aead_algo.is_supported() {
6785                    eprintln!("AEAD algorithm {} unsupported by
6786                               selected crypto backend, skipping", aead_algo);
6787                    continue;
6788                }
6789            }
6790
6791            let mut buf = Vec::new();
6792            if marker_before {
6793                Packet::Marker(Default::default()).serialize(&mut buf).unwrap();
6794            }
6795            buf.extend_from_slice(crate::tests::message(test.filename));
6796            if marker_after {
6797                Packet::Marker(Default::default()).serialize(&mut buf).unwrap();
6798            }
6799
6800            let mut ppr = PacketParserBuilder::from_bytes(&buf)
6801                .unwrap()
6802                .build()
6803                .unwrap_or_else(|_| panic!("Error reading {}", test.filename));
6804
6805            // Make sure we actually decrypted...
6806            let mut saw_literal = false;
6807            while let PacketParserResult::Some(mut pp) = ppr {
6808                pp.possible_message().unwrap();
6809
6810                match pp.packet {
6811                    Packet::SEIP(_) => {
6812                        let key = crate::fmt::from_hex(test.key_hex, false)
6813                            .unwrap().into();
6814                        pp.decrypt(Some(test.algo), &key).unwrap();
6815                    },
6816                    Packet::Literal(_) => {
6817                        assert!(! saw_literal);
6818                        saw_literal = true;
6819                    },
6820                    _ => {},
6821                }
6822
6823                ppr = pp.recurse().unwrap().1;
6824            }
6825            assert!(saw_literal);
6826            if let PacketParserResult::EOF(eof) = ppr {
6827                eof.is_message().unwrap();
6828            } else {
6829                unreachable!();
6830            }
6831        }
6832      }
6833    }
6834
6835    #[test]
6836    fn keyring_validator() {
6837      for marker in 0..4 {
6838        let marker_before = marker & 1 > 0;
6839        let marker_after = marker & 2 > 0;
6840
6841        for test in &["testy.pgp",
6842                      "lutz.pgp",
6843                      "testy-new.pgp",
6844                      "neal.pgp"]
6845        {
6846            let mut buf = Vec::new();
6847            if marker_before {
6848                Packet::Marker(Default::default()).serialize(&mut buf).unwrap();
6849            }
6850            buf.extend_from_slice(crate::tests::key("testy.pgp"));
6851            buf.extend_from_slice(crate::tests::key(test));
6852            if marker_after {
6853                Packet::Marker(Default::default()).serialize(&mut buf).unwrap();
6854            }
6855
6856            let mut ppr = PacketParserBuilder::from_bytes(&buf)
6857                .unwrap()
6858                .build()
6859                .unwrap_or_else(|_| panic!("Error reading {:?}", test));
6860
6861            while let PacketParserResult::Some(pp) = ppr {
6862                assert!(pp.possible_keyring().is_ok());
6863                ppr = pp.recurse().unwrap().1;
6864            }
6865            if let PacketParserResult::EOF(eof) = ppr {
6866                assert!(eof.is_keyring().is_ok());
6867                assert!(eof.is_cert().is_err());
6868            } else {
6869                unreachable!();
6870            }
6871        }
6872      }
6873    }
6874
6875    #[test]
6876    fn cert_validator() {
6877      for marker in 0..4 {
6878        let marker_before = marker & 1 > 0;
6879        let marker_after = marker & 2 > 0;
6880
6881        for test in &["testy.pgp",
6882                      "lutz.pgp",
6883                      "testy-new.pgp",
6884                      "neal.pgp"]
6885        {
6886            let mut buf = Vec::new();
6887            if marker_before {
6888                Packet::Marker(Default::default()).serialize(&mut buf).unwrap();
6889            }
6890            buf.extend_from_slice(crate::tests::key(test));
6891            if marker_after {
6892                Packet::Marker(Default::default()).serialize(&mut buf).unwrap();
6893            }
6894
6895            let mut ppr = PacketParserBuilder::from_bytes(&buf)
6896                .unwrap()
6897                .build()
6898                .unwrap_or_else(|_| panic!("Error reading {:?}", test));
6899
6900            while let PacketParserResult::Some(pp) = ppr {
6901                assert!(pp.possible_keyring().is_ok());
6902                assert!(pp.possible_cert().is_ok());
6903                ppr = pp.recurse().unwrap().1;
6904            }
6905            if let PacketParserResult::EOF(eof) = ppr {
6906                assert!(eof.is_keyring().is_ok());
6907                assert!(eof.is_cert().is_ok());
6908            } else {
6909                unreachable!();
6910            }
6911        }
6912      }
6913    }
6914
6915    // If we don't decrypt the SEIP packet, it shows up as opaque
6916    // content.
6917    #[test]
6918    fn message_validator_opaque_content() {
6919        for test in DECRYPT_TESTS.iter() {
6920            let mut ppr = PacketParserBuilder::from_bytes(
6921                crate::tests::message(test.filename)).unwrap()
6922                .build()
6923                .unwrap_or_else(|_| panic!("Error reading {}", test.filename));
6924
6925            let mut saw_literal = false;
6926            while let PacketParserResult::Some(pp) = ppr {
6927                assert!(pp.possible_message().is_ok());
6928
6929                match pp.packet {
6930                    Packet::Literal(_) => {
6931                        assert!(! saw_literal);
6932                        saw_literal = true;
6933                    },
6934                    _ => {},
6935                }
6936
6937                ppr = pp.recurse().unwrap().1;
6938            }
6939            assert!(! saw_literal);
6940            if let PacketParserResult::EOF(eof) = ppr {
6941                eprintln!("eof: {:?}; message: {:?}", eof, eof.is_message());
6942                assert!(eof.is_message().is_ok());
6943            } else {
6944                unreachable!();
6945            }
6946        }
6947    }
6948
6949    #[test]
6950    fn path() {
6951        for test in DECRYPT_TESTS.iter() {
6952            if !test.algo.is_supported() {
6953                eprintln!("Algorithm {} unsupported, skipping", test.algo);
6954                continue;
6955            }
6956
6957            if let Some(aead_algo) = test.aead_algo {
6958                if !aead_algo.is_supported() {
6959                    eprintln!("AEAD algorithm {} unsupported, skipping", aead_algo);
6960                    continue;
6961                }
6962            }
6963
6964            eprintln!("Decrypting {}", test.filename);
6965
6966            let mut ppr = PacketParserBuilder::from_bytes(
6967                crate::tests::message(test.filename)).unwrap()
6968                .build()
6969                .unwrap_or_else(|_| panic!("Error reading {}", test.filename));
6970
6971            let mut last_path = vec![];
6972
6973            let mut paths = test.paths.to_vec();
6974            // We pop from the end.
6975            paths.reverse();
6976
6977            while let PacketParserResult::Some(mut pp) = ppr {
6978                let path = paths.pop().expect("Message longer than expect");
6979                assert_eq!(path.0, pp.packet.tag());
6980                assert_eq!(path.1, pp.path());
6981
6982                assert_eq!(last_path, pp.last_path());
6983                last_path = pp.path.to_vec();
6984
6985                eprintln!("  {}: {:?}", pp.packet.tag(), pp.path());
6986
6987                match pp.packet {
6988                    Packet::SEIP(_) => {
6989                        let key = crate::fmt::from_hex(test.key_hex, false)
6990                            .unwrap().into();
6991
6992                        pp.decrypt(test.algo, &key).unwrap();
6993                    }
6994                    _ => (),
6995                }
6996
6997                ppr = pp.recurse().unwrap().1;
6998            }
6999            paths.reverse();
7000            assert_eq!(paths.len(), 0,
7001                       "Message shorter than expected (expecting: {:?})",
7002                       paths);
7003
7004            if let PacketParserResult::EOF(eof) = ppr {
7005                assert_eq!(last_path, eof.last_path());
7006            } else {
7007                panic!("Expect an EOF");
7008            }
7009        }
7010    }
7011
7012    #[test]
7013    fn corrupted_cert() {
7014        use crate::armor::{Reader, ReaderMode, Kind};
7015
7016        // The following Cert is corrupted about a third the way
7017        // through.  Make sure we can recover.
7018        let mut ppr = PacketParser::from_reader(
7019            Reader::from_bytes(crate::tests::key("corrupted.pgp"),
7020                               ReaderMode::Tolerant(Some(Kind::PublicKey))))
7021            .unwrap();
7022
7023        let mut sigs = 0;
7024        let mut subkeys = 0;
7025        let mut userids = 0;
7026        let mut uas = 0;
7027        let mut unknown = 0;
7028        while let PacketParserResult::Some(pp) = ppr {
7029            match pp.packet {
7030                Packet::Signature(_) => sigs += 1,
7031                Packet::PublicSubkey(_) => subkeys += 1,
7032                Packet::UserID(_) => userids += 1,
7033                Packet::UserAttribute(_) => uas += 1,
7034                Packet::Unknown(ref p) => {
7035                    dbg!(p);
7036                    unknown += 1;
7037                },
7038                _ => (),
7039            }
7040
7041            ppr = pp.next().unwrap().1;
7042        }
7043
7044        assert_eq!(sigs, 53);
7045        assert_eq!(subkeys, 3);
7046        assert_eq!(userids, 5);
7047        assert_eq!(uas, 0);
7048        assert_eq!(unknown, 2);
7049    }
7050
7051    #[test]
7052    fn junk_prefix() {
7053        // Make sure we can read the first packet.
7054        let msg = crate::tests::message("sig.pgp");
7055
7056        let ppr = PacketParserBuilder::from_bytes(msg).unwrap()
7057            .dearmor(packet_parser_builder::Dearmor::Disabled)
7058            .build();
7059        assert_match!(Ok(PacketParserResult::Some(ref _pp)) = ppr);
7060
7061
7062        // Prepend an invalid byte and make sure we fail.  Note: we
7063        // have a mechanism to skip corruption, however, that is only
7064        // activated once we've seen a good packet.  This test checks
7065        // that we don't try to recover.
7066        let mut msg2 = Vec::new();
7067        msg2.push(0);
7068        msg2.extend_from_slice(msg);
7069
7070        let ppr = PacketParserBuilder::from_bytes(&msg2[..]).unwrap()
7071            .dearmor(packet_parser_builder::Dearmor::Disabled)
7072            .build();
7073        assert_match!(Err(_) = ppr);
7074    }
7075
7076    /// Issue #141.
7077    #[test]
7078    fn truncated_packet() {
7079        for msg in &[crate::tests::message("literal-mode-b.pgp"),
7080                     crate::tests::message("literal-mode-t-partial-body.pgp"),
7081        ] {
7082            // Make sure we can read the first packet.
7083            let ppr = PacketParserBuilder::from_bytes(msg).unwrap()
7084                .dearmor(packet_parser_builder::Dearmor::Disabled)
7085                .build();
7086            assert_match!(Ok(PacketParserResult::Some(ref _pp)) = ppr);
7087
7088            // Now truncate the packet.
7089            let msg2 = &msg[..msg.len() - 1];
7090            let ppr = PacketParserBuilder::from_bytes(msg2).unwrap()
7091                .dearmor(packet_parser_builder::Dearmor::Disabled)
7092                .build().unwrap();
7093            if let PacketParserResult::Some(pp) = ppr {
7094                let err = pp.next().err().unwrap();
7095                assert_match!(Some(&Error::MalformedPacket(_))
7096                              = err.downcast_ref());
7097            } else {
7098                panic!("No packet!?");
7099            }
7100        }
7101    }
7102
7103    #[test]
7104    fn max_packet_size() {
7105        use crate::serialize::Serialize;
7106        let uid = Packet::UserID("foobar".into());
7107        let mut buf = Vec::new();
7108        uid.serialize(&mut buf).unwrap();
7109
7110        // Make sure we can read it.
7111        let ppr = PacketParserBuilder::from_bytes(&buf).unwrap()
7112            .build().unwrap();
7113        if let PacketParserResult::Some(pp) = ppr {
7114            assert_eq!(Packet::UserID("foobar".into()), pp.packet);
7115        } else {
7116            panic!("failed to parse userid");
7117        }
7118
7119        // But if we set the maximum packet size too low, it is parsed
7120        // into an unknown packet.
7121        let ppr = PacketParserBuilder::from_bytes(&buf).unwrap()
7122            .max_packet_size(5)
7123            .build().unwrap();
7124        if let PacketParserResult::Some(pp) = ppr {
7125            if let Packet::Unknown(ref u) = pp.packet {
7126                assert_eq!(u.tag(), Tag::UserID);
7127                assert_match!(Some(&Error::PacketTooLarge(_, _, _))
7128                              = u.error().downcast_ref());
7129            } else {
7130                panic!("expected an unknown packet, got {:?}", pp.packet);
7131            }
7132        } else {
7133            panic!("failed to parse userid");
7134        }
7135
7136    }
7137
7138    /// We erroneously assumed that when BufferedReader::next() is
7139    /// called, a SEIP container be opaque and hence there cannot be a
7140    /// buffered_reader::Reserve on the stack with Cookie::fake_eof
7141    /// set.  But, we could simply call BufferedReader::next() after
7142    /// the SEIP packet is decrypted, or buffer a SEIP packet's body,
7143    /// then call BufferedReader::recurse(), which falls back to
7144    /// BufferedReader::next() because some data has been read.
7145    #[test]
7146    fn issue_455() -> Result<()> {
7147        let sk: SessionKey =
7148            crate::fmt::hex::decode("3E99593760EE241488462BAFAE4FA268\
7149                                     260B14B82D310D196DCEC82FD4F67678")?.into();
7150        let algo = SymmetricAlgorithm::AES256;
7151
7152        // Decrypt, then call BufferedReader::next().
7153        eprintln!("Decrypt, then next():\n");
7154        let mut ppr = PacketParser::from_bytes(
7155            crate::tests::message("encrypted-to-testy.pgp"))?;
7156        while let PacketParserResult::Some(mut pp) = ppr {
7157            match &pp.packet {
7158                Packet::SEIP(_) => {
7159                    pp.decrypt(algo, &sk)?;
7160                },
7161                _ => (),
7162            }
7163            // Used to trigger the assertion failure on the SEIP
7164            // packet:
7165            ppr = pp.next()?.1;
7166        }
7167
7168        // Decrypt, buffer, then call BufferedReader::recurse().
7169        eprintln!("\nDecrypt, buffer, then recurse():\n");
7170        let mut ppr = PacketParser::from_bytes(
7171            crate::tests::message("encrypted-to-testy.pgp"))?;
7172        while let PacketParserResult::Some(mut pp) = ppr {
7173            match &pp.packet {
7174                Packet::SEIP(_) => {
7175                    pp.decrypt(algo, &sk)?;
7176                    pp.buffer_unread_content()?;
7177                },
7178                _ => (),
7179            }
7180            // Used to trigger the assertion failure on the SEIP
7181            // packet:
7182            ppr = pp.recurse()?.1;
7183        }
7184        Ok(())
7185    }
7186
7187    /// Crash in the AED parser due to missing chunk size validation.
7188    #[test]
7189    fn issue_514() -> Result<()> {
7190        let data = &[212, 43, 1, 0, 0, 125, 212, 0, 10, 10, 10];
7191        let ppr = PacketParser::from_bytes(&data)?;
7192        let packet = &ppr.unwrap().packet;
7193        if let Packet::Unknown(_) = packet {
7194            Ok(())
7195        } else {
7196            panic!("expected unknown packet, got: {:?}", packet);
7197        }
7198    }
7199
7200    /// Malformed subpackets must not cause a hard parsing error.
7201    #[test]
7202    fn malformed_embedded_signature() -> Result<()> {
7203        let ppr = PacketParser::from_bytes(
7204            crate::tests::file("edge-cases/malformed-embedded-sig.pgp"))?;
7205        let packet = &ppr.unwrap().packet;
7206        if let Packet::Unknown(_) = packet {
7207            Ok(())
7208        } else {
7209            panic!("expected unknown packet, got: {:?}", packet);
7210        }
7211    }
7212
7213    /// Malformed notation names must not cause hard parsing errors.
7214    #[test]
7215    fn malformed_notation_name() -> Result<()> {
7216        let ppr = PacketParser::from_bytes(
7217            crate::tests::file("edge-cases/malformed-notation-name.pgp"))?;
7218        let packet = &ppr.unwrap().packet;
7219        if let Packet::Unknown(_) = packet {
7220            Ok(())
7221        } else {
7222            panic!("expected unknown packet, got: {:?}", packet);
7223        }
7224    }
7225
7226    /// Checks that the content hash is correctly computed whether
7227    /// the content has been (fully) read.
7228    #[test]
7229    fn issue_537() -> Result<()> {
7230        // Buffer unread content.
7231        let ppr0 = PacketParserBuilder::from_bytes(
7232            crate::tests::message("literal-mode-b.pgp"))?
7233            .buffer_unread_content()
7234            .build()?;
7235        let pp0 = ppr0.unwrap();
7236        let (packet0, _) = pp0.recurse()?;
7237
7238        // Drop unread content.
7239        let ppr1 = PacketParser::from_bytes(
7240            crate::tests::message("literal-mode-b.pgp"))?;
7241        let pp1 = ppr1.unwrap();
7242        let (packet1, _) = pp1.recurse()?;
7243
7244        // Read content.
7245        let ppr2 = PacketParser::from_bytes(
7246            crate::tests::message("literal-mode-b.pgp"))?;
7247        let mut pp2 = ppr2.unwrap();
7248        io::copy(&mut pp2, &mut io::sink())?;
7249        let (packet2, _) = pp2.recurse()?;
7250
7251        // Partially read content.
7252        let ppr3 = PacketParser::from_bytes(
7253            crate::tests::message("literal-mode-b.pgp"))?;
7254        let mut pp3 = ppr3.unwrap();
7255        let mut buf = [0];
7256        let nread = pp3.read(&mut buf)?;
7257        assert_eq!(buf.len(), nread);
7258        let (packet3, _) = pp3.recurse()?;
7259
7260        assert_eq!(packet0, packet1);
7261        assert_eq!(packet1, packet2);
7262        assert_eq!(packet2, packet3);
7263        Ok(())
7264    }
7265
7266    /// Checks that newlines are properly normalized when verifying
7267    /// text signatures.
7268    #[test]
7269    fn issue_530_verifying() -> Result<()> {
7270        use std::io::Write;
7271        use crate::*;
7272        use crate::packet::signature;
7273        use crate::serialize::stream::{Message, Signer};
7274
7275        use crate::policy::StandardPolicy;
7276        use crate::{Result, Cert};
7277        use crate::parse::Parse;
7278        use crate::parse::stream::*;
7279
7280        let data = b"one\r\ntwo\r\nthree";
7281
7282        let p = &StandardPolicy::new();
7283        let cert: Cert =
7284            Cert::from_bytes(crate::tests::key("testy-new-private.pgp"))?;
7285        let signing_keypair = cert.keys().secret()
7286            .with_policy(p, None).alive().revoked(false).for_signing().next().unwrap()
7287            .key().clone().into_keypair()?;
7288        let mut signature = vec![];
7289        {
7290            let message = Message::new(&mut signature);
7291            let mut message = Signer::with_template(
7292                message, signing_keypair,
7293                signature::SignatureBuilder::new(SignatureType::Text)
7294            )?.detached().build()?;
7295            message.write_all(data)?;
7296            message.finalize()?;
7297        }
7298
7299        struct Helper {}
7300        impl VerificationHelper for Helper {
7301            fn get_certs(&mut self, _ids: &[KeyHandle]) -> Result<Vec<Cert>> {
7302                Ok(vec![Cert::from_bytes(crate::tests::key("testy-new.pgp"))?])
7303            }
7304            fn check(&mut self, structure: MessageStructure) -> Result<()> {
7305                let [layer]: [&MessageLayer; 1] = structure
7306                    .iter().collect::<Vec<_>>().try_into().unwrap();
7307                let MessageLayer::SignatureGroup { results } = layer else {
7308                    unreachable!();
7309                };
7310                assert_eq!(results.len(), 1);
7311                results[0].as_ref().unwrap();
7312                assert!(results[0].is_ok());
7313                return Ok(());
7314            }
7315        }
7316
7317        let h = Helper {};
7318        let mut v = DetachedVerifierBuilder::from_bytes(&signature)?
7319            .with_policy(p, None, h)?;
7320
7321        for data in &[
7322            &b"one\r\ntwo\r\nthree"[..], // dos
7323            b"one\ntwo\nthree",          // unix
7324            b"one\ntwo\r\nthree",        // mixed
7325            b"one\r\ntwo\nthree",
7326            b"one\rtwo\rthree",          // classic mac
7327        ] {
7328            v.verify_bytes(data)?;
7329        }
7330
7331        Ok(())
7332    }
7333
7334    /// Tests for a panic in the SKESK parser.
7335    #[test]
7336    fn issue_588() -> Result<()> {
7337        let data = vec![0x8c, 0x34, 0x05, 0x12, 0x02, 0x00, 0xaf, 0x0d,
7338                        0xff, 0xff, 0x65];
7339        let _ = PacketParser::from_bytes(&data);
7340        Ok(())
7341    }
7342
7343    /// Tests for a panic in the packet parser.
7344    #[test]
7345    fn packet_parser_on_mangled_cert() -> Result<()> {
7346        // The armored input cert is mangled.  Currently, Sequoia
7347        // doesn't grok the mangled armor, but it should not panic.
7348        let mut ppr = match PacketParser::from_bytes(
7349            crate::tests::key("bobs-cert-badly-mangled.asc")) {
7350            Ok(ppr) => ppr,
7351            Err(_) => return Ok(()),
7352        };
7353        while let PacketParserResult::Some(pp) = ppr {
7354            dbg!(&pp.packet);
7355            if let Ok((_, tmp)) = pp.recurse() {
7356                ppr = tmp;
7357            } else {
7358                break;
7359            }
7360        }
7361        Ok(())
7362    }
7363
7364    // Issue 967.
7365    #[test]
7366    fn packet_before_junk_emitted() -> Result<()> {
7367        let bytes = crate::tests::key("testy-new.pgp");
7368
7369        let mut ppr = match PacketParser::from_bytes(bytes) {
7370            Ok(ppr) => ppr,
7371            Err(_) => panic!("valid"),
7372        };
7373        let mut packets_ok = Vec::new();
7374        while let PacketParserResult::Some(pp) = ppr {
7375            if let Ok((packet, tmp)) = pp.recurse() {
7376                packets_ok.push(packet);
7377                ppr = tmp;
7378            } else {
7379                break;
7380            }
7381        }
7382
7383        let mut bytes = bytes.to_vec();
7384        // Add some junk.
7385        bytes.push(0);
7386        let mut ppr = match PacketParser::from_bytes(&bytes[..]) {
7387            Ok(ppr) => ppr,
7388            Err(_) => panic!("valid"),
7389        };
7390        let mut packets_mangled = Vec::new();
7391        while let PacketParserResult::Some(pp) = ppr {
7392            if let Ok((packet, tmp)) = pp.recurse() {
7393                packets_mangled.push(packet);
7394                ppr = tmp;
7395            } else {
7396                break;
7397            }
7398        }
7399
7400        assert_eq!(packets_ok.len(), packets_mangled.len());
7401        assert_eq!(packets_ok, packets_mangled);
7402
7403        Ok(())
7404    }
7405
7406    /// Tests for a panic in the packet parser.
7407    fn parse_message(message: &str) {
7408        eprintln!("parsing {:?}", message);
7409        let mut ppr = match PacketParser::from_bytes(message) {
7410            Ok(ppr) => ppr,
7411            Err(_) => return,
7412        };
7413        while let PacketParserResult::Some(pp) = ppr {
7414            dbg!(&pp.packet);
7415            if let Ok((_, tmp)) = pp.recurse() {
7416                ppr = tmp;
7417            } else {
7418                break;
7419            }
7420        }
7421    }
7422
7423    /// Tests issue 1005.
7424    #[test]
7425    fn panic_on_short_zip() {
7426        parse_message("-----BEGIN PGP SIGNATURE-----
7427
7428owGjAA0=
7429zXvj
7430-----END PGP SIGNATURE-----
7431");
7432    }
7433
7434    /// Tests issue 957.
7435    #[test]
7436    fn panic_on_malformed_armor() {
7437        parse_message("-----BEGIN PGP MESSAGE-----
7438
7439heLBX8Pq0kUBwQz2iFAzRwOdgTBvH5KsDU9lmE
7440
7441-----END PGP MESSAGE-----
7442");
7443    }
7444
7445    /// Tests issue 1024.
7446    #[test]
7447    // XXX: While lenient parsing seemed like the right thing to do,
7448    // this breaks equality and round-tripping: we normalize the
7449    // non-canonical encoding, so two distinct wire representations
7450    // are folded into one in-core representation.
7451    #[ignore]
7452    fn parse_secret_with_leading_zeros() -> Result<()> {
7453        crate::Cert::from_bytes(
7454            crate::tests::key("leading-zeros-private.pgp"))?
7455            .primary_key().key().clone()
7456            .parts_into_secret()?
7457            .decrypt_secret(&("hunter22"[..]).into())?
7458            .into_keypair()?;
7459        Ok(())
7460    }
7461
7462    /// Tests that junk pseudo-packets have a proper map when
7463    /// buffering is turned on.
7464    #[test]
7465    #[cfg(feature = "compression-deflate")]
7466    fn parse_junk_with_mapping() -> Result<()> {
7467        let silly = "-----BEGIN PGP MESSAGE-----
7468
7469yCsBO81bKqlfklugX5yRX5qTopuXX6KbWpFZXKJXUlGSetb4dXm+gYFBCRcA
7470=IHpt
7471-----END PGP MESSAGE-----
7472";
7473        let mut ppr = PacketParserBuilder::from_bytes(silly)?
7474            .map(true).buffer_unread_content().build()?;
7475        let mut i = 0;
7476        while let PacketParserResult::Some(pp) = ppr {
7477            assert!(pp.map().unwrap().iter().count() > 0);
7478            for f in pp.map().unwrap().iter() {
7479                eprintln!("{:?}", f);
7480            }
7481            ppr = match pp.recurse() {
7482                Ok((_, ppr)) => {
7483                    i += 1;
7484                    ppr
7485                },
7486                Err(_) => {
7487                    // The third packet is a junk pseudo-packet, and
7488                    // recursing will fail.
7489                    assert_eq!(i, 2);
7490                    break;
7491                },
7492            }
7493        }
7494        Ok(())
7495    }
7496
7497    /// Tests for issue 1095, parsing a secret key packet with an
7498    /// unknown S2K mechanism.
7499    #[test]
7500    fn key_unknown_s2k() -> Result<()> {
7501        let mut ppr = PacketParser::from_bytes(
7502            crate::tests::key("hardware-backed-secret.pgp"))?;
7503        let mut i = 0;
7504        while let PacketParserResult::Some(pp) = ppr {
7505            if i == 0 {
7506                assert!(matches!(&pp.packet, Packet::SecretKey(_)));
7507            }
7508            if i == 3 {
7509                assert!(matches!(&pp.packet, Packet::SecretSubkey(_)));
7510            }
7511
7512            // Make sure it roundtrips.
7513            let p = &pp.packet;
7514            let v = p.to_vec()?;
7515            let q = Packet::from_bytes(&v)?;
7516            assert_eq!(p, &q);
7517
7518            ppr = pp.recurse()?.1;
7519            i += 1;
7520        }
7521        Ok(())
7522    }
7523
7524    #[test]
7525    fn nested_embedded_signatures() {
7526        // Builds a crafted OpenPGP certificate (~44 KB) that crashes any process
7527        // parsing it. The certificate contains a signature with 3000 nested
7528        // EmbeddedSignature subpackets - enough to overflow the default 8 MB stack.
7529        // This is the same path triggered by keyserver fetches (Cert::from_bytes),
7530        // RPM signature verification, Autocrypt header parsing, etc.
7531
7532        use crate::Cert;
7533
7534        let dummy_rsa_sig = [0x00, 0x01, 0x01]; // MPI: 1-bit value 1
7535
7536        // Innermost signature: minimal valid v4 body plus one RSA signature MPI.
7537        let mut sig = vec![
7538            0x04, 0x00, 0x01, 0x08, // v4, Binary, RSA, SHA256
7539            0x00, 0x00,             // hashed subpacket area: 0 bytes
7540            0x00, 0x00,             // unhashed subpacket area: 0 bytes
7541            0x00, 0x00,             // hash prefix
7542        ];
7543        sig.extend_from_slice(&dummy_rsa_sig);
7544
7545        // Nest 3000 times: each layer wraps the previous signature as an
7546        // EmbeddedSignature subpacket (tag 32) in the unhashed area.
7547        for _ in 0..3000 {
7548            let c_len = 1 + sig.len();
7549            let len_enc = if c_len < 192 {
7550                vec![c_len as u8]
7551            } else if c_len < 16320 {
7552                let a = c_len - 192;
7553                vec![((a >> 8) as u8) + 192, (a & 0xFF) as u8]
7554            } else {
7555                let l = c_len as u32;
7556                vec![0xFF, (l >> 24) as u8, (l >> 16) as u8, (l >> 8) as u8, l as u8]
7557            };
7558
7559            let mut sub = len_enc;
7560            sub.push(32); // EmbeddedSignature subpacket tag
7561            sub.extend(&sig);
7562            if sub.len() > 65535 { break; } // SubpacketArea max size
7563
7564            let ulen = sub.len();
7565            let mut outer = vec![
7566                0x04, 0x00, 0x01, 0x08, 0x00, 0x00,
7567                (ulen >> 8) as u8, (ulen & 0xFF) as u8,
7568            ];
7569            outer.extend(&sub);
7570            outer.extend(&[0x00, 0x00]); // hash prefix
7571            outer.extend_from_slice(&dummy_rsa_sig);
7572            sig = outer;
7573        }
7574
7575        // Wrap in a minimal OpenPGP certificate so the payload matches
7576        // real-world delivery: keyserver fetch, RPM package, Autocrypt header.
7577        sig[1] = 0x10; // patch signature type -> Generic Certification
7578
7579        if let Err(err) = Signature::from_bytes(&sig) {
7580            let err = err.downcast::<Error>();
7581            assert!(matches!(err, Ok(Error::MalformedPacket(_))));
7582        } else {
7583            panic!("Failed to rejected nested embedded signatures");
7584        }
7585
7586        // Minimal v4 RSA public key body
7587        let mut pk = vec![0x04, 0x00, 0x00, 0x00, 0x00, 0x01]; // v4, time=0, RSA
7588        pk.extend(&[0x02, 0x00]);          // 512-bit modulus
7589        pk.extend(&[0xFF; 64]);            // dummy modulus
7590        pk.extend(&[0x00, 0x11]);          // 17-bit exponent
7591        pk.extend(&[0x01, 0x00, 0x01]);    // e = 65537
7592
7593        let uid = b"Test <test@test.com>";
7594
7595        // Assemble: Public Key (tag 6) + UserID (tag 13) + Signature (tag 2)
7596        let mut cert_data = Vec::new();
7597        let header = |tag: u8, len: usize| {
7598            let mut h = vec![0xC0 | tag];
7599            if len < 192 { h.push(len as u8); }
7600            else {
7601                let l = len as u32;
7602                h.extend([0xFF, (l >> 24) as u8, (l >> 16) as u8, (l >> 8) as u8, l as u8]);
7603            }
7604            h
7605        };
7606        cert_data.extend(header(6, pk.len()));
7607        cert_data.extend(&pk);
7608        cert_data.extend(header(13, uid.len()));
7609        cert_data.extend(uid);
7610        cert_data.extend(header(2, sig.len()));
7611        cert_data.extend(&sig);
7612
7613        // We should be able to parse the certificate by rejecting the
7614        // invalid signature.  If we parse the nested signatures, then
7615        // we'll probably exhaust the stack and crash.
7616        eprintln!("{} bytes ({:.1} KB), calling Cert::from_bytes()...",
7617                  cert_data.len(), cert_data.len() as f64 / 1024.0);
7618        let _ = Cert::from_bytes(&cert_data);
7619        eprintln!("no crash (stack may be larger than default)");
7620    }
7621
7622    #[test]
7623    fn cleartext() {
7624        // Check if we're processing a clear text message.
7625
7626        eprintln!("Checking a cleartext signature with the clear text \
7627                   transformation enabled.");
7628        let mut ppr = PacketParserBuilder::from_bytes(
7629            crate::tests::message("a-cypherpunks-manifesto.txt.cleartext.sig"))
7630            .expect("Can read file")
7631            .process_csf_message(true)
7632            .build()
7633            .expect("Can build packet parser");
7634
7635        while let PacketParserResult::Some(pp) = ppr {
7636            eprintln!("Have {:?} packet", pp.packet.tag());
7637            assert!(pp.processing_csf_message());
7638            ppr = pp.recurse().expect("well-formed message").1;
7639        }
7640
7641        eprintln!("Checking a cleartext signature with the clear text \
7642                   transformation disabled.");
7643        let mut ppr = PacketParserBuilder::from_bytes(
7644            crate::tests::message("a-cypherpunks-manifesto.txt.cleartext.sig"))
7645            .expect("Can read file")
7646            .process_csf_message(false)
7647            .build()
7648            .expect("Can build packet parser");
7649
7650        while let PacketParserResult::Some(pp) = ppr {
7651            eprintln!("Have {:?} packet", pp.packet.tag());
7652            assert!(! pp.processing_csf_message());
7653            ppr = pp.recurse().expect("well-formed message").1;
7654        }
7655
7656        eprintln!("Checking a detached signature with the clear text \
7657                   transformation enabled.");
7658        let mut ppr = PacketParserBuilder::from_bytes(
7659            crate::tests::message("a-cypherpunks-manifesto.txt.ed25519.sig"))
7660            .expect("Can read file")
7661            .process_csf_message(true)
7662            .build()
7663            .expect("Can build packet parser");
7664
7665        while let PacketParserResult::Some(pp) = ppr {
7666            eprintln!("Have {:?} packet", pp.packet.tag());
7667            assert!(! pp.processing_csf_message());
7668            ppr = pp.recurse().expect("well-formed message").1;
7669        }
7670    }
7671}