sequoia_openpgp/
parse.rs

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