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}