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