diff options
Diffstat (limited to 'openpgp')
-rw-r--r-- | openpgp/src/parse.rs (renamed from openpgp/src/parse/parse.rs) | 95 | ||||
-rw-r--r-- | openpgp/src/parse/mod.rs | 94 |
2 files changed, 93 insertions, 96 deletions
diff --git a/openpgp/src/parse/parse.rs b/openpgp/src/parse.rs index 80792cc8..89bcabe4 100644 --- a/openpgp/src/parse/parse.rs +++ b/openpgp/src/parse.rs @@ -1,3 +1,94 @@ +//! OpenPGP packet parser. +//! +//! An OpenPGP message is a sequence of packets. Some of the packets +//! contain other packets. These containers include encrypted packets +//! (the SED and SEIP packets), and compressed packets. This +//! structure results in a tree, which is laid out in depth-first +//! order. +//! +//! There are two major concerns that inform the design of the parsing +//! API. +//! +//! First, when processing a container, it is possible to either +//! recurse into the container, and process its children, or treat the +//! contents of the container as an opaque byte stream, and process +//! the packet following the container. The low-level +//! [`PacketParser`] and mid-level [`PacketPileParser`] abstractions +//! allow the caller to choose the behavior by either calling the +//! `recurse()` method or the `next()` method, as appropriate. +//! OpenPGP doesn't impose any restrictions on the amount of nesting. +//! So, to prevent a denial of service attack, the parsers doesn't +//! recurse more than `MAX_RECURSION_DEPTH` times, by default. +//! +//! Second, packets can contain an effectively unbounded amount of +//! data. To avoid errors due to memory exhaustion, the +//! [`PacketParser`] and [`PacketPileParser`] abstractions support +//! parsing packets in a streaming manner, i.e., never buffering more +//! than O(1) bytes of data. To do this, the parsers initially only +//! parse a packet's header (which is rarely more than a few kilobytes +//! of data), and return control to the caller. After inspecting that +//! data, the caller can decide how to handle the packet's contents. +//! If the content is deemed interesting, it can be streamed or +//! buffered. Otherwise, it can be dropped. Streaming is possible +//! not only for literal data packets, but also containers (other +//! packets also support the interface, but just return EOF). For +//! instance, encryption can be stripped by saving the decrypted +//! content of an encryption packet, which is just an OpenPGP message. +//! +//! We explicitly chose to not use a callback-based API, but something +//! that is closer to Rust's iterator API. Unfortunately, because a +//! [`PacketParser`] needs mutable access to the input stream (so that +//! the content can be streamed), only a single [`PacketParser`] item +//! can be live at a time (without a fair amount of unsafe nastiness). +//! This is incompatible with Rust's iterator concept, which allows +//! any number of items to be live at any time. For instance: +//! +//! ```rust +//! let mut v = vec![1, 2, 3, 4]; +//! let mut iter = v.iter_mut(); +//! +//! let x = iter.next().unwrap(); +//! let y = iter.next().unwrap(); +//! +//! *x += 10; // This does not cause an error! +//! *y += 10; +//! ``` +//! +//! This crate provide three abstractions for parsing OpenPGP +//! messages: +//! +//! - The [`PacketParser`] abstraction produces one packet at a +//! time. What is done with those packets is completely up to the +//! caller. +//! +//! - The [`PacketPileParser`] abstraction builds on the +//! [`PacketParser`] abstraction and provides a similar interface. +//! However, after each iteration, the `PacketPileParser` adds the +//! packet to a [`PacketPile`], which is returned once the packets are +//! completely processed. +//! +//! This interface should only be used if the caller actually +//! wants a `PacketPile`; if the OpenPGP message is parsed in place, +//! then using a `PacketParser` is better. +//! +//! - The [`PacketPile::from_file`] (and related methods) is the most +//! convenient, but least flexible way to parse a sequence of OpenPGP +//! packets. Whereas a `PacketPileParser` allows the caller to +//! determine how to handle individual packets, the +//! [`PacketPile::from_file`] parses the whole message at once and +//! returns a [`PacketPile`]. +//! +//! This interface should only be used if the caller is certain +//! that the parsed message will fit in memory. +//! +//! In all cases, the default behavior can be configured using a +//! [`PacketParserBuilder`]. +//! +//! [`PacketParser`]: struct.PacketParser.html +//! [`PacketPileParser`]: struct.PacketPileParser.html +//! [`PacketPile`]: ../struct.PacketPile.html +//! [`PacketPile::from_file`]: ../struct.PacketPile.html#method.from_file +//! [`PacketParserBuilder`]: struct.PacketParserBuilder.html use std; use std::io; use std::io::prelude::*; @@ -2650,7 +2741,7 @@ impl PacketParserState { /// # use openpgp::Result; /// # use openpgp::Packet; /// # use openpgp::parse::{Parse, PacketParserResult, PacketParser}; -/// # let _ = f(include_bytes!("../../tests/data/keys/public-key.gpg")); +/// # let _ = f(include_bytes!("../tests/data/keys/public-key.gpg")); /// # /// # fn f(message_data: &[u8]) -> Result<()> { /// let mut ppr = PacketParser::from_bytes(message_data)?; @@ -3592,7 +3683,7 @@ impl <'a> PacketParser<'a> { /// # use openpgp::Packet; /// # use openpgp::parse::{Parse, PacketParserResult, PacketParser}; /// # use std::string::String; - /// # f(include_bytes!("../../tests/data/messages/literal-mode-t-partial-body.gpg")); + /// # f(include_bytes!("../tests/data/messages/literal-mode-t-partial-body.gpg")); /// # /// # fn f(message_data: &[u8]) -> Result<()> { /// let mut ppr = PacketParser::from_bytes(message_data)?; diff --git a/openpgp/src/parse/mod.rs b/openpgp/src/parse/mod.rs deleted file mode 100644 index 9c72a9fa..00000000 --- a/openpgp/src/parse/mod.rs +++ /dev/null @@ -1,94 +0,0 @@ -//! OpenPGP packet parser. -//! -//! An OpenPGP message is a sequence of packets. Some of the packets -//! contain other packets. These containers include encrypted packets -//! (the SED and SEIP packets), and compressed packets. This -//! structure results in a tree, which is laid out in depth-first -//! order. -//! -//! There are two major concerns that inform the design of the parsing -//! API. -//! -//! First, when processing a container, it is possible to either -//! recurse into the container, and process its children, or treat the -//! contents of the container as an opaque byte stream, and process -//! the packet following the container. The low-level -//! [`PacketParser`] and mid-level [`PacketPileParser`] abstractions -//! allow the caller to choose the behavior by either calling the -//! `recurse()` method or the `next()` method, as appropriate. -//! OpenPGP doesn't impose any restrictions on the amount of nesting. -//! So, to prevent a denial of service attack, the parsers doesn't -//! recurse more than `MAX_RECURSION_DEPTH` times, by default. -//! -//! Second, packets can contain an effectively unbounded amount of -//! data. To avoid errors due to memory exhaustion, the -//! [`PacketParser`] and [`PacketPileParser`] abstractions support -//! parsing packets in a streaming manner, i.e., never buffering more -//! than O(1) bytes of data. To do this, the parsers initially only -//! parse a packet's header (which is rarely more than a few kilobytes -//! of data), and return control to the caller. After inspecting that -//! data, the caller can decide how to handle the packet's contents. -//! If the content is deemed interesting, it can be streamed or -//! buffered. Otherwise, it can be dropped. Streaming is possible -//! not only for literal data packets, but also containers (other -//! packets also support the interface, but just return EOF). For -//! instance, encryption can be stripped by saving the decrypted -//! content of an encryption packet, which is just an OpenPGP message. -//! -//! We explicitly chose to not use a callback-based API, but something -//! that is closer to Rust's iterator API. Unfortunately, because a -//! [`PacketParser`] needs mutable access to the input stream (so that -//! the content can be streamed), only a single [`PacketParser`] item -//! can be live at a time (without a fair amount of unsafe nastiness). -//! This is incompatible with Rust's iterator concept, which allows -//! any number of items to be live at any time. For instance: -//! -//! ```rust -//! let mut v = vec![1, 2, 3, 4]; -//! let mut iter = v.iter_mut(); -//! -//! let x = iter.next().unwrap(); -//! let y = iter.next().unwrap(); -//! -//! *x += 10; // This does not cause an error! -//! *y += 10; -//! ``` -//! -//! This crate provide three abstractions for parsing OpenPGP -//! messages: -//! -//! - The [`PacketParser`] abstraction produces one packet at a -//! time. What is done with those packets is completely up to the -//! caller. -//! -//! - The [`PacketPileParser`] abstraction builds on the -//! [`PacketParser`] abstraction and provides a similar interface. -//! However, after each iteration, the `PacketPileParser` adds the -//! packet to a [`PacketPile`], which is returned once the packets are -//! completely processed. -//! -//! This interface should only be used if the caller actually -//! wants a `PacketPile`; if the OpenPGP message is parsed in place, -//! then using a `PacketParser` is better. -//! -//! - The [`PacketPile::from_file`] (and related methods) is the most -//! convenient, but least flexible way to parse a sequence of OpenPGP -//! packets. Whereas a `PacketPileParser` allows the caller to -//! determine how to handle individual packets, the -//! [`PacketPile::from_file`] parses the whole message at once and -//! returns a [`PacketPile`]. -//! -//! This interface should only be used if the caller is certain -//! that the parsed message will fit in memory. -//! -//! In all cases, the default behavior can be configured using a -//! [`PacketParserBuilder`]. -//! -//! [`PacketParser`]: struct.PacketParser.html -//! [`PacketPileParser`]: struct.PacketPileParser.html -//! [`PacketPile`]: ../struct.PacketPile.html -//! [`PacketPile::from_file`]: ../struct.PacketPile.html#method.from_file -//! [`PacketParserBuilder`]: struct.PacketParserBuilder.html - -// Hack so that the file doesn't have to be named mod.rs. -include!("parse.rs"); |