Module sequoia_openpgp::packet
source · Expand description
Packet-related data types.
OpenPGP data structures are packet based. This module defines the corresponding data structures.
Most users of this library will not need to generate these packets
themselves. Instead, the packets are instantiated as a side
effect of parsing a message, or creating a message. The main
current exception are Signature
packets. Working with
Signature
packets is, however, simplified by using the
SignatureBuilder
.
§Data Types
Many OpenPGP packets include a version field. Versioning is used
to make it easier to change the standard. For instance, using
versioning, it is possible to remove a field from a packet without
introducing a new packet type, which would also require changing
the grammar. Versioning also enables a degree of forward
compatibility when a new version of a packet can be safely
ignored. For instance, there are currently two versions of the
Signature
packet with completely different layouts: v3 and
v4. An implementation that does not understand the latest
version of the packet can still parse and display a message using
them; it will just be unable to verify that signature.
In Sequoia, packets that have a version field are represented by
enum
s, and each supported version of the packet has a variant,
and a corresponding struct
. This is the case even when only one
version of the packet is currently defined, as is the case with
the OnePassSig
packet. The enum
s implement forwarders for
common operations. As such, users of this library can often
ignore that there are multiple versions of a given packet.
§Unknown Packets
Sequoia gracefully handles unsupported packets by storing them as
Unknown
packets. There are several types of unknown packets:
-
Packets that are known, but explicitly not supported.
The two major examples are the
SED
packet type and v3Signature
packets, which have both been considered insecure for well over a decade.Note: future versions of Sequoia may add limited support for these packets to enable parsing archived messages.
-
Packets that are known about, but that use unsupported options, e.g., a
Compressed Data
packet using an unknown or unsupported algorithm. -
Packets that are unknown, e.g., future or private extensions.
When Sequoia parses a message containing these packets, it
doesn’t fail. Instead, Sequoia stores them in the Unknown
data structure. This allows applications to not only continue to
process such messages (albeit with degraded performance), but to
losslessly reserialize the messages, should that be required.
§Containers
Packets can be divided into two categories: containers and
non-containers. A container is a packet that contains other
OpenPGP packets. For instance, by definition, a Compressed Data
packet contains an OpenPGP Message. It is possible to
iterate over a container’s descendants using the
Container::descendants
method. (Note: Container
s Deref
to Container
.)
§Packet Headers and Bodies
Conceptually, packets have zero or more headers and an optional
body. The headers are small, and have a known upper bound. The
version field is, for instance, 4 bytes, and although
Signature
SubpacketArea
areas are variable in size,
they are limited to 64 KB. In contrast the body, can be unbounded
in size.
To limit memory use, and enable streaming processing (i.e.,
ensuring that processing a message can be done using a fixed size
buffer), Sequoia does not require that a packet’s body be present
in memory. For instance, the body of a literal data packet may be
streamed. And, at the end, a Literal
packet is still
returned. This allows the caller to examine the message
structure, and the message headers in in toto even when
streaming. It is even possible to compare two streamed version of
a packet: Sequoia stores a hash of the body. See the Body
data structure for more details.
§Equality
There are several reasonable ways to define equality for
Packet
s. Unfortunately, none of them are appropriate in all
situations. This makes choosing a general-purpose equality
function for Eq
difficult.
Consider defining Eq
as the equivalence of two Packet
s’
serialized forms. If an application naively deduplicates
signatures, then an attacker can potentially perform a denial of
service attack by causing the application to process many
cryptographically-valid Signature
s by varying the content of one
cryptographically-valid Signature
’s unhashed area. This attack
can be prevented by only comparing data that is protected by the
signature. But this means that naively deduplicating Signature
packets will return in “a random” variant being used. So, again,
an attacker could create variants of a cryptographically-valid
Signature
to get the implementation to incorrectly drop a useful
one.
These issues are also relevant when comparing Key
s: should the
secret key material be compared? Usually we want to merge the
secret key material. But, again, if done naively, the incorrect
secret key material may be retained or dropped completely.
Instead of trying to come up with a definition of equality that is
reasonable for all situations, we use a conservative definition:
two packets are considered equal if the serialized forms of their
packet bodies as defined by RFC 4880 are equal. That is, two
packets are considered equal if and only if their serialized forms
are equal modulo the OpenPGP framing (CTB
and length style,
potential partial body encoding). This definition will avoid
unintentionally dropping information when naively deduplicating
packets, but it will result in potential redundancies.
For some packets, we provide additional variants of equality. For
instance, Key::public_cmp
compares just the public parts of
two keys.
Re-exports§
pub use self::header::Header;
pub use self::user_attribute::UserAttribute;
Modules§
- AEAD encrypted data packets.
- OpenPGP packet headers.
- Key-related functionality.
- One-pass signature packets.
- PublicKey-Encrypted Session Key packets.
- Brings the most relevant types and traits into scope for working with packets.
- Symmetrically Encrypted Integrity Protected data packets.
- Signature-related functionality.
- Symmetric-Key Encrypted Session Key Packets.
- User Attribute packets and subpackets.
Structs§
- Fields used by multiple packet types.
- Holds a compressed data packet.
- Holds packet bodies.
- An iterator over the contents of a packet in depth-first order.
- Holds a literal packet.
- Holds an MDC packet.
- Holds a Marker packet.
- Holds a Trust packet.
- Holds an unknown packet.
- Holds a UserID packet.
Enums§
- Holds an AEAD encrypted data packet.
- A packet’s body holds either unprocessed bytes, processed bytes, or packets.
- Holds a public key, public subkey, private key or private subkey packet.
- Holds a one-pass signature packet.
- Holds an asymmetrically encrypted session key.
- Enumeration of packet types.
- Holds a SEIP packet.
- Holds a symmetrically encrypted session key.
- Holds a signature packet.
- The OpenPGP packet tags as defined in Section 4.3 of RFC 4880.
Traits§
- Convenient downcasting from Packets to Packet Bodies.