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}