Module sequoia_openpgp::source · [−]
Packet parsing infrastructure.
OpenPGP defines a binary representation suitable for storing and communicating OpenPGP data structures (see Section 3 ff. of RFC 4880). 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
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 an
io::Reader, a file identified by its
Path, 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 using
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.
- Decrypt a message: Use a streaming
- Verify a message: Use a streaming
- Verify a detached signature: Use a
- Parse a
- Parse a keyring: Use
- Parse an unstructured sequence of small packets from a trusted
- Parse an unstructured sequence of packets: Use the
- Parse an unstructured sequence of packets with full control
over the parser: Use a
- Customize the parser behavior even more: Use a
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:
Decryptorare the most convenient way to parse OpenPGP messages.
PacketPile::from_file(and related methods) is the most convenient, but least flexible way to parse an arbitrary sequence of OpenPGP packets. Whereas a
PacketPileParserallows the caller to determine how to handle individual packets, the
PacketPile::from_fileparses the whole stream at once and returns a
PacketPileParserabstraction builds on the
PacketParserabstraction and provides a similar interface. However, after each iteration, the
PacketPileParseradds 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 stream is parsed in place, then using a
This interface should only be used if the caller is certain that the parsed stream will fit in memory.
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
ASCII armored data
PacketParser will by default automatically detect and
remove any ASCII armor encoding (see Section 6 of RFC 4880).
This automatism can be disabled and fine-tuned using
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
Parseinterface) 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 an 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
SKESKpackets, as well as the encryption container itself), the
Literalpacket’s headers, as well as parts of the
Signatureare not covered by the signatures.
Ciphertext integrity is provided by the
MDCmechanism, but the integrity can only be checked after decrypting the whole container. Proper authenticated encryption is provided by the
AEDcontainer, but as of this writing it is not standardized.
Private state used by the
A low-level OpenPGP message parser.
A builder for configuring a
Information about the stream of packets parsed by the
Parses an OpenPGP stream with the convenience of
PacketPile::from_file and the flexibility of a
Controls transparent stripping of ASCII armor when parsing.
The result of parsing a packet.
The default maximum size of non-container packets.
The default amount of acceptable nesting.
Parsing of packets and related structures.