Expand description
Packet parsing infrastructure.
OpenPGP defines a binary representation suitable for storing and communicating OpenPGP data structures (see Section 3 ff. of RFC 9580). Parsing is the process of interpreting the binary representation.
An OpenPGP stream represents a sequence of packets. Some of the packets contain other packets. These so-called containers include encrypted data packets (the SED and SEIP packets), and compressed data packets. This structure results in a tree, which is laid out in depth-first order.
OpenPGP defines objects consisting of several packets with a
specific structure. These objects are Messages, Certs and
sequences of Certs (“keyrings”). Verifying the structure of
these objects is also an act of parsing.
This crate provides several interfaces to parse OpenPGP data. They fall in roughly three categories:
-
First, most data structures in this crate implement the
Parsetrait. It provides a uniform interface to parse data from anio::Reader, a file identified by itsPath, or simply a byte slice. -
Second, there is a convenient interface to decrypt and/or verify OpenPGP messages in a streaming fashion. Encrypted and/or signed data is read using the
Parseinterface, and decrypted and/or verified data can be read usingio::Read. -
Finally, we expose the low-level
PacketParser, allowing fine-grained control over the parsing.
The choice of interface depends on the specific use case. In many circumstances, OpenPGP data can not be trusted until it has been authenticated. Therefore, it has to be treated as attacker controlled data, and it has to be treated with great care. See the section Security Considerations below.
§Common Operations
- Decrypt a message: Use a streaming
Decryptor. - Verify a message: Use a streaming
Verifier. - Verify a detached signature: Use a
DetachedVerifier. - Parse a
Cert: UseCert’sParseinterface. - Parse a keyring: Use
CertParser’sParseinterface. - Parse an unstructured sequence of small packets from a trusted
source: Use
PacketPilesParseinterface (e.g.PacketPile::from_file). - Parse an unstructured sequence of packets: Use the
PacketPileParser. - Parse an unstructured sequence of packets with full control
over the parser: Use a
PacketParser. - Customize the parser behavior even more: Use a
PacketParserBuilder.
§Data Structures and Interfaces
This crate provides several interfaces for parsing OpenPGP streams, ordered from the most convenient but least flexible to the least convenient but most flexible:
-
The streaming
Verifier,DetachedVerifier, andDecryptorare the most convenient way to parse OpenPGP messages. -
The
PacketPile::from_file(and related methods) is the most convenient, but least flexible way to parse an arbitrary sequence of OpenPGP packets. Whereas aPacketPileParserallows the caller to determine how to handle individual packets, thePacketPile::from_fileparses the whole stream at once and returns aPacketPile. -
The
PacketPileParserabstraction builds on thePacketParserabstraction and provides a similar interface. However, after each iteration, thePacketPileParseradds the packet to aPacketPile, 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 stream is parsed in place, then using aPacketParseris better.This interface should only be used if the caller is certain that the parsed stream will fit in memory.
-
The
PacketParserabstraction produces one packet at a time. What is done with those packets is completely up to the caller.
The behavior of the PacketParser can be configured using a
PacketParserBuilder.
§ASCII armored data
The PacketParser will by default automatically detect and
remove any ASCII armor encoding (see Section 6 of RFC 9580).
This automatism can be disabled and fine-tuned using
PacketParserBuilder::dearmor.
§Security Considerations
In general, OpenPGP data must be considered attacker controlled and thus treated with great care. Even though we use a memory-safe language, there are several aspects to be aware of:
-
OpenPGP messages may be compressed. Therefore, one cannot predict the uncompressed size of a message by looking at the compressed representation. Operations that parse OpenPGP streams and buffer the packet data (like using the
PacketPile’sParseinterface) are inherently unsafe and must only be used on trusted data. -
The authenticity of an OpenPGP message can only be checked once it has been fully processed. Therefore, the plaintext must be buffered and not be trusted until the whole message is processed and signatures and/or ciphertext integrity are verified. On the other hand, buffering an unbounded amount of data is problematic and can lead to out-of-memory situations resulting in denial of service. The streaming message processing interfaces address this problem by buffering a configurable amount of data before releasing any data to the caller, and only revert to streaming unverified data if the message exceeds the buffer. See
DEFAULT_BUFFER_SIZEfor more information. -
Not all parts of signed-then-encrypted OpenPGP messages are authenticated. Notably, all packets outside the encryption container (any
PKESKandSKESKpackets, as well as the encryption container itself), theLiteralpacket’s headers, as well as parts of theSignatureare not covered by the signatures. -
Ciphertext integrity is provided by the [version 2 SEIP] packet’s use of authenticated encryption.
-
In messages compatible with RFC 4880, ciphertext integrity is provided by the
version 1 SEIPpacket’sMDCmechanism, but the integrity can only be checked after decrypting the whole container.
Re-exports§
pub use buffered_reader;
Modules§
Structs§
- Cookie
- Private state used by the
PacketParser. - Packet
Parser - A low-level OpenPGP message parser.
- Packet
Parser Builder - A builder for configuring a
PacketParser. - Packet
ParserEOF - Information about the stream of packets parsed by the
PacketParser. - Packet
Pile Parser - Parses an OpenPGP stream with the convenience of
PacketPile::from_fileand the flexibility of aPacketParser.
Enums§
- Dearmor
- Controls transparent stripping of ASCII armor when parsing.
- Packet
Parser Result - The result of parsing a packet.
Constants§
- DEFAULT_
MAX_ PACKET_ SIZE - The default maximum size of non-container packets.
- DEFAULT_
MAX_ RECURSION_ DEPTH - The default amount of acceptable nesting.
Traits§
- Parse
- Parsing of packets and related structures.