sequoia_openpgp/packet/
mod.rs

1//! Packet-related data types.
2//!
3//! OpenPGP data structures are [packet based].  This module defines
4//! the corresponding data structures.
5//!
6//! Most users of this library will not need to generate these packets
7//! themselves.  Instead, the packets are instantiated as a side
8//! effect of [parsing a message], or [creating a message].  The main
9//! current exception are `Signature` packets.  Working with
10//! `Signature` packets is, however, simplified by using the
11//! [`SignatureBuilder`].
12//!
13//! # Data Types
14//!
15//! Many OpenPGP packets include a version field.  Versioning is used
16//! to make it easier to change the standard.  For instance, using
17//! versioning, it is possible to remove a field from a packet without
18//! introducing a new packet type, which would also require changing
19//! [the grammar].  Versioning also enables a degree of forward
20//! compatibility when a new version of a packet can be safely
21//! ignored.  For instance, there are currently two versions of the
22//! [`Signature`] packet with completely different layouts: [v3] and
23//! [v4].  An implementation that does not understand the latest
24//! version of the packet can still parse and display a message using
25//! them; it will just be unable to verify that signature.
26//!
27//! In Sequoia, packets that have a version field are represented by
28//! `enum`s, and each supported version of the packet has a variant,
29//! and a corresponding `struct`.  This is the case even when only one
30//! version of the packet is currently defined, as is the case with
31//! the [`OnePassSig`] packet.  The `enum`s implement forwarders for
32//! common operations.  As such, users of this library can often
33//! ignore that there are multiple versions of a given packet.
34//!
35//! # Unknown Packets
36//!
37//! Sequoia gracefully handles unsupported packets by storing them as
38//! [`Unknown`] packets.  There are several types of unknown packets:
39//!
40//!   - Packets that are known, but explicitly not supported.
41//!
42//!     The two major examples are the [`SED`] packet type and v3
43//!     `Signature` packets, which have both been considered insecure
44//!     for well over a decade.
45//!
46//!     Note: future versions of Sequoia may add limited support for
47//!     these packets to enable parsing archived messages.
48//!
49//!   - Packets that are known about, but that use unsupported
50//!     options, e.g., a [`Compressed Data`] packet using an unknown or
51//!     unsupported algorithm.
52//!
53//!   - Packets that are unknown, e.g., future or [private
54//!     extensions].
55//!
56//! When Sequoia [parses] a message containing these packets, it
57//! doesn't fail.  Instead, Sequoia stores them in the [`Unknown`]
58//! data structure.  This allows applications to not only continue to
59//! process such messages (albeit with degraded performance), but to
60//! losslessly reserialize the messages, should that be required.
61//!
62//! # Containers
63//!
64//! Packets can be divided into two categories: containers and
65//! non-containers.  A container is a packet that contains other
66//! OpenPGP packets.  For instance, by definition, a [`Compressed
67//! Data`] packet contains an [OpenPGP Message].  It is possible to
68//! iterate over a container's descendants using the
69//! [`Container::descendants`] method.  (Note: `Container`s have a
70//! `.container_ref()` and a `.container_mut()` method that return a
71//! reference to [`Container`].)
72//!
73//! # Packet Headers and Bodies
74//!
75//! Conceptually, packets have zero or more headers and an optional
76//! body.  The headers are small, and have a known upper bound.  The
77//! version field is, for instance, 4 bytes, and although
78//! [`Signature`][] [`SubpacketArea`][] areas are variable in size,
79//! they are limited to 64 KB.  In contrast the body, can be unbounded
80//! in size.
81//!
82//! To limit memory use, and enable streaming processing (i.e.,
83//! ensuring that processing a message can be done using a fixed size
84//! buffer), Sequoia does not require that a packet's body be present
85//! in memory.  For instance, the body of a literal data packet may be
86//! streamed.  And, at the end, a [`Literal`] packet is still
87//! returned.  This allows the caller to examine the message
88//! structure, and the message headers in *in toto* even when
89//! streaming.  It is even possible to compare two streamed version of
90//! a packet: Sequoia stores a hash of the body.  See the [`Body`]
91//! data structure for more details.
92//!
93//! # Equality
94//!
95//! There are several reasonable ways to define equality for
96//! `Packet`s.  Unfortunately, none of them are appropriate in all
97//! situations.  This makes choosing a general-purpose equality
98//! function for [`Eq`] difficult.
99//!
100//! Consider defining `Eq` as the equivalence of two `Packet`s'
101//! serialized forms.  If an application naively deduplicates
102//! signatures, then an attacker can potentially perform a
103//! denial-of-service attack by causing the application to process many
104//! cryptographically-valid `Signature`s by varying the content of one
105//! cryptographically-valid `Signature`'s unhashed area.  This attack
106//! can be prevented by only comparing data that is protected by the
107//! signature.  But this means that naively deduplicating `Signature`
108//! packets will return in "a random" variant being used.  So, again,
109//! an attacker could create variants of a cryptographically-valid
110//! `Signature` to get the implementation to incorrectly drop a useful
111//! one.
112//!
113//! These issues are also relevant when comparing [`Key`s]: should the
114//! secret key material be compared?  Usually we want to merge the
115//! secret key material.  But, again, if done naively, the incorrect
116//! secret key material may be retained or dropped completely.
117//!
118//! Instead of trying to come up with a definition of equality that is
119//! reasonable for all situations, we use a conservative definition:
120//! two packets are considered equal if the serialized forms of their
121//! packet bodies as defined by RFC 9580 are equal.  That is, two
122//! packets are considered equal if and only if their serialized forms
123//! are equal modulo the OpenPGP framing ([`CTB`] and [length style],
124//! potential [partial body encoding]).  This definition will avoid
125//! unintentionally dropping information when naively deduplicating
126//! packets, but it will result in potential redundancies.
127//!
128//! For some packets, we provide additional variants of equality.  For
129//! instance, [`Key::public_cmp`] compares just the public parts of
130//! two keys.
131//!
132//! [packet based]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5
133//! [the grammar]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10
134//! [v3]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.2
135//! [v4]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3
136//! [parsing a message]: crate::parse
137//! [creating a message]: crate::serialize::stream
138//! [`SignatureBuilder`]: signature::SignatureBuilder
139//! [`SED`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.7
140//! [private extensions]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5
141//! [`Compressed Data`]: CompressedData
142//! [parses]: crate::parse
143//! [OpenPGP Message]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.3
144//! [`Container::descendants`]: Container::descendants()
145//! [`Deref`]: std::ops::Deref
146//! [`SubpacketArea`]: signature::subpacket::SubpacketArea
147//! [`Eq`]: std::cmp::Eq
148//! [`Key`s]: Key
149//! [`CTB`]: header::CTB
150//! [length style]: https://www.rfc-editor.org/rfc/rfc9580.html#section-4.2
151//! [partial body encoding]: https://www.rfc-editor.org/rfc/rfc9580.html#section-4.2.1.4
152//! [`Key::public_cmp`]: Key::public_cmp()
153use std::fmt;
154use std::hash::Hasher;
155use std::ops::{Deref, DerefMut};
156use std::slice;
157use std::iter::IntoIterator;
158
159#[cfg(test)]
160use quickcheck::{Arbitrary, Gen};
161
162use crate::Result;
163
164#[macro_use]
165mod container;
166pub use container::Container;
167pub use container::Body;
168
169pub mod prelude;
170
171mod any;
172pub use self::any::Any;
173
174mod tag;
175pub use self::tag::Tag;
176pub mod header;
177pub use self::header::Header;
178
179mod unknown;
180pub use self::unknown::Unknown;
181pub mod signature;
182pub mod one_pass_sig;
183pub use one_pass_sig::OnePassSig;
184pub mod key;
185pub use key::Key;
186mod marker;
187pub use self::marker::Marker;
188mod trust;
189pub use self::trust::Trust;
190mod userid;
191pub use self::userid::UserID;
192pub mod user_attribute;
193pub use self::user_attribute::UserAttribute;
194mod literal;
195pub use self::literal::Literal;
196mod compressed_data;
197pub use self::compressed_data::CompressedData;
198pub mod seip;
199pub mod skesk;
200pub use skesk::SKESK;
201pub mod pkesk;
202pub use pkesk::PKESK;
203mod mdc;
204pub use self::mdc::MDC;
205mod padding;
206pub use self::padding::Padding;
207
208/// Enumeration of packet types.
209///
210/// The different OpenPGP packets are detailed in [Section 5 of RFC 9580].
211///
212///   [Section 5 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5
213///
214/// The [`Unknown`] packet allows Sequoia to deal with packets that it
215/// doesn't understand.  It is basically a binary blob that includes
216/// the packet's [tag].  See the [module-level documentation] for
217/// details.
218///
219/// # A note on equality
220///
221/// We define equality on `Packet` as the equality of the serialized
222/// form of their packet bodies as defined by RFC 9580.  That is, two
223/// packets are considered equal if and only if their serialized forms
224/// are equal, modulo the OpenPGP framing ([`CTB`] and [length style],
225/// potential [partial body encoding]).
226///
227/// [`Unknown`]: crate::packet::Unknown
228/// [tag]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5
229/// [module-level documentation]: crate::packet#unknown-packets
230/// [`CTB`]: crate::packet::header::CTB
231/// [length style]: https://www.rfc-editor.org/rfc/rfc9580.html#section-4.2
232/// [partial body encoding]: https://www.rfc-editor.org/rfc/rfc9580.html#section-4.2.1.4
233#[non_exhaustive]
234#[derive(PartialEq, Eq, Hash, Clone)]
235pub enum Packet {
236    /// Unknown packet.
237    Unknown(Unknown),
238    /// Signature packet.
239    Signature(Signature),
240    /// One pass signature packet.
241    OnePassSig(OnePassSig),
242    /// Public key packet.
243    PublicKey(key::PublicKey),
244    /// Public subkey packet.
245    PublicSubkey(key::PublicSubkey),
246    /// Public/Secret key pair.
247    SecretKey(key::SecretKey),
248    /// Public/Secret subkey pair.
249    SecretSubkey(key::SecretSubkey),
250    /// Marker packet.
251    Marker(Marker),
252    /// Trust packet.
253    Trust(Trust),
254    /// User ID packet.
255    UserID(UserID),
256    /// User attribute packet.
257    UserAttribute(UserAttribute),
258    /// Literal data packet.
259    Literal(Literal),
260    /// Compressed literal data packet.
261    CompressedData(CompressedData),
262    /// Public key encrypted data packet.
263    PKESK(PKESK),
264    /// Symmetric key encrypted data packet.
265    SKESK(SKESK),
266    /// Symmetric key encrypted, integrity protected data packet.
267    SEIP(SEIP),
268    /// Modification detection code packet.
269    #[deprecated]
270    MDC(MDC),
271    /// Padding packet.
272    Padding(Padding),
273}
274assert_send_and_sync!(Packet);
275
276macro_rules! impl_into_iterator {
277    ($t:ty) => {
278        impl_into_iterator!($t where);
279    };
280    ($t:ty where $( $w:ident: $c:path ),*) => {
281        /// Implement `IntoIterator` so that
282        /// `cert::insert_packets(sig)` just works.
283        impl<$($w),*> IntoIterator for $t
284            where $($w: $c ),*
285        {
286            type Item = $t;
287            type IntoIter = std::iter::Once<$t>;
288
289            fn into_iter(self) -> Self::IntoIter {
290                std::iter::once(self)
291            }
292        }
293    }
294}
295
296impl_into_iterator!(Packet);
297impl_into_iterator!(Unknown);
298impl_into_iterator!(Signature);
299impl_into_iterator!(OnePassSig);
300impl_into_iterator!(Marker);
301impl_into_iterator!(Trust);
302impl_into_iterator!(UserID);
303impl_into_iterator!(UserAttribute);
304impl_into_iterator!(Literal);
305impl_into_iterator!(CompressedData);
306impl_into_iterator!(PKESK);
307impl_into_iterator!(SKESK);
308impl_into_iterator!(SEIP);
309impl_into_iterator!(MDC);
310impl_into_iterator!(Key<P, R> where P: key::KeyParts, R: key::KeyRole);
311
312// Make it easy to pass an iterator of Packets to something expecting
313// an iterator of Into<Result<Packet>> (specifically,
314// CertParser::into_iter).
315impl From<Packet> for Result<Packet> {
316    fn from(p: Packet) -> Self {
317        Ok(p)
318    }
319}
320
321impl Packet {
322    /// Returns the `Packet's` corresponding OpenPGP tag.
323    ///
324    /// Tags are explained in [Section 5 of RFC 9580].
325    ///
326    ///   [Section 5 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5
327    pub fn tag(&self) -> Tag {
328        match self {
329            Packet::Unknown(ref packet) => packet.tag(),
330            Packet::Signature(_) => Tag::Signature,
331            Packet::OnePassSig(_) => Tag::OnePassSig,
332            Packet::PublicKey(_) => Tag::PublicKey,
333            Packet::PublicSubkey(_) => Tag::PublicSubkey,
334            Packet::SecretKey(_) => Tag::SecretKey,
335            Packet::SecretSubkey(_) => Tag::SecretSubkey,
336            Packet::Marker(_) => Tag::Marker,
337            Packet::Trust(_) => Tag::Trust,
338            Packet::UserID(_) => Tag::UserID,
339            Packet::UserAttribute(_) => Tag::UserAttribute,
340            Packet::Literal(_) => Tag::Literal,
341            Packet::CompressedData(_) => Tag::CompressedData,
342            Packet::PKESK(_) => Tag::PKESK,
343            Packet::SKESK(_) => Tag::SKESK,
344            Packet::SEIP(_) => Tag::SEIP,
345            #[allow(deprecated)]
346            Packet::MDC(_) => Tag::MDC,
347            Packet::Padding(_) => Tag::Padding,
348        }
349    }
350
351    /// Returns the parsed `Packet's` corresponding OpenPGP tag.
352    ///
353    /// Returns the packets tag, but only if it was successfully
354    /// parsed into the corresponding packet type.  If e.g. a
355    /// Signature Packet uses some unsupported methods, it is parsed
356    /// into an `Packet::Unknown`.  `tag()` returns `Tag::Signature`,
357    /// whereas `kind()` returns `None`.
358    pub fn kind(&self) -> Option<Tag> {
359        match self {
360            Packet::Unknown(_) => None,
361            _ => Some(self.tag()),
362        }
363    }
364
365    /// Returns whether this is a critical packet.
366    ///
367    /// Upon encountering an unknown critical packet, implementations
368    /// MUST reject the whole packet sequence.  On the other hand,
369    /// unknown non-critical packets MUST be ignored.  See [Section
370    /// 4.3 of RFC 9580].
371    ///
372    /// [Section 4.3 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-4.3
373    pub fn is_critical(&self) -> bool {
374        self.tag().is_critical()
375    }
376
377    /// Returns the `Packet's` version, if the packet is versioned and
378    /// recognized.
379    ///
380    /// If the packet is not versioned, or we couldn't parse the
381    /// packet, this function returns `None`.
382    pub fn version(&self) -> Option<u8> {
383        match self {
384            Packet::Unknown(_) => None,
385            Packet::Signature(p) => Some(p.version()),
386            Packet::OnePassSig(p) => Some(p.version()),
387            Packet::PublicKey(p) => Some(p.version()),
388            Packet::PublicSubkey(p) => Some(p.version()),
389            Packet::SecretKey(p) => Some(p.version()),
390            Packet::SecretSubkey(p) => Some(p.version()),
391            Packet::Marker(_) => None,
392            Packet::Trust(_) => None,
393            Packet::UserID(_) => None,
394            Packet::UserAttribute(_) => None,
395            Packet::Literal(_) => None,
396            Packet::CompressedData(_) => None,
397            Packet::PKESK(p) => Some(p.version()),
398            Packet::SKESK(p) => Some(p.version()),
399            Packet::SEIP(p) => Some(p.version()),
400            #[allow(deprecated)]
401            Packet::MDC(_) => None,
402            Packet::Padding(_) => None,
403        }
404    }
405
406    /// Hashes most everything into state.
407    ///
408    /// This is an alternate implementation of [`Hash`], which does
409    /// not hash:
410    ///
411    ///   - The unhashed subpacket area of Signature packets.
412    ///   - Secret key material.
413    ///
414    ///   [`Hash`]: std::hash::Hash
415    ///
416    /// Unlike [`Signature::normalize`], this method ignores
417    /// authenticated packets in the unhashed subpacket area.
418    ///
419    ///   [`Signature::normalize`]: Signature::normalize()
420    pub fn normalized_hash<H>(&self, state: &mut H)
421        where H: Hasher
422    {
423        use std::hash::Hash;
424
425        match self {
426            Packet::Signature(sig) => sig.normalized_hash(state),
427            Packet::OnePassSig(x) => Hash::hash(&x, state),
428            Packet::PublicKey(k) => k.public_hash(state),
429            Packet::PublicSubkey(k) => k.public_hash(state),
430            Packet::SecretKey(k) => k.public_hash(state),
431            Packet::SecretSubkey(k) => k.public_hash(state),
432            Packet::Marker(x) => Hash::hash(&x, state),
433            Packet::Trust(x) => Hash::hash(&x, state),
434            Packet::UserID(x) => Hash::hash(&x, state),
435            Packet::UserAttribute(x) => Hash::hash(&x, state),
436            Packet::Literal(x) => Hash::hash(&x, state),
437            Packet::CompressedData(x) => Hash::hash(&x, state),
438            Packet::PKESK(x) => Hash::hash(&x, state),
439            Packet::SKESK(x) => Hash::hash(&x, state),
440            Packet::SEIP(x) => Hash::hash(&x, state),
441            #[allow(deprecated)]
442            Packet::MDC(x) => Hash::hash(&x, state),
443            Packet::Unknown(x) => Hash::hash(&x, state),
444            Packet::Padding(x) => Padding::hash(x, state),
445        }
446    }
447}
448
449// Allow transparent access of common fields.
450impl Packet {
451    /// Returns a reference to the packet's `Common` struct.
452    fn common(&self) -> &Common {
453        match self {
454            Packet::Unknown(ref packet) => &packet.common,
455            Packet::Signature(ref packet) => &packet.common,
456            Packet::OnePassSig(OnePassSig::V3(packet)) => &packet.common,
457            Packet::OnePassSig(OnePassSig::V6(packet)) => &packet.common.common,
458            Packet::PublicKey(Key::V4(packet)) => &packet.common,
459            Packet::PublicKey(Key::V6(packet)) => &packet.common.common,
460            Packet::PublicSubkey(Key::V4(packet)) => &packet.common,
461            Packet::PublicSubkey(Key::V6(packet)) => &packet.common.common,
462            Packet::SecretKey(Key::V4(packet)) => &packet.common,
463            Packet::SecretKey(Key::V6(packet)) => &packet.common.common,
464            Packet::SecretSubkey(Key::V4(packet)) => &packet.common,
465            Packet::SecretSubkey(Key::V6(packet)) => &packet.common.common,
466            Packet::Marker(ref packet) => &packet.common,
467            Packet::Trust(ref packet) => &packet.common,
468            Packet::UserID(ref packet) => &packet.common,
469            Packet::UserAttribute(ref packet) => &packet.common,
470            Packet::Literal(ref packet) => &packet.common,
471            Packet::CompressedData(ref packet) => &packet.common,
472            Packet::PKESK(PKESK::V3(packet)) => &packet.common,
473            Packet::PKESK(PKESK::V6(packet)) => &packet.common,
474            Packet::SKESK(SKESK::V4(ref packet)) => &packet.common,
475            Packet::SKESK(SKESK::V6(ref packet)) => &packet.skesk4.common,
476            Packet::SEIP(SEIP::V1(packet)) => &packet.common,
477            Packet::SEIP(SEIP::V2(packet)) => &packet.common,
478            #[allow(deprecated)]
479            Packet::MDC(ref packet) => &packet.common,
480            Packet::Padding(packet) => &packet.common,
481        }
482    }
483}
484
485impl fmt::Debug for Packet {
486    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
487        fn debug_fmt(p: &Packet, f: &mut fmt::Formatter) -> fmt::Result {
488            match p {
489                Packet::Unknown(v) => write!(f, "Unknown({:?})", v),
490                Packet::Signature(v) => write!(f, "Signature({:?})", v),
491                Packet::OnePassSig(v) => write!(f, "OnePassSig({:?})", v),
492                Packet::PublicKey(v) => write!(f, "PublicKey({:?})", v),
493                Packet::PublicSubkey(v) => write!(f, "PublicSubkey({:?})", v),
494                Packet::SecretKey(v) => write!(f, "SecretKey({:?})", v),
495                Packet::SecretSubkey(v) => write!(f, "SecretSubkey({:?})", v),
496                Packet::Marker(v) => write!(f, "Marker({:?})", v),
497                Packet::Trust(v) => write!(f, "Trust({:?})", v),
498                Packet::UserID(v) => write!(f, "UserID({:?})", v),
499                Packet::UserAttribute(v) => write!(f, "UserAttribute({:?})", v),
500                Packet::Literal(v) => write!(f, "Literal({:?})", v),
501                Packet::CompressedData(v) => write!(f, "CompressedData({:?})", v),
502                Packet::PKESK(v) => write!(f, "PKESK({:?})", v),
503                Packet::SKESK(v) => write!(f, "SKESK({:?})", v),
504                Packet::SEIP(v) => write!(f, "SEIP({:?})", v),
505                #[allow(deprecated)]
506                Packet::MDC(v) => write!(f, "MDC({:?})", v),
507                Packet::Padding(v) => write!(f, "Padding({:?})", v),
508            }
509        }
510
511        fn try_armor_fmt(p: &Packet, f: &mut fmt::Formatter)
512                         -> Result<fmt::Result> {
513            use crate::armor::{Writer, Kind};
514            use crate::serialize::Serialize;
515            let mut w = Writer::new(Vec::new(), Kind::File)?;
516            p.serialize(&mut w)?;
517            let buf = w.finalize()?;
518            Ok(f.write_str(std::str::from_utf8(&buf).expect("clean")))
519        }
520
521        if ! cfg!(test) {
522            debug_fmt(self, f)
523        } else {
524            try_armor_fmt(self, f).unwrap_or_else(|_| debug_fmt(self, f))
525        }
526    }
527}
528
529#[cfg(test)]
530impl Arbitrary for Packet {
531    fn arbitrary(g: &mut Gen) -> Self {
532        use crate::arbitrary_helper::gen_arbitrary_from_range;
533
534        match gen_arbitrary_from_range(0..16, g) {
535            0 => Signature::arbitrary(g).into(),
536            1 => OnePassSig::arbitrary(g).into(),
537            2 => Key::<key::PublicParts, key::PrimaryRole>::arbitrary(g)
538                .into(),
539            3 => Key::<key::PublicParts, key::SubordinateRole>::arbitrary(g)
540                .into(),
541            4 => Key::<key::SecretParts, key::PrimaryRole>::arbitrary(g)
542                .into(),
543            5 => Key::<key::SecretParts, key::SubordinateRole>::arbitrary(g)
544                .into(),
545            6 => Marker::arbitrary(g).into(),
546            7 => Trust::arbitrary(g).into(),
547            8 => UserID::arbitrary(g).into(),
548            9 => UserAttribute::arbitrary(g).into(),
549            10 => Literal::arbitrary(g).into(),
550            11 => CompressedData::arbitrary(g).into(),
551            12 => PKESK::arbitrary(g).into(),
552            13 => SKESK::arbitrary(g).into(),
553            14 => Padding::arbitrary(g).into(),
554            15 => loop {
555                let mut u = Unknown::new(
556                    Tag::arbitrary(g), anyhow::anyhow!("Arbitrary::arbitrary"));
557                u.set_body(Arbitrary::arbitrary(g));
558                let u = Packet::Unknown(u);
559
560                // Check that we didn't accidentally make a valid
561                // packet.
562                use crate::parse::Parse;
563                use crate::serialize::SerializeInto;
564                if let Ok(Packet::Unknown(_)) = Packet::from_bytes(
565                    &u.to_vec().unwrap())
566                {
567                    break u;
568                }
569
570                // Try again!
571            },
572            _ => unreachable!(),
573        }
574    }
575}
576
577/// Fields used by multiple packet types.
578#[derive(Default, Debug, Clone)]
579pub(crate) struct Common {
580    // In the future, this structure will hold the parsed CTB, packet
581    // length, and lengths of chunks of partial body encoded packets.
582    // This will allow for bit-perfect roundtripping of parsed
583    // packets.  Since we consider Packets to be equal if their
584    // serialized form is equal modulo CTB, packet length encoding,
585    // and chunk lengths, this structure has trivial implementations
586    // for PartialEq, Eq, PartialOrd, Ord, and Hash, so that we can
587    // derive PartialEq, Eq, PartialOrd, Ord, and Hash for most
588    // packets.
589
590    /// XXX: Prevents trivial matching on this structure.  Remove once
591    /// this structure actually gains some fields.
592    dummy: std::marker::PhantomData<()>,
593}
594assert_send_and_sync!(Common);
595
596impl Common {
597    /// Returns a default version of `Common`.
598    ///
599    /// This is equivalent to using `Common::from`, but the function
600    /// is constant.
601    pub(crate) const fn new() -> Self {
602        Common {
603            dummy: std::marker::PhantomData
604        }
605    }
606}
607
608#[cfg(test)]
609impl Arbitrary for Common {
610    fn arbitrary(_: &mut Gen) -> Self {
611        // XXX: Change if this gets interesting fields.
612        Common::default()
613    }
614}
615
616impl PartialEq for Common {
617    fn eq(&self, _: &Common) -> bool {
618        // Don't compare anything.
619        true
620    }
621}
622
623impl Eq for Common {}
624
625impl PartialOrd for Common {
626    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
627        Some(self.cmp(other))
628    }
629}
630
631impl Ord for Common {
632    fn cmp(&self, _: &Self) -> std::cmp::Ordering {
633        std::cmp::Ordering::Equal
634    }
635}
636
637impl std::hash::Hash for Common {
638    fn hash<H: std::hash::Hasher>(&self, _: &mut H) {
639        // Don't hash anything.
640    }
641}
642
643
644/// An iterator over the *contents* of a packet in depth-first order.
645///
646/// Given a [`Packet`], an `Iter` iterates over the `Packet` and any
647/// `Packet`s that it contains.  For non-container `Packet`s, this
648/// just returns a reference to the `Packet` itself.  For [container
649/// `Packet`s] like [`CompressedData`], and [`SEIP`], this
650/// walks the `Packet` hierarchy in depth-first order, and returns the
651/// `Packet`s the first time they are visited.  (Thus, the packet
652/// itself is always returned first.)
653///
654/// This is returned by [`PacketPile::descendants`] and
655/// [`Container::descendants`].
656///
657/// [container `Packet`s]: self#containers
658/// [`PacketPile::descendants`]: super::PacketPile::descendants()
659/// [`Container::descendants`]: Container::descendants()
660pub struct Iter<'a> {
661    // An iterator over the current message's children.
662    children: slice::Iter<'a, Packet>,
663    // The current child (i.e., the last value returned by
664    // children.next()).
665    child: Option<&'a Packet>,
666    // The iterator over the current child's children.
667    grandchildren: Option<Box<Iter<'a>>>,
668
669    // The depth of the last returned packet.  This is used by the
670    // `paths` iter.
671    depth: usize,
672}
673assert_send_and_sync!(Iter<'_>);
674
675impl<'a> Default for Iter<'a> {
676    fn default() -> Self {
677        Iter {
678            children: [].iter(),
679            child: None,
680            grandchildren: None,
681            depth: 0,
682        }
683    }
684}
685
686impl<'a> Iterator for Iter<'a> {
687    type Item = &'a Packet;
688
689    fn next(&mut self) -> Option<Self::Item> {
690        // If we don't have a grandchild iterator (self.grandchildren
691        // is None), then we are just starting, and we need to get the
692        // next child.
693        if let Some(ref mut grandchildren) = self.grandchildren {
694            let grandchild = grandchildren.next();
695            // If the grandchild iterator is exhausted (grandchild is
696            // None), then we need the next child.
697            if grandchild.is_some() {
698                self.depth = grandchildren.depth + 1;
699                return grandchild;
700            }
701        }
702
703        // Get the next child and the iterator for its children.
704        self.child = self.children.next();
705        if let Some(child) = self.child {
706            self.grandchildren = child.descendants().map(Box::new);
707        }
708
709        // First return the child itself.  Subsequent calls will
710        // return its grandchildren.
711        self.depth = 0;
712        self.child
713    }
714}
715
716impl<'a> Iter<'a> {
717    /// Extends an `Iter` to also return each packet's `pathspec`.
718    ///
719    /// This is similar to `enumerate`, but instead of counting, this
720    /// returns each packet's `pathspec` in addition to a reference to
721    /// the packet.
722    ///
723    /// See [`PacketPile::path_ref`] for an explanation of
724    /// `pathspec`s.
725    ///
726    /// [`PacketPile::path_ref`]: super::PacketPile::path_ref
727    ///
728    /// # Examples
729    ///
730    /// ```rust
731    /// use sequoia_openpgp as openpgp;
732    /// # use openpgp::Result;
733    /// use openpgp::packet::prelude::*;
734    /// use openpgp::PacketPile;
735    ///
736    /// # fn main() -> Result<()> {
737    /// # let message = {
738    /// #     use openpgp::types::CompressionAlgorithm;
739    /// #     use openpgp::packet;
740    /// #     use openpgp::PacketPile;
741    /// #     use openpgp::serialize::Serialize;
742    /// #     use openpgp::parse::Parse;
743    /// #     use openpgp::types::DataFormat;
744    /// #
745    /// #     let mut lit = Literal::new(DataFormat::Unicode);
746    /// #     lit.set_body(b"test".to_vec());
747    /// #     let lit = Packet::from(lit);
748    /// #
749    /// #     let mut cd = CompressedData::new(
750    /// #         CompressionAlgorithm::Uncompressed);
751    /// #     cd.set_body(packet::Body::Structured(vec![lit.clone()]));
752    /// #     let cd = Packet::from(cd);
753    /// #
754    /// #     // Make sure we created the message correctly: serialize,
755    /// #     // parse it, and then check its form.
756    /// #     let mut bytes = Vec::new();
757    /// #     cd.serialize(&mut bytes)?;
758    /// #
759    /// #     let pp = PacketPile::from_bytes(&bytes[..])?;
760    /// #
761    /// #     assert_eq!(pp.descendants().count(), 2);
762    /// #     assert_eq!(pp.path_ref(&[0]).unwrap().tag(),
763    /// #                packet::Tag::CompressedData);
764    /// #     assert_eq!(pp.path_ref(&[0, 0]), Some(&lit));
765    /// #
766    /// #     cd
767    /// # };
768    /// #
769    /// let pp = PacketPile::from(message);
770    /// let tags: Vec<(Vec<usize>, Tag)> = pp.descendants().paths()
771    ///     .map(|(path, packet)| (path, packet.into()))
772    ///     .collect::<Vec<_>>();
773    /// assert_eq!(&tags,
774    ///            &[
775    ///               // Root.
776    ///               ([0].to_vec(), Tag::CompressedData),
777    ///               // Root's first child.
778    ///               ([0, 0].to_vec(), Tag::Literal),
779    ///             ]);
780    /// # Ok(()) }
781    /// ```
782    pub fn paths(self)
783                 -> impl Iterator<Item = (Vec<usize>, &'a Packet)> + Send + Sync
784    {
785        PacketPathIter {
786            iter: self,
787            path: None,
788        }
789    }
790}
791
792
793/// Augments the packet returned by `Iter` with its `pathspec`.
794///
795/// Like [`Iter::enumerate`].
796///
797/// [`Iter::enumerate`]: std::iter::Iterator::enumerate()
798struct PacketPathIter<'a> {
799    iter: Iter<'a>,
800
801    // The path to the most recently returned node relative to the
802    // start of the iterator.
803    path: Option<Vec<usize>>,
804}
805
806impl<'a> Iterator for PacketPathIter<'a> {
807    type Item = (Vec<usize>, &'a Packet);
808
809    fn next(&mut self) -> Option<Self::Item> {
810        if let Some(packet) = self.iter.next() {
811            if self.path.is_none() {
812                // Init.
813                let mut path = Vec::with_capacity(4);
814                path.push(0);
815                self.path = Some(path);
816            } else {
817                let mut path = self.path.take().unwrap();
818                let old_depth = path.len() - 1;
819
820                let depth = self.iter.depth;
821                if old_depth > depth {
822                    // We popped.
823                    path.truncate(depth + 1);
824                    path[depth] += 1;
825                } else if old_depth == depth {
826                    // Sibling.
827                    path[old_depth] += 1;
828                } else if old_depth + 1 == depth {
829                    // Recursion.
830                    path.push(0);
831                }
832                self.path = Some(path);
833            }
834            Some((self.path.as_ref().unwrap().clone(), packet))
835        } else {
836            None
837        }
838    }
839}
840
841// Tests the `paths`() iter and `path_ref`().
842#[test]
843fn packet_path_iter() {
844    use crate::parse::Parse;
845    use crate::PacketPile;
846
847    fn paths<'a>(iter: impl Iterator<Item=&'a Packet>) -> Vec<Vec<usize>> {
848        let mut lpaths : Vec<Vec<usize>> = Vec::new();
849        for (i, packet) in iter.enumerate() {
850            let mut v = Vec::new();
851            v.push(i);
852            lpaths.push(v);
853
854            if let Some(container) = packet.container_ref() {
855                if let Some(c) = container.children() {
856                    for mut path in paths(c).into_iter()
857                    {
858                        path.insert(0, i);
859                        lpaths.push(path);
860                    }
861                }
862            }
863        }
864        lpaths
865    }
866
867    for i in 1..5 {
868        let pile = PacketPile::from_bytes(
869            crate::tests::message(&format!("recursive-{}.pgp", i)[..])).unwrap();
870
871        let mut paths1 : Vec<Vec<usize>> = Vec::new();
872        for path in paths(pile.children()).iter() {
873            paths1.push(path.clone());
874        }
875
876        let mut paths2 : Vec<Vec<usize>> = Vec::new();
877        for (path, packet) in pile.descendants().paths() {
878            assert_eq!(Some(packet), pile.path_ref(&path[..]));
879            paths2.push(path);
880        }
881
882        if paths1 != paths2 {
883            eprintln!("PacketPile:");
884            pile.pretty_print();
885
886            eprintln!("Expected paths:");
887            for p in paths1 {
888                eprintln!("  {:?}", p);
889            }
890
891            eprintln!("Got paths:");
892            for p in paths2 {
893                eprintln!("  {:?}", p);
894            }
895
896            panic!("Something is broken.  Don't panic.");
897        }
898    }
899}
900
901/// Holds a signature packet.
902///
903/// Signature packets are used to hold all kinds of signatures
904/// including certifications, and signatures over documents.  See
905/// [Section 5.2 of RFC 9580] for details.
906///
907///   [Section 5.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2
908///
909/// When signing a document, a `Signature` packet is typically created
910/// indirectly by the [streaming `Signer`].  Similarly, a `Signature`
911/// packet is created as a side effect of parsing a signed message
912/// using the [`PacketParser`].
913///
914/// `Signature` packets are also used for [self signatures on Keys],
915/// [self signatures on User IDs], [self signatures on User
916/// Attributes], [certifications of User IDs], and [certifications of
917/// User Attributes].  In these cases, you'll typically want to use
918/// the [`SignatureBuilder`] to create the `Signature` packet.  See
919/// the linked documentation for details, and examples.
920///
921/// [streaming `Signer`]: crate::serialize::stream::Signer
922/// [`PacketParser`]: crate::parse::PacketParser
923/// [self signatures on Keys]: Key::bind()
924/// [self signatures on User IDs]: UserID::bind()
925/// [self signatures on User Attributes]: user_attribute::UserAttribute::bind()
926/// [certifications of User IDs]: UserID::certify()
927/// [certifications of User Attributes]: user_attribute::UserAttribute::certify()
928/// [`SignatureBuilder`]: signature::SignatureBuilder
929///
930/// # A note on equality
931///
932/// Two `Signature` packets are considered equal if their serialized
933/// form is equal.  Notably this includes the unhashed subpacket area
934/// and the order of subpackets and notations.  This excludes the
935/// computed digest and signature level, which are not serialized.
936///
937/// A consequence of considering packets in the unhashed subpacket
938/// area is that an adversary can take a valid signature and create
939/// many distinct but valid signatures by changing the unhashed
940/// subpacket area.  This has the potential of creating a denial of
941/// service vector, if `Signature`s are naively deduplicated.  To
942/// protect against this, consider using [`Signature::normalized_eq`].
943///
944///   [`Signature::normalized_eq`]: Signature::normalized_eq()
945///
946/// # Examples
947///
948/// Add a User ID to an existing certificate:
949///
950/// ```
951/// use std::time;
952/// use sequoia_openpgp as openpgp;
953/// use openpgp::cert::prelude::*;
954/// use openpgp::packet::prelude::*;
955/// use openpgp::policy::StandardPolicy;
956///
957/// # fn main() -> openpgp::Result<()> {
958/// let p = &StandardPolicy::new();
959///
960/// let t1 = time::SystemTime::now();
961/// let t2 = t1 + time::Duration::from_secs(1);
962///
963/// let (cert, _) = CertBuilder::new()
964///     .set_creation_time(t1)
965///     .add_userid("Alice <alice@example.org>")
966///     .generate()?;
967///
968/// // Add a new User ID.
969/// let mut signer = cert
970///     .primary_key().key().clone().parts_into_secret()?.into_keypair()?;
971///
972/// // Use the existing User ID's signature as a template.  This ensures that
973/// // we use the same
974/// let userid = UserID::from("Alice <alice@other.com>");
975/// let template: signature::SignatureBuilder
976///     = cert.with_policy(p, t1)?.primary_userid().unwrap()
977///         .binding_signature().clone().into();
978/// let sig = template.clone()
979///     .set_signature_creation_time(t2)?;
980/// let sig = userid.bind(&mut signer, &cert, sig)?;
981///
982/// let cert = cert.insert_packets(vec![Packet::from(userid), sig.into()])?.0;
983/// # assert_eq!(cert.with_policy(p, t2)?.userids().count(), 2);
984/// # Ok(()) }
985/// ```
986#[non_exhaustive]
987#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)]
988pub enum Signature {
989    /// Signature packet version 3.
990    V3(self::signature::Signature3),
991
992    /// Signature packet version 4.
993    V4(self::signature::Signature4),
994
995    /// Signature packet version 6.
996    V6(self::signature::Signature6),
997}
998assert_send_and_sync!(Signature);
999
1000impl Signature {
1001    /// Gets the version.
1002    pub fn version(&self) -> u8 {
1003        match self {
1004            Signature::V3(_) => 3,
1005            Signature::V4(_) => 4,
1006            Signature::V6(_) => 6,
1007        }
1008    }
1009}
1010
1011impl From<Signature> for Packet {
1012    fn from(s: Signature) -> Self {
1013        Packet::Signature(s)
1014    }
1015}
1016
1017impl Signature {
1018    /// Gets the salt, if any.
1019    pub fn salt(&self) -> Option<&[u8]> {
1020        match self {
1021            Signature::V3(_) => None,
1022            Signature::V4(_) => None,
1023            Signature::V6(s) => Some(s.salt()),
1024        }
1025    }
1026
1027}
1028
1029// Trivial forwarder for singleton enum.
1030impl Deref for Signature {
1031    type Target = signature::Signature4;
1032
1033    fn deref(&self) -> &Self::Target {
1034        match self {
1035            Signature::V3(sig) => &sig.intern,
1036            Signature::V4(sig) => sig,
1037            Signature::V6(sig) => &sig.common,
1038        }
1039    }
1040}
1041
1042// Trivial forwarder for singleton enum.
1043impl DerefMut for Signature {
1044    fn deref_mut(&mut self) -> &mut Self::Target {
1045        match self {
1046            Signature::V3(ref mut sig) => &mut sig.intern,
1047            Signature::V4(ref mut sig) => sig,
1048            Signature::V6(ref mut sig) => &mut sig.common,
1049        }
1050    }
1051}
1052
1053/// Holds a SEIP packet.
1054///
1055/// A SEIP packet holds encrypted data.  The data contains additional
1056/// OpenPGP packets.  See [Section 5.13 of RFC 9580] for details.
1057///
1058/// A SEIP packet is not normally instantiated directly.  In most
1059/// cases, you'll create one as a side effect of encrypting a message
1060/// using the [streaming serializer], or parsing an encrypted message
1061/// using the [`PacketParser`].
1062///
1063/// [Section 5.13 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.13
1064/// [streaming serializer]: crate::serialize::stream
1065/// [`PacketParser`]: crate::parse::PacketParser
1066#[derive(PartialEq, Eq, Hash, Clone, Debug)]
1067#[non_exhaustive]
1068pub enum SEIP {
1069    /// SEIP packet version 1.
1070    V1(self::seip::SEIP1),
1071
1072    /// SEIP packet version 2.
1073    V2(self::seip::SEIP2),
1074}
1075assert_send_and_sync!(SEIP);
1076
1077impl SEIP {
1078    /// Gets the version.
1079    pub fn version(&self) -> u8 {
1080        match self {
1081            SEIP::V1(_) => 1,
1082            SEIP::V2(_) => 2,
1083        }
1084    }
1085}
1086
1087impl From<SEIP> for Packet {
1088    fn from(p: SEIP) -> Self {
1089        Packet::SEIP(p)
1090    }
1091}
1092
1093#[cfg(test)]
1094mod test {
1095    use super::*;
1096    use crate::serialize::SerializeInto;
1097    use crate::parse::Parse;
1098
1099    quickcheck! {
1100        fn roundtrip(p: Packet) -> bool {
1101            let buf = p.to_vec().expect("Failed to serialize packet");
1102            let q = Packet::from_bytes(&buf).unwrap();
1103            assert_eq!(p, q);
1104            true
1105        }
1106    }
1107
1108    quickcheck! {
1109        /// Given a packet and a position, induces a bit flip in the
1110        /// serialized form, then checks that PartialEq detects that.
1111        /// Recall that for packets, PartialEq is defined using the
1112        /// serialized form.
1113        fn mutate_eq_discriminates(p: Packet, i: usize) -> bool {
1114            if p.tag() == Tag::CompressedData {
1115                // Mutating compressed data streams is not that
1116                // trivial, because there are bits we can flip without
1117                // changing the decompressed data.
1118                return true;
1119            }
1120
1121            let mut buf = p.to_vec().unwrap();
1122            // Avoid first two bytes so that we don't change the
1123            // type and reduce the chance of changing the length.
1124            if buf.len() < 3 { return true; }
1125            let bit = i % ((buf.len() - 2) * 8) + 16;
1126            buf[bit / 8] ^= 1 << (bit % 8);
1127            match Packet::from_bytes(&buf) {
1128                Ok(q) => p != q,
1129                Err(_) => true, // Packet failed to parse.
1130            }
1131        }
1132    }
1133
1134    /// Problem on systems with 32-bit time_t.
1135    #[test]
1136    fn issue_802() -> Result<()> {
1137        let pp = crate::PacketPile::from_bytes(b"-----BEGIN PGP ARMORED FILE-----
1138
1139xiEE/////xIJKyQDAwIIAQENAFYp8M2JngCfc04tIwMBCuU=
1140-----END PGP ARMORED FILE-----
1141")?;
1142        let p = pp.path_ref(&[0]).unwrap();
1143        let buf = p.to_vec().expect("Failed to serialize packet");
1144        let q = Packet::from_bytes(&buf).unwrap();
1145        assert_eq!(p, &q);
1146        Ok(())
1147    }
1148}