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