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 [`Deref`]
70 //! to [`Container`].)
71 //!
72 //! # Packet Headers and Bodies
73 //!
74 //! Conceptually, packets have zero or more headers and an optional
75 //! body.  The headers are small, and have a known upper bound.  The
76 //! version field is, for instance, 4 bytes, and although
77 //! [`Signature`][] [`SubpacketArea`][] areas are variable in size,
78 //! they are limited to 64 KB.  In contrast the body, can be unbounded
79 //! in size.
80 //!
81 //! To limit memory use, and enable streaming processing (i.e.,
82 //! ensuring that processing a message can be done using a fixed size
83 //! buffer), Sequoia does not require that a packet's body be present
84 //! in memory.  For instance, the body of a literal data packet may be
85 //! streamed.  And, at the end, a [`Literal`] packet is still
86 //! returned.  This allows the caller to examine the message
87 //! structure, and the message headers in *in toto* even when
88 //! streaming.  It is even possible to compare two streamed version of
89 //! a packet: Sequoia stores a hash of the body.  See the [`Body`]
90 //! data structure for more details.
91 //!
92 //! # Equality
93 //!
94 //! There are several reasonable ways to define equality for
95 //! `Packet`s.  Unfortunately, none of them are appropriate in all
96 //! situations.  This makes choosing a general-purpose equality
97 //! function for [`Eq`] difficult.
98 //!
99 //! Consider defining `Eq` as the equivalence of two `Packet`s'
100 //! serialized forms.  If an application naively deduplicates
101 //! signatures, then an attacker can potentially perform a denial of
102 //! service attack by causing the application to process many
103 //! cryptographically-valid `Signature`s by varying the content of one
104 //! cryptographically-valid `Signature`'s unhashed area.  This attack
105 //! can be prevented by only comparing data that is protected by the
106 //! signature.  But this means that naively deduplicating `Signature`
107 //! packets will return in "a random" variant being used.  So, again,
108 //! an attacker could create variants of a cryptographically-valid
109 //! `Signature` to get the implementation to incorrectly drop a useful
110 //! one.
111 //!
112 //! These issues are also relevant when comparing [`Key`s]: should the
113 //! secret key material be compared?  Usually we want to merge the
114 //! secret key material.  But, again, if done naively, the incorrect
115 //! secret key material may be retained or dropped completely.
116 //!
117 //! Instead of trying to come up with a definition of equality that is
118 //! reasonable for all situations, we use a conservative definition:
119 //! two packets are considered equal if the serialized forms of their
120 //! packet bodies as defined by RFC 4880 are equal.  That is, two
121 //! packets are considered equal if and only if their serialized forms
122 //! are equal modulo the OpenPGP framing ([`CTB`] and [length style],
123 //! potential [partial body encoding]).  This definition will avoid
124 //! unintentionally dropping information when naively deduplicating
125 //! packets, but it will result in potential redundancies.
126 //!
127 //! For some packets, we provide additional variants of equality.  For
128 //! instance, [`Key::public_cmp`] compares just the public parts of
129 //! two keys.
130 //!
131 //! [packet based]: https://tools.ietf.org/html/rfc4880#section-5
132 //! [the grammar]: https://tools.ietf.org/html/rfc4880#section-11
133 //! [`Signature`]: enum.Signature.html
134 //! [v3]: https://tools.ietf.org/html/rfc4880#section-5.2.2
135 //! [v4]: https://tools.ietf.org/html/rfc4880#section-5.2.3
136 //! [`OnePassSig`]: enum.OnePassSig.html
137 //! [parsing a message]: ../parse/index.html
138 //! [creating a message]: ../serialize/stream/index.html
139 //! [`SignatureBuilder`]: signature/struct.SignatureBuilder.html
140 //! [`SED`]: https://tools.ietf.org/html/rfc4880#section-5.7
141 //! [`Unknown`]: struct.Unknown.html
142 //! [private extensions]: https://tools.ietf.org/html/rfc4880#section-4.3
143 //! [`Compressed Data`]: struct.CompressedData.html
144 //! [parses]: ../parse/index.html
145 //! [OpenPGP Message]: https://tools.ietf.org/html/rfc4880#section-11.3
146 //! [`Container::descendants`]: struct.Container.html#method.descendants
147 //! [`Deref`]: https://doc.rust-lang.org/stable/std/ops/trait.Deref.html
148 //! [`Container`]: struct.Container.html
149 //! [`Signature`]: enum.Signature.html
150 //! [`SubpacketArea`]: signature/subpacket/struct.SubpacketArea.html
151 //! [`Literal`]: struct.Literal.html
152 //! [`Body`]: enum.Body.html
153 //! [`Eq`]: https://doc.rust-lang.org/stable/std/cmp/trait.Eq.html
154 //! [`Key`s]: enum.Key.html
155 //! [`CTB`]: header/enum.CTB.html
156 //! [length style]: https://tools.ietf.org/html/rfc4880#section-4.2
157 //! [partial body encoding]: https://tools.ietf.org/html/rfc4880#section-4.2.2.4
158 //! [`Key::public_cmp`]: enum.Key.html#method.public_cmp
159 use std::fmt;
160 use std::ops::{Deref, DerefMut};
161 use std::slice;
162 use std::iter::IntoIterator;
163 
164 #[cfg(any(test, feature = "quickcheck"))]
165 use quickcheck::{Arbitrary, Gen};
166 
167 use crate::Error;
168 use crate::Result;
169 
170 #[macro_use]
171 mod container;
172 pub use container::Container;
173 pub use container::Body;
174 
175 pub mod prelude;
176 
177 use crate::crypto::{
178     KeyPair,
179     Password,
180 };
181 
182 mod tag;
183 pub use self::tag::Tag;
184 pub mod header;
185 pub use self::header::Header;
186 
187 mod unknown;
188 pub use self::unknown::Unknown;
189 pub mod signature;
190 pub mod one_pass_sig;
191 pub mod key;
192 use key::{
193     Key4,
194     SecretKeyMaterial
195 };
196 mod marker;
197 pub use self::marker::Marker;
198 mod trust;
199 pub use self::trust::Trust;
200 mod userid;
201 pub use self::userid::UserID;
202 pub mod user_attribute;
203 pub use self::user_attribute::UserAttribute;
204 mod literal;
205 pub use self::literal::Literal;
206 mod compressed_data;
207 pub use self::compressed_data::CompressedData;
208 pub mod seip;
209 pub mod skesk;
210 pub mod pkesk;
211 mod mdc;
212 pub use self::mdc::MDC;
213 pub mod aed;
214 
215 // DOC-HACK: To avoid having a top-level re-export of `Cert`, we move
216 // it in a submodule `def`.
217 pub use def::Packet;
218 mod def {
219 use super::*;
220 /// Enumeration of packet types.
221 ///
222 /// The different OpenPGP packets are detailed in [Section 5 of RFC 4880].
223 ///
224 /// The [`Unknown`] packet allows Sequoia to deal with packets that it
225 /// doesn't understand.  It is basically a binary blob that includes
226 /// the packet's [tag].  See the [module-level documentation] for
227 /// details.
228 ///
229 /// Note: This enum cannot be exhaustively matched to allow future
230 /// extensions.
231 ///
232 /// # A note on equality
233 ///
234 /// We define equality on `Packet` as the equality of the serialized
235 /// form of their packet bodies as defined by RFC 4880.  That is, two
236 /// packets are considered equal if and only if their serialized forms
237 /// are equal, modulo the OpenPGP framing ([`CTB`] and [length style],
238 /// potential [partial body encoding]).
239 ///
240 /// [`Unknown`]: struct.Unknown.html
241 /// [tag]: https://tools.ietf.org/html/rfc4880#section-4.3
242 /// [module-level documentation]: index.html#unknown-packets
243 /// [`CTB`]: header/enum.CTB.html
244 /// [length style]: https://tools.ietf.org/html/rfc4880#section-4.2
245 /// [partial body encoding]: https://tools.ietf.org/html/rfc4880#section-4.2.2.4
246 #[derive(Debug)]
247 #[derive(PartialEq, Eq, Hash, Clone)]
248 pub enum Packet {
249     /// Unknown packet.
250     Unknown(Unknown),
251     /// Signature packet.
252     Signature(Signature),
253     /// One pass signature packet.
254     OnePassSig(OnePassSig),
255     /// Public key packet.
256     PublicKey(key::PublicKey),
257     /// Public subkey packet.
258     PublicSubkey(key::PublicSubkey),
259     /// Public/Secret key pair.
260     SecretKey(key::SecretKey),
261     /// Public/Secret subkey pair.
262     SecretSubkey(key::SecretSubkey),
263     /// Marker packet.
264     Marker(Marker),
265     /// Trust packet.
266     Trust(Trust),
267     /// User ID packet.
268     UserID(UserID),
269     /// User attribute packet.
270     UserAttribute(UserAttribute),
271     /// Literal data packet.
272     Literal(Literal),
273     /// Compressed literal data packet.
274     CompressedData(CompressedData),
275     /// Public key encrypted data packet.
276     PKESK(PKESK),
277     /// Symmetric key encrypted data packet.
278     SKESK(SKESK),
279     /// Symmetric key encrypted, integrity protected data packet.
280     SEIP(SEIP),
281     /// Modification detection code packet.
282     MDC(MDC),
283     /// AEAD Encrypted Data Packet.
284     AED(AED),
285 
286     /// This marks this enum as non-exhaustive.  Do not use this
287     /// variant.
288     #[doc(hidden)] __Nonexhaustive,
289 }
290 } // doc-hack, see above
291 
292 macro_rules! impl_into_iterator {
293     ($t:ty) => {
294         impl_into_iterator!($t where);
295     };
296     ($t:ty where $( $w:ident: $c:path ),*) => {
297         /// Implement `IntoIterator` so that
298         /// `cert::merge_packets(sig)` just works.
299         impl<$($w),*> IntoIterator for $t
300             where $($w: $c ),*
301         {
302             type Item = $t;
303             type IntoIter = std::iter::Once<$t>;
304 
305             fn into_iter(self) -> Self::IntoIter {
306                 std::iter::once(self)
307             }
308         }
309     }
310 }
311 
312 impl_into_iterator!(Packet);
313 impl_into_iterator!(Unknown);
314 impl_into_iterator!(Signature);
315 impl_into_iterator!(OnePassSig);
316 impl_into_iterator!(Marker);
317 impl_into_iterator!(Trust);
318 impl_into_iterator!(UserID);
319 impl_into_iterator!(UserAttribute);
320 impl_into_iterator!(Literal);
321 impl_into_iterator!(CompressedData);
322 impl_into_iterator!(PKESK);
323 impl_into_iterator!(SKESK);
324 impl_into_iterator!(SEIP);
325 impl_into_iterator!(MDC);
326 impl_into_iterator!(AED);
327 impl_into_iterator!(Key<P, R> where P: key::KeyParts, R: key::KeyRole);
328 
329 // Make it easy to pass an iterator of Packets to something expecting
330 // an iterator of Into<Result<Packet>> (specifically,
331 // CertParser::into_iter).
332 impl From<Packet> for Result<Packet> {
from(p: Packet) -> Self333     fn from(p: Packet) -> Self {
334         Ok(p)
335     }
336 }
337 
338 impl Packet {
339     /// Returns the `Packet's` corresponding OpenPGP tag.
340     ///
341     /// Tags are explained in [Section 4.3 of RFC 4880].
342     ///
343     ///   [Section 4.3 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-4.3
tag(&self) -> Tag344     pub fn tag(&self) -> Tag {
345         match self {
346             &Packet::Unknown(ref packet) => packet.tag(),
347             &Packet::Signature(_) => Tag::Signature,
348             &Packet::OnePassSig(_) => Tag::OnePassSig,
349             &Packet::PublicKey(_) => Tag::PublicKey,
350             &Packet::PublicSubkey(_) => Tag::PublicSubkey,
351             &Packet::SecretKey(_) => Tag::SecretKey,
352             &Packet::SecretSubkey(_) => Tag::SecretSubkey,
353             &Packet::Marker(_) => Tag::Marker,
354             &Packet::Trust(_) => Tag::Trust,
355             &Packet::UserID(_) => Tag::UserID,
356             &Packet::UserAttribute(_) => Tag::UserAttribute,
357             &Packet::Literal(_) => Tag::Literal,
358             &Packet::CompressedData(_) => Tag::CompressedData,
359             &Packet::PKESK(_) => Tag::PKESK,
360             &Packet::SKESK(_) => Tag::SKESK,
361             &Packet::SEIP(_) => Tag::SEIP,
362             &Packet::MDC(_) => Tag::MDC,
363             &Packet::AED(_) => Tag::AED,
364             Packet::__Nonexhaustive => unreachable!(),
365         }
366     }
367 
368     /// Returns the parsed `Packet's` corresponding OpenPGP tag.
369     ///
370     /// Returns the packets tag, but only if it was successfully
371     /// parsed into the corresponding packet type.  If e.g. a
372     /// Signature Packet uses some unsupported methods, it is parsed
373     /// into an `Packet::Unknown`.  `tag()` returns `Tag::Signature`,
374     /// whereas `kind()` returns `None`.
kind(&self) -> Option<Tag>375     pub fn kind(&self) -> Option<Tag> {
376         match self {
377             &Packet::Unknown(_) => None,
378             _ => Some(self.tag()),
379         }
380     }
381 }
382 
383 // Allow transparent access of common fields.
384 impl<'a> Deref for Packet {
385     type Target = Common;
386 
deref(&self) -> &Self::Target387     fn deref(&self) -> &Self::Target {
388         match self {
389             &Packet::Unknown(ref packet) => &packet.common,
390             &Packet::Signature(ref packet) => &packet.common,
391             &Packet::OnePassSig(ref packet) => &packet.common,
392             &Packet::PublicKey(ref packet) => &packet.common,
393             &Packet::PublicSubkey(ref packet) => &packet.common,
394             &Packet::SecretKey(ref packet) => &packet.common,
395             &Packet::SecretSubkey(ref packet) => &packet.common,
396             &Packet::Marker(ref packet) => &packet.common,
397             &Packet::Trust(ref packet) => &packet.common,
398             &Packet::UserID(ref packet) => &packet.common,
399             &Packet::UserAttribute(ref packet) => &packet.common,
400             &Packet::Literal(ref packet) => &packet.common,
401             &Packet::CompressedData(ref packet) => &packet.common,
402             &Packet::PKESK(ref packet) => &packet.common,
403             &Packet::SKESK(SKESK::V4(ref packet)) => &packet.common,
404             &Packet::SKESK(SKESK::V5(ref packet)) => &packet.skesk4.common,
405             Packet::SKESK(SKESK::__Nonexhaustive) => unreachable!(),
406             &Packet::SEIP(ref packet) => &packet.common,
407             &Packet::MDC(ref packet) => &packet.common,
408             &Packet::AED(ref packet) => &packet.common,
409             Packet::__Nonexhaustive => unreachable!(),
410         }
411     }
412 }
413 
414 impl<'a> DerefMut for Packet {
deref_mut(&mut self) -> &mut Common415     fn deref_mut(&mut self) -> &mut Common {
416         match self {
417             &mut Packet::Unknown(ref mut packet) => &mut packet.common,
418             &mut Packet::Signature(ref mut packet) => &mut packet.common,
419             &mut Packet::OnePassSig(ref mut packet) => &mut packet.common,
420             &mut Packet::PublicKey(ref mut packet) => &mut packet.common,
421             &mut Packet::PublicSubkey(ref mut packet) => &mut packet.common,
422             &mut Packet::SecretKey(ref mut packet) => &mut packet.common,
423             &mut Packet::SecretSubkey(ref mut packet) => &mut packet.common,
424             &mut Packet::Marker(ref mut packet) => &mut packet.common,
425             &mut Packet::Trust(ref mut packet) => &mut packet.common,
426             &mut Packet::UserID(ref mut packet) => &mut packet.common,
427             &mut Packet::UserAttribute(ref mut packet) => &mut packet.common,
428             &mut Packet::Literal(ref mut packet) => &mut packet.common,
429             &mut Packet::CompressedData(ref mut packet) => &mut packet.common,
430             &mut Packet::PKESK(ref mut packet) => &mut packet.common,
431             &mut Packet::SKESK(SKESK::V4(ref mut packet)) => &mut packet.common,
432             &mut Packet::SKESK(SKESK::V5(ref mut packet)) => &mut packet.skesk4.common,
433             Packet::SKESK(SKESK::__Nonexhaustive) => unreachable!(),
434             &mut Packet::SEIP(ref mut packet) => &mut packet.common,
435             &mut Packet::MDC(ref mut packet) => &mut packet.common,
436             &mut Packet::AED(ref mut packet) => &mut packet.common,
437             Packet::__Nonexhaustive => unreachable!(),
438         }
439     }
440 }
441 
442 #[cfg(any(test, feature = "quickcheck"))]
443 impl Arbitrary for Packet {
arbitrary<G: Gen>(g: &mut G) -> Self444     fn arbitrary<G: Gen>(g: &mut G) -> Self {
445         use rand::Rng;
446         match g.gen_range(0, 14) {
447             0 => Signature::arbitrary(g).into(),
448             1 => OnePassSig::arbitrary(g).into(),
449             2 => Key::<key::PublicParts, key::UnspecifiedRole>::arbitrary(g)
450                 .role_into_primary().into(),
451             3 => Key::<key::PublicParts, key::UnspecifiedRole>::arbitrary(g)
452                 .role_into_subordinate().into(),
453             4 => Key::<key::SecretParts, key::UnspecifiedRole>::arbitrary(g)
454                 .role_into_primary().into(),
455             5 => Key::<key::SecretParts, key::UnspecifiedRole>::arbitrary(g)
456                 .role_into_subordinate().into(),
457             6 => Marker::arbitrary(g).into(),
458             7 => Trust::arbitrary(g).into(),
459             8 => UserID::arbitrary(g).into(),
460             9 => UserAttribute::arbitrary(g).into(),
461             10 => Literal::arbitrary(g).into(),
462             11 => CompressedData::arbitrary(g).into(),
463             12 => PKESK::arbitrary(g).into(),
464             13 => SKESK::arbitrary(g).into(),
465             _ => unreachable!(),
466         }
467     }
468 }
469 
470 /// Fields used by multiple packet types.
471 #[derive(Debug, Clone)]
472 pub struct Common {
473     // In the future, this structure will hold the parsed CTB, packet
474     // length, and lengths of chunks of partial body encoded packets.
475     // This will allow for bit-perfect roundtripping of parsed
476     // packets.  Since we consider Packets to be equal if their
477     // serialized form is equal modulo CTB, packet length encoding,
478     // and chunk lengths, this structure has trivial implementations
479     // for PartialEq, Eq, PartialOrd, Ord, and Hash, so that we can
480     // derive PartialEq, Eq, PartialOrd, Ord, and Hash for most
481     // packets.
482 
483     /// XXX: Prevents trivial matching on this structure.  Remove once
484     /// this structure actually gains some fields.
485     dummy: std::marker::PhantomData<()>,
486 }
487 
488 #[cfg(any(test, feature = "quickcheck"))]
489 impl Arbitrary for Common {
arbitrary<G: Gen>(_: &mut G) -> Self490     fn arbitrary<G: Gen>(_: &mut G) -> Self {
491         // XXX: Change if this gets interesting fields.
492         Common::default()
493     }
494 }
495 
496 impl Default for Common {
default() -> Common497     fn default() -> Common {
498         Common {
499             dummy: Default::default(),
500         }
501     }
502 }
503 
504 impl PartialEq for Common {
eq(&self, _: &Common) -> bool505     fn eq(&self, _: &Common) -> bool {
506         // Don't compare anything.
507         true
508     }
509 }
510 
511 impl Eq for Common {}
512 
513 impl PartialOrd for Common {
partial_cmp(&self, _: &Self) -> Option<std::cmp::Ordering>514     fn partial_cmp(&self, _: &Self) -> Option<std::cmp::Ordering> {
515         Some(std::cmp::Ordering::Equal)
516     }
517 }
518 
519 impl Ord for Common {
cmp(&self, _: &Self) -> std::cmp::Ordering520     fn cmp(&self, _: &Self) -> std::cmp::Ordering {
521         std::cmp::Ordering::Equal
522     }
523 }
524 
525 impl std::hash::Hash for Common {
hash<H: std::hash::Hasher>(&self, _: &mut H)526     fn hash<H: std::hash::Hasher>(&self, _: &mut H) {
527         // Don't hash anything.
528     }
529 }
530 
531 
532 /// An iterator over the *contents* of a packet in depth-first order.
533 ///
534 /// Given a [`Packet`], an `Iter` iterates over the `Packet` and any
535 /// `Packet`s that it contains.  For non-container `Packet`s, this
536 /// just returns a reference to the `Packet` itself.  For [container
537 /// `Packet`s] like [`CompressedData`], [`SEIP`], and [`AED`], this
538 /// walks the `Packet` hierarchy in depth-first order, and returns the
539 /// `Packet`s the first time they are visited.  (Thus, the packet
540 /// itself is always returned first.)
541 ///
542 /// This is returned by [`PacketPile::descendants`] and
543 /// [`Container::descendants`].
544 ///
545 /// [`Packet`]: enum.Packet.html
546 /// [container `Packet`s]: index.html#containers
547 /// [`CompressedData`]: struct.CompressedData.html
548 /// [`SEIP`]: enum.SEIP.html
549 /// [`AED`]: enum.AED.html
550 /// [`PacketPile::descendants`]: ../struct.PacketPile.html#method.descendants
551 /// [`Container::descendants`]: struct.Container.html#method.descendants
552 pub struct Iter<'a> {
553     // An iterator over the current message's children.
554     children: slice::Iter<'a, Packet>,
555     // The current child (i.e., the last value returned by
556     // children.next()).
557     child: Option<&'a Packet>,
558     // The an iterator over the current child's children.
559     grandchildren: Option<Box<Iter<'a>>>,
560 
561     // The depth of the last returned packet.  This is used by the
562     // `paths` iter.
563     depth: usize,
564 }
565 
566 impl<'a> Default for Iter<'a> {
default() -> Self567     fn default() -> Self {
568         Iter {
569             children: [].iter(),
570             child: None,
571             grandchildren: None,
572             depth: 0,
573         }
574     }
575 }
576 
577 impl<'a> Iterator for Iter<'a> {
578     type Item = &'a Packet;
579 
next(&mut self) -> Option<Self::Item>580     fn next(&mut self) -> Option<Self::Item> {
581         // If we don't have a grandchild iterator (self.grandchildren
582         // is None), then we are just starting, and we need to get the
583         // next child.
584         if let Some(ref mut grandchildren) = self.grandchildren {
585             let grandchild = grandchildren.next();
586             // If the grandchild iterator is exhausted (grandchild is
587             // None), then we need the next child.
588             if grandchild.is_some() {
589                 self.depth = grandchildren.depth + 1;
590                 return grandchild;
591             }
592         }
593 
594         // Get the next child and the iterator for its children.
595         self.child = self.children.next();
596         if let Some(child) = self.child {
597             self.grandchildren = child.descendants().map(|d| Box::new(d));
598         }
599 
600         // First return the child itself.  Subsequent calls will
601         // return its grandchildren.
602         self.depth = 0;
603         return self.child;
604     }
605 }
606 
607 impl<'a> Iter<'a> {
608     /// Extends an `Iter` to also return each packet's `pathspec`.
609     ///
610     /// This is similar to `enumerate`, but instead of counting, this
611     /// returns each packet's `pathspec` in addition to a reference to
612     /// the packet.
613     ///
614     /// See [`PacketPile::path_ref`] for an explanation of
615     /// `pathspec`s.
616     ///
617     /// [`PacketPile::path_ref`]: ../struct.PacketPile.html#path_ref
618     ///
619     /// # Examples
620     ///
621     /// ```rust
622     /// use sequoia_openpgp as openpgp;
623     /// # use openpgp::Result;
624     /// use openpgp::packet::prelude::*;
625     /// use openpgp::PacketPile;
626     ///
627     /// # fn main() -> Result<()> {
628     /// # let message = {
629     /// #     use openpgp::types::CompressionAlgorithm;
630     /// #     use openpgp::packet;
631     /// #     use openpgp::PacketPile;
632     /// #     use openpgp::serialize::Serialize;
633     /// #     use openpgp::parse::Parse;
634     /// #     use openpgp::types::DataFormat;
635     /// #
636     /// #     let mut lit = Literal::new(DataFormat::Text);
637     /// #     lit.set_body(b"test".to_vec());
638     /// #     let lit = Packet::from(lit);
639     /// #
640     /// #     let mut cd = CompressedData::new(
641     /// #         CompressionAlgorithm::Uncompressed);
642     /// #     cd.set_body(packet::Body::Structured(vec![lit.clone()]));
643     /// #     let cd = Packet::from(cd);
644     /// #
645     /// #     // Make sure we created the message correctly: serialize,
646     /// #     // parse it, and then check its form.
647     /// #     let mut bytes = Vec::new();
648     /// #     cd.serialize(&mut bytes)?;
649     /// #
650     /// #     let pp = PacketPile::from_bytes(&bytes[..])?;
651     /// #
652     /// #     assert_eq!(pp.descendants().count(), 2);
653     /// #     assert_eq!(pp.path_ref(&[0]).unwrap().tag(),
654     /// #                packet::Tag::CompressedData);
655     /// #     assert_eq!(pp.path_ref(&[0, 0]), Some(&lit));
656     /// #
657     /// #     cd
658     /// # };
659     /// #
660     /// let pp = PacketPile::from(message);
661     /// let tags: Vec<(Vec<usize>, Tag)> = pp.descendants().paths()
662     ///     .map(|(path, packet)| (path, packet.into()))
663     ///     .collect::<Vec<_>>();
664     /// assert_eq!(&tags,
665     ///            &[
666     ///               // Root.
667     ///               ([0].to_vec(), Tag::CompressedData),
668     ///               // Root's first child.
669     ///               ([0, 0].to_vec(), Tag::Literal),
670     ///             ]);
671     /// # Ok(()) }
672     /// ```
paths(self) -> impl Iterator<Item = (Vec<usize>, &'a Packet)>673     pub fn paths(self) -> impl Iterator<Item = (Vec<usize>, &'a Packet)> {
674         PacketPathIter {
675             iter: self,
676             path: None,
677         }
678     }
679 }
680 
681 
682 /// Augments the packet returned by `Iter` with its `pathspec`.
683 ///
684 /// Like [`Iter::enumerate`].
685 ///
686 /// [`Iter::enumerate`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.enumerate
687 /// [`Iter`]: struct.Iter.html
688 struct PacketPathIter<'a> {
689     iter: Iter<'a>,
690 
691     // The path to the most recently returned node relative to the
692     // start of the iterator.
693     path: Option<Vec<usize>>,
694 }
695 
696 impl<'a> Iterator for PacketPathIter<'a> {
697     type Item = (Vec<usize>, &'a Packet);
698 
next(&mut self) -> Option<Self::Item>699     fn next(&mut self) -> Option<Self::Item> {
700         if let Some(packet) = self.iter.next() {
701             if self.path.is_none() {
702                 // Init.
703                 let mut path = Vec::with_capacity(4);
704                 path.push(0);
705                 self.path = Some(path);
706             } else {
707                 let mut path = self.path.take().unwrap();
708                 let old_depth = path.len() - 1;
709 
710                 let depth = self.iter.depth;
711                 if old_depth > depth {
712                     // We popped.
713                     path.truncate(depth + 1);
714                     path[depth] += 1;
715                 } else if old_depth == depth {
716                     // Sibling.
717                     path[old_depth] += 1;
718                 } else if old_depth + 1 == depth {
719                     // Recursion.
720                     path.push(0);
721                 }
722                 self.path = Some(path);
723             }
724             Some((self.path.as_ref().unwrap().clone(), packet))
725         } else {
726             None
727         }
728     }
729 }
730 
731 // Tests the `paths`() iter and `path_ref`().
732 #[test]
packet_path_iter()733 fn packet_path_iter() {
734     use crate::parse::Parse;
735     use crate::PacketPile;
736 
737     fn paths<'a>(iter: impl Iterator<Item=&'a Packet>) -> Vec<Vec<usize>> {
738         let mut lpaths : Vec<Vec<usize>> = Vec::new();
739         for (i, packet) in iter.enumerate() {
740             let mut v = Vec::new();
741             v.push(i);
742             lpaths.push(v);
743 
744             if let Some(ref container) = packet.container_ref() {
745                 if let Some(c) = container.children() {
746                     for mut path in paths(c).into_iter()
747                     {
748                         path.insert(0, i);
749                         lpaths.push(path);
750                     }
751                 }
752             }
753         }
754         lpaths
755     }
756 
757     for i in 1..5 {
758         let pile = PacketPile::from_bytes(
759             crate::tests::message(&format!("recursive-{}.gpg", i)[..])).unwrap();
760 
761         let mut paths1 : Vec<Vec<usize>> = Vec::new();
762         for path in paths(pile.children()).iter() {
763             paths1.push(path.clone());
764         }
765 
766         let mut paths2 : Vec<Vec<usize>> = Vec::new();
767         for (path, packet) in pile.descendants().paths() {
768             assert_eq!(Some(packet), pile.path_ref(&path[..]));
769             paths2.push(path);
770         }
771 
772         if paths1 != paths2 {
773             eprintln!("PacketPile:");
774             pile.pretty_print();
775 
776             eprintln!("Expected paths:");
777             for p in paths1 {
778                 eprintln!("  {:?}", p);
779             }
780 
781             eprintln!("Got paths:");
782             for p in paths2 {
783                 eprintln!("  {:?}", p);
784             }
785 
786             panic!("Something is broken.  Don't panic.");
787         }
788     }
789 }
790 
791 /// Holds a signature packet.
792 ///
793 /// Signature packets are used to hold all kinds of signatures
794 /// including certifications, and signatures over documents.  See
795 /// [Section 5.2 of RFC 4880] for details.
796 ///
797 ///   [Section 5.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.2
798 ///
799 /// When signing a document, a `Signature` packet is typically created
800 /// indirectly by the [streaming `Signer`].  Similarly, a `Signature`
801 /// packet is created as a side effect of parsing a signed message
802 /// using the [`PacketParser`].
803 ///
804 /// `Signature` packets are also used for [self signatures on Keys],
805 /// [self signatures on User IDs], [self signatures on User
806 /// Attributes], [certifications of User IDs], and [certifications of
807 /// User Attributes].  In these cases, you'll typically want to use
808 /// the [`SignatureBuilder`] to create the `Signature` packet.  See
809 /// the linked documentation for details, and examples.
810 ///
811 /// [streaming `Signer`]: ../serialize/stream/struct.Signer.html
812 /// [`PacketParser`]: ../parse/index.html
813 /// [self signatures on Keys]: enum.Key.html#method.bind
814 /// [self signatures on User IDs]: struct.UserID.html#method.bind
815 /// [self signatures on User Attributes]: user_attribute/struct.UserAttribute.html#method.bind
816 /// [certifications of User IDs]: struct.UserID.html#method.certify
817 /// [certifications of User Attributes]: user_attribute/struct.UserAttribute.html#method.certify
818 /// [`SignatureBuilder`]: signature/struct.SignatureBuilder.html
819 ///
820 /// Note: This enum cannot be exhaustively matched to allow future
821 /// extensions.
822 ///
823 /// # A note on equality
824 ///
825 /// Two `Signature` packets are considered equal if their serialized
826 /// form is equal.  Notably this includes the unhashed subpacket area
827 /// and the order of subpackets and notations.  This excludes the
828 /// computed digest and signature level, which are not serialized.
829 ///
830 /// A consequence of considering packets in the unhashed subpacket
831 /// area is that an adversary can take a valid signature and create
832 /// many distinct but valid signatures by changing the unhashed
833 /// subpacket area.  This has the potential of creating a denial of
834 /// service vector, if `Signature`s are naively deduplicated.  To
835 /// protect against this, consider using [`Signature::normalized_eq`].
836 ///
837 ///   [`Signature::normalized_eq`]: #method.normalized_eq
838 ///
839 /// # Examples
840 ///
841 /// Add a User ID to an existing certificate:
842 ///
843 /// ```
844 /// use std::time;
845 /// use sequoia_openpgp as openpgp;
846 /// use openpgp::cert::prelude::*;
847 /// use openpgp::packet::prelude::*;
848 /// use openpgp::policy::StandardPolicy;
849 ///
850 /// # fn main() -> openpgp::Result<()> {
851 /// let p = &StandardPolicy::new();
852 ///
853 /// let t1 = time::SystemTime::now();
854 /// let t2 = t1 + time::Duration::from_secs(1);
855 ///
856 /// let (cert, _) = CertBuilder::new()
857 ///     .set_creation_time(t1)
858 ///     .add_userid("Alice <alice@example.org>")
859 ///     .generate()?;
860 ///
861 /// // Add a new User ID.
862 /// let mut signer = cert
863 ///     .primary_key().key().clone().parts_into_secret()?.into_keypair()?;
864 ///
865 /// // Use the existing User ID's signature as a template.  This ensures that
866 /// // we use the same
867 /// let userid = UserID::from("Alice <alice@other.com>");
868 /// let template: signature::SignatureBuilder
869 ///     = cert.with_policy(p, t1)?.primary_userid().unwrap()
870 ///         .binding_signature().clone().into();
871 /// let sig = template.clone()
872 ///     .set_signature_creation_time(t2)?;
873 /// let sig = userid.bind(&mut signer, &cert, sig)?;
874 ///
875 /// let cert = cert.merge_packets(vec![Packet::from(userid), sig.into()])?;
876 /// # assert_eq!(cert.with_policy(p, t2)?.userids().count(), 2);
877 /// # Ok(()) }
878 /// ```
879 #[derive(PartialEq, Eq, Hash, Clone, Debug)]
880 pub enum Signature {
881     /// Signature packet version 4.
882     V4(self::signature::Signature4),
883 
884     /// This marks this enum as non-exhaustive.  Do not use this
885     /// variant.
886     #[doc(hidden)] __Nonexhaustive,
887 }
888 
889 impl Signature {
890     /// Gets the version.
version(&self) -> u8891     pub fn version(&self) -> u8 {
892         match self {
893             &Signature::V4(_) => 4,
894             Signature::__Nonexhaustive => unreachable!(),
895         }
896     }
897 }
898 
899 impl From<Signature> for Packet {
from(s: Signature) -> Self900     fn from(s: Signature) -> Self {
901         Packet::Signature(s)
902     }
903 }
904 
905 // Trivial forwarder for singleton enum.
906 impl Deref for Signature {
907     type Target = signature::Signature4;
908 
deref(&self) -> &Self::Target909     fn deref(&self) -> &Self::Target {
910         match self {
911             Signature::V4(sig) => sig,
912             Signature::__Nonexhaustive => unreachable!(),
913         }
914     }
915 }
916 
917 // Trivial forwarder for singleton enum.
918 impl DerefMut for Signature {
deref_mut(&mut self) -> &mut Self::Target919     fn deref_mut(&mut self) -> &mut Self::Target {
920         match self {
921             Signature::V4(ref mut sig) => sig,
922             Signature::__Nonexhaustive => unreachable!(),
923         }
924     }
925 }
926 
927 /// Holds a one-pass signature packet.
928 ///
929 /// See [Section 5.4 of RFC 4880] for details.
930 ///
931 /// A `OnePassSig` packet is not normally instantiated directly.  In
932 /// most cases, you'll create one as a side-effect of signing a
933 /// message using the [streaming serializer], or parsing a signed
934 /// message using the [`PacketParser`].
935 ///
936 /// Note: This enum cannot be exhaustively matched to allow future
937 /// extensions.
938 ///
939 /// [Section 5.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.4
940 /// [`PacketParser`]: ../parse/index.html
941 /// [streaming serializer]: ../serialize/stream/index.html
942 #[derive(PartialEq, Eq, Hash, Clone, Debug)]
943 pub enum OnePassSig {
944     /// OnePassSig packet version 3.
945     V3(self::one_pass_sig::OnePassSig3),
946 
947     /// This marks this enum as non-exhaustive.  Do not use this
948     /// variant.
949     #[doc(hidden)] __Nonexhaustive,
950 }
951 
952 impl OnePassSig {
953     /// Gets the version.
version(&self) -> u8954     pub fn version(&self) -> u8 {
955         match self {
956             &OnePassSig::V3(_) => 3,
957             OnePassSig::__Nonexhaustive => unreachable!(),
958         }
959     }
960 }
961 
962 impl From<OnePassSig> for Packet {
from(s: OnePassSig) -> Self963     fn from(s: OnePassSig) -> Self {
964         Packet::OnePassSig(s)
965     }
966 }
967 
968 // Trivial forwarder for singleton enum.
969 impl Deref for OnePassSig {
970     type Target = one_pass_sig::OnePassSig3;
971 
deref(&self) -> &Self::Target972     fn deref(&self) -> &Self::Target {
973         match self {
974             OnePassSig::V3(ops) => ops,
975             OnePassSig::__Nonexhaustive => unreachable!(),
976         }
977     }
978 }
979 
980 // Trivial forwarder for singleton enum.
981 impl DerefMut for OnePassSig {
deref_mut(&mut self) -> &mut Self::Target982     fn deref_mut(&mut self) -> &mut Self::Target {
983         match self {
984             OnePassSig::V3(ref mut ops) => ops,
985             OnePassSig::__Nonexhaustive => unreachable!(),
986         }
987     }
988 }
989 
990 /// Holds an asymmetrically encrypted session key.
991 ///
992 /// The session key is used to decrypt the actual ciphertext, which is
993 /// typically stored in a [SEIP] or [AED] packet.  See [Section 5.1 of
994 /// RFC 4880] for details.
995 ///
996 /// A PKESK packet is not normally instantiated directly.  In most
997 /// cases, you'll create one as a side-effect of encrypting a message
998 /// using the [streaming serializer], or parsing an encrypted message
999 /// using the [`PacketParser`].
1000 ///
1001 /// Note: This enum cannot be exhaustively matched to allow future
1002 /// extensions.
1003 ///
1004 /// [SEIP]: enum.SEIP.html
1005 /// [AED]: enum.AED.html
1006 /// [Section 5.1 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.1
1007 /// [streaming serializer]: ../serialize/stream/index.html
1008 /// [`PacketParser`]: ../parse/index.html
1009 #[derive(PartialEq, Eq, Hash, Clone, Debug)]
1010 pub enum PKESK {
1011     /// PKESK packet version 3.
1012     V3(self::pkesk::PKESK3),
1013 
1014     /// This marks this enum as non-exhaustive.  Do not use this
1015     /// variant.
1016     #[doc(hidden)] __Nonexhaustive,
1017 }
1018 
1019 impl PKESK {
1020     /// Gets the version.
version(&self) -> u81021     pub fn version(&self) -> u8 {
1022         match self {
1023             PKESK::V3(_) => 3,
1024             PKESK::__Nonexhaustive => unreachable!(),
1025         }
1026     }
1027 }
1028 
1029 impl From<PKESK> for Packet {
from(p: PKESK) -> Self1030     fn from(p: PKESK) -> Self {
1031         Packet::PKESK(p)
1032     }
1033 }
1034 
1035 // Trivial forwarder for singleton enum.
1036 impl Deref for PKESK {
1037     type Target = self::pkesk::PKESK3;
1038 
deref(&self) -> &Self::Target1039     fn deref(&self) -> &Self::Target {
1040         match self {
1041             PKESK::V3(ref p) => p,
1042             PKESK::__Nonexhaustive => unreachable!(),
1043         }
1044     }
1045 }
1046 
1047 // Trivial forwarder for singleton enum.
1048 impl DerefMut for PKESK {
deref_mut(&mut self) -> &mut Self::Target1049     fn deref_mut(&mut self) -> &mut Self::Target {
1050         match self {
1051             PKESK::V3(ref mut p) => p,
1052             PKESK::__Nonexhaustive => unreachable!(),
1053         }
1054     }
1055 }
1056 
1057 /// Holds a symmetrically encrypted session key.
1058 ///
1059 /// The session key is used to decrypt the actual ciphertext, which is
1060 /// typically stored in a [SEIP] or [AED] packet.  See [Section 5.3 of
1061 /// RFC 4880] for details.
1062 ///
1063 /// An SKESK packet is not normally instantiated directly.  In most
1064 /// cases, you'll create one as a side-effect of encrypting a message
1065 /// using the [streaming serializer], or parsing an encrypted message
1066 /// using the [`PacketParser`].
1067 ///
1068 /// Note: This enum cannot be exhaustively matched to allow future
1069 /// extensions.
1070 ///
1071 /// [SEIP]: enum.SEIP.html
1072 /// [AED]: enum.AED.html
1073 /// [Section 5.3 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.3
1074 /// [streaming serializer]: ../serialize/stream/index.html
1075 /// [`PacketParser`]: ../parse/index.html
1076 #[derive(PartialEq, Eq, Hash, Clone, Debug)]
1077 pub enum SKESK {
1078     /// SKESK packet version 4.
1079     V4(self::skesk::SKESK4),
1080     /// SKESK packet version 5.
1081     ///
1082     /// This feature is [experimental](../index.html#experimental-features).
1083     V5(self::skesk::SKESK5),
1084 
1085     /// This marks this enum as non-exhaustive.  Do not use this
1086     /// variant.
1087     #[doc(hidden)] __Nonexhaustive,
1088 }
1089 
1090 impl SKESK {
1091     /// Gets the version.
version(&self) -> u81092     pub fn version(&self) -> u8 {
1093         match self {
1094             &SKESK::V4(_) => 4,
1095             &SKESK::V5(_) => 5,
1096             SKESK::__Nonexhaustive => unreachable!(),
1097         }
1098     }
1099 }
1100 
1101 impl From<SKESK> for Packet {
from(p: SKESK) -> Self1102     fn from(p: SKESK) -> Self {
1103         Packet::SKESK(p)
1104     }
1105 }
1106 
1107 /// Holds a public key, public subkey, private key or private subkey packet.
1108 ///
1109 /// The different `Key` packets are described in [Section 5.5 of RFC 4880].
1110 ///
1111 ///   [Section 5.5 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.5
1112 ///
1113 /// Note: This enum cannot be exhaustively matched to allow future
1114 /// extensions.
1115 ///
1116 /// # Key Variants
1117 ///
1118 /// There are four different types of keys in OpenPGP: [public keys],
1119 /// [secret keys], [public subkeys], and [secret subkeys].  Although
1120 /// the semantics of each type of key are slightly different, the
1121 /// underlying representation is identical (even a public key and a
1122 /// secret key are the same: the public key variant just contains 0
1123 /// bits of secret key material).
1124 ///
1125 /// In Sequoia, we use a single type, `Key`, for all four variants.
1126 /// To improve type safety, we use marker traits rather than an `enum`
1127 /// to distinguish them.  Specifically, we `Key` is generic over two
1128 /// type variables, `P` and `R`.
1129 ///
1130 /// `P` and `R` take marker traits, which describe how any secret key
1131 /// material should be treated, and the key's role (primary or
1132 /// subordinate).  The markers also determine the `Key`'s behavior and
1133 /// the exposed functionality.  `P` can be [`key::PublicParts`],
1134 /// [`key::SecretParts`], or [`key::UnspecifiedParts`].  And, `R` can
1135 /// be [`key::PrimaryRole`], [`key::SubordinateRole`], or
1136 /// [`key::UnspecifiedRole`].
1137 ///
1138 /// If `P` is `key::PublicParts`, any secret key material that is
1139 /// present is ignored.  For instance, when serializing a key with
1140 /// this marker, any secret key material will be skipped.  This is
1141 /// illutrated in the following example.  If `P` is
1142 /// `key::SecretParts`, then the key definitely contains secret key
1143 /// material (although it is not guaranteed that the secret key
1144 /// material is valid), and methods that require secret key material
1145 /// are available.
1146 ///
1147 /// Unlike `P`, `R` does not say anything about the `Key`'s content.
1148 /// But, a key's role does influence's the key's semantics.  For
1149 /// instance, some of a primary key's meta-data is located on the
1150 /// primary User ID whereas a subordinate key's meta-data is located
1151 /// on its binding signature.
1152 ///
1153 /// The unspecified variants [`key::UnspecifiedParts`] and
1154 /// [`key::UnspecifiedRole`] exist to simplify type erasure, which is
1155 /// needed to mix different types of keys in a single collection.  For
1156 /// instance, [`Cert::keys`] returns an iterator over the keys in a
1157 /// certificate.  Since the keys have different roles (a primary key
1158 /// and zero or more subkeys), but the `Iterator` has to be over a
1159 /// single, fixed type, the returned keys use the
1160 /// `key::UnspecifiedRole` marker.
1161 ///
1162 /// [public keys]: https://tools.ietf.org/html/rfc4880#section-5.5.1.1
1163 /// [secret keys]: https://tools.ietf.org/html/rfc4880#section-5.5.1.3
1164 /// [public subkeys]: https://tools.ietf.org/html/rfc4880#section-5.5.1.2
1165 /// [secret subkeys]: https://tools.ietf.org/html/rfc4880#section-5.5.1.4
1166 /// [`key::PublicParts`]: key/struct.PublicParts.html
1167 /// [`key::SecretParts`]: key/struct.SecretParts.html
1168 /// [`key::UnspecifiedParts`]: key/struct.UnspecifiedParts.html
1169 /// [`key::PrimaryRole`]: key/struct.PrimaryRole.html
1170 /// [`key::SubordinateRole`]: key/struct.SubordinateRole.html
1171 /// [`key::UnspecifiedRole`]: key/struct.UnspecifiedRole.html
1172 /// [`Cert::keys`]: ../struct.Cert.html#method.keys
1173 ///
1174 /// ## Examples
1175 ///
1176 /// Serializing a public key with secret key material drops the secret
1177 /// key material:
1178 ///
1179 /// ```
1180 /// use sequoia_openpgp as openpgp;
1181 /// use openpgp::cert::prelude::*;
1182 /// use openpgp::packet::prelude::*;
1183 /// use sequoia_openpgp::parse::Parse;
1184 /// use openpgp::serialize::Serialize;
1185 ///
1186 /// # fn main() -> openpgp::Result<()> {
1187 /// // Generate a new certificate.  It has secret key material.
1188 /// let (cert, _) = CertBuilder::new()
1189 ///     .generate()?;
1190 ///
1191 /// let pk = cert.primary_key().key();
1192 /// assert!(pk.has_secret());
1193 ///
1194 /// // Serializing a `Key<key::PublicParts, _>` drops the secret key
1195 /// // material.
1196 /// let mut bytes = Vec::new();
1197 /// Packet::from(pk.clone()).serialize(&mut bytes);
1198 /// let p : Packet = Packet::from_bytes(&bytes)?;
1199 ///
1200 /// if let Packet::PublicKey(key) = p {
1201 ///     assert!(! key.has_secret());
1202 /// } else {
1203 ///     unreachable!();
1204 /// }
1205 /// # Ok(())
1206 /// # }
1207 /// ```
1208 ///
1209 /// # Conversions
1210 ///
1211 /// Sometimes it is necessary to change a marker.  For instance, to
1212 /// help prevent a user from inadvertently leaking secret key
1213 /// material, the [`Cert`] data structure never returns keys with the
1214 /// [`key::SecretParts`] marker.  This means, to use any secret key
1215 /// material, e.g., when creating a [`Signer`], the user needs to
1216 /// explicitly opt-in by changing the marker using
1217 /// [`Key::parts_into_secret`] or [`Key::parts_as_secret`].
1218 ///
1219 /// For `P`, the conversion functions are: [`Key::parts_into_public`],
1220 /// [`Key::parts_as_public`], [`Key::parts_into_secret`],
1221 /// [`Key::parts_as_secret`], [`Key::parts_into_unspecified`], and
1222 /// [`Key::parts_as_unspecified`].  With the exception of converting
1223 /// `P` to `key::SecretParts`, these functions are infallible.
1224 /// Converting `P` to `key::SecretParts` may fail if the key doesn't
1225 /// have any secret key material.  (Note: although the secret key
1226 /// material is required, it not checked for validity.)
1227 ///
1228 /// For `R`, the conversion functions are [`Key::role_into_primary`],
1229 /// [`Key::role_as_primary`], [`Key::role_into_subordinate`],
1230 /// [`Key::role_as_subordinate`], [`Key::role_into_unspecified`], and
1231 /// [`Key::role_as_unspecified`].
1232 ///
1233 /// It is also possible to use `From`.
1234 ///
1235 /// [`Signer`]: ../crypto/trait.Signer.html
1236 /// [`Key::parts_as_secret`]: enum.Key.html#method.parts_as_secret
1237 /// [`Key::parts_into_public`]: #method.parts_into_public
1238 /// [`Key::parts_as_public`]: #method.parts_as_public
1239 /// [`Key::parts_into_secret`]: #method.parts_into_secret
1240 /// [`Key::parts_as_secret`]: #method.parts_as_secret
1241 /// [`Key::parts_into_unspecified`]: #method.parts_into_unspecified
1242 /// [`Key::parts_as_unspecified`]: #method.parts_as_unspecified
1243 /// [`Key::role_into_primary`]: #method.role_into_primary
1244 /// [`Key::role_as_primary`]: #method.role_as_primary
1245 /// [`Key::role_into_subordinate`]: #method.role_into_subordinate
1246 /// [`Key::role_as_subordinate`]: #method.role_as_subordinate
1247 /// [`Key::role_into_unspecified`]: #method.role_into_unspecified
1248 /// [`Key::role_as_unspecified`]: #method.role_as_unspecified
1249 ///
1250 /// ## Examples
1251 ///
1252 /// Changing a marker:
1253 ///
1254 /// ```
1255 /// use sequoia_openpgp as openpgp;
1256 /// use openpgp::cert::prelude::*;
1257 /// use openpgp::packet::prelude::*;
1258 ///
1259 /// # fn main() -> openpgp::Result<()> {
1260 /// // Generate a new certificate.  It has secret key material.
1261 /// let (cert, _) = CertBuilder::new()
1262 ///     .generate()?;
1263 ///
1264 /// let pk: &Key<key::PublicParts, key::PrimaryRole>
1265 ///     = cert.primary_key().key();
1266 /// // `has_secret`s is one of the few methods that ignores the
1267 /// // parts type.
1268 /// assert!(pk.has_secret());
1269 ///
1270 /// // Treat it like a secret key.  This only works if `pk` really
1271 /// // has secret key material (which it does in this case, see above).
1272 /// let sk = pk.parts_as_secret()?;
1273 /// assert!(sk.has_secret());
1274 ///
1275 /// // And back.
1276 /// let pk = sk.parts_as_public();
1277 /// // Yes, the secret key material is still there.
1278 /// assert!(pk.has_secret());
1279 /// # Ok(())
1280 /// # }
1281 /// ```
1282 ///
1283 /// The [`Cert`] data structure only returns public keys.  To work
1284 /// with any secret key material, the `Key` first needs to be
1285 /// converted to a secret key.  This is necessary, for instance, when
1286 /// creating a [`Signer`]:
1287 ///
1288 /// [`Cert`]: ../struct.Cert.html
1289 ///
1290 /// ```rust
1291 /// use std::time;
1292 /// use sequoia_openpgp as openpgp;
1293 /// # use openpgp::Result;
1294 /// use openpgp::cert::prelude::*;
1295 /// use openpgp::crypto::KeyPair;
1296 /// use openpgp::policy::StandardPolicy;
1297 ///
1298 /// # fn main() -> Result<()> {
1299 /// let p = &StandardPolicy::new();
1300 ///
1301 /// let the_past = time::SystemTime::now() - time::Duration::from_secs(1);
1302 /// let (cert, _) = CertBuilder::new()
1303 ///     .set_creation_time(the_past)
1304 ///     .generate()?;
1305 ///
1306 /// // Set the certificate to expire now.  To do this, we need
1307 /// // to create a new self-signature, and sign it using a
1308 /// // certification-capable key.  The primary key is always
1309 /// // certification capable.
1310 /// let mut keypair = cert.primary_key()
1311 ///     .key().clone().parts_into_secret()?.into_keypair()?;
1312 /// let sigs = cert.set_expiration_time(p, None, &mut keypair,
1313 ///                                     Some(time::SystemTime::now()))?;
1314 ///
1315 /// let cert = cert.merge_packets(sigs)?;
1316 /// // It's expired now.
1317 /// assert!(cert.with_policy(p, None)?.alive().is_err());
1318 /// # Ok(())
1319 /// # }
1320 /// ```
1321 ///
1322 /// # Key Generation
1323 ///
1324 /// `Key` is a wrapper around [the different key formats].
1325 /// (Currently, Sequoia only supports version 4 keys, however, future
1326 /// versions may add limited support for version 3 keys to facilitate
1327 /// working with achieved messages, and RFC 4880bis includes [a
1328 /// proposal for a new key format].)  As such, it doesn't provide a
1329 /// mechanism to generate keys or import existing key material.
1330 /// Instead, use the format-specific functions (e.g.,
1331 /// [`Key4::generate_ecc`]) and then convert the result into a `Key`
1332 /// packet, as the following example demonstrates.
1333 ///
1334 /// [the different key formats]: https://tools.ietf.org/html/rfc4880#section-5.5.2
1335 /// [a proposal for a new key format]: https://www.ietf.org/id/draft-ietf-openpgp-rfc4880bis-09.html#section-5.5.2
1336 /// [`Key4::generate_ecc`]: key/struct.Key4.html#method.generate_ecc
1337 ///
1338 ///
1339 /// ## Examples
1340 ///
1341 /// ```
1342 /// use sequoia_openpgp as openpgp;
1343 /// use openpgp::packet::prelude::*;
1344 /// use openpgp::types::Curve;
1345 ///
1346 /// # fn main() -> openpgp::Result<()> {
1347 /// let key: Key<key::SecretParts, key::PrimaryRole>
1348 ///     = Key::from(Key4::generate_ecc(true, Curve::Ed25519)?);
1349 /// # Ok(())
1350 /// # }
1351 /// ```
1352 ///
1353 /// # Password Protection
1354 ///
1355 /// OpenPGP provides a mechanism to [password protect keys].  If a key
1356 /// is password protected, you need to decrypt the password using
1357 /// [`Key::decrypt_secret`] before using its secret key material
1358 /// (e.g., to decrypt a message, or to generate a signature).
1359 ///
1360 /// [password protect keys]: https://tools.ietf.org/html/rfc4880#section-3.7
1361 /// [`Key::decrypt_secret`]: #method.decrypt_secret
1362 ///
1363 /// # A note on equality
1364 ///
1365 /// The implementation of `Eq` for `Key` compares the serialized form
1366 /// of `Key`s.  Notably this includes the secret key material, but
1367 /// excludes the `KeyParts` and `KeyRole` marker traits.
1368 /// To exclude the secret key material from the comparison, use
1369 /// [`Key::public_cmp`] or [`Key::public_eq`].
1370 ///
1371 /// When merging in secret key material from untrusted sources, you
1372 /// need to be very careful: secret key material is not
1373 /// cryptographically protected by the key's self signature.  Thus, an
1374 /// attacker can provide a valid key with a valid self signature, but
1375 /// invalid secret key material.  If naively merged, this could
1376 /// overwrite valid secret key material, and thereby render the key
1377 /// useless.  Unfortunately, the only way to find out that the secret
1378 /// key material is bad is to actually try using it.  But, because the
1379 /// secret key material is usually encrypted, this can't always be
1380 /// done automatically.
1381 ///
1382 /// [`Key::public_cmp`]: #method.public_cmp
1383 /// [`Key::public_eq`]: #method.public_eq
1384 ///
1385 /// Compare:
1386 ///
1387 /// ```
1388 /// use sequoia_openpgp as openpgp;
1389 /// use openpgp::cert::prelude::*;
1390 /// use openpgp::packet::prelude::*;
1391 ///
1392 /// # fn main() -> openpgp::Result<()> {
1393 /// // Generate a new certificate.  It has secret key material.
1394 /// let (cert, _) = CertBuilder::new()
1395 ///     .generate()?;
1396 ///
1397 /// let sk = cert.primary_key().key();
1398 /// assert!(sk.has_secret());
1399 ///
1400 /// // Strip the secret key material.
1401 /// let cert = cert.clone().strip_secret_key_material();
1402 /// let pk = cert.primary_key().key();
1403 /// assert!(! pk.has_secret());
1404 ///
1405 /// // Eq compares both the public and the secret bits, so it
1406 /// // considers pk and sk to be different.
1407 /// assert_ne!(pk, sk);
1408 ///
1409 /// // Key::public_eq only compares the public bits, so it considers
1410 /// // them to be equal.
1411 /// assert!(Key::public_eq(pk, sk));
1412 /// # Ok(())
1413 /// # }
1414 /// ```
1415 #[derive(PartialEq, Eq, Hash, Clone, Debug)]
1416 pub enum Key<P: key::KeyParts, R: key::KeyRole> {
1417     /// A version 4 `Key` packet.
1418     V4(Key4<P, R>),
1419 
1420     /// This marks this enum as non-exhaustive.  Do not use this
1421     /// variant.
1422     #[doc(hidden)] __Nonexhaustive,
1423 }
1424 
1425 impl<P: key::KeyParts, R: key::KeyRole> fmt::Display for Key<P, R> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1426     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1427         match self {
1428             Key::V4(k) => k.fmt(f),
1429             Key::__Nonexhaustive => unreachable!(),
1430         }
1431     }
1432 }
1433 
1434 impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> {
1435     /// Gets the version.
version(&self) -> u81436     pub fn version(&self) -> u8 {
1437         match self {
1438             Key::V4(_) => 4,
1439             Key::__Nonexhaustive => unreachable!(),
1440         }
1441     }
1442 
1443     /// Compares the public bits of two keys.
1444     ///
1445     /// This returns `Ordering::Equal` if the public MPIs, version,
1446     /// creation time and algorithm of the two `Key`s match.  This
1447     /// does not consider the packet's encoding, packet's tag or the
1448     /// secret key material.
public_cmp<PB, RB>(&self, b: &Key<PB, RB>) -> std::cmp::Ordering where PB: key::KeyParts, RB: key::KeyRole,1449     pub fn public_cmp<PB, RB>(&self, b: &Key<PB, RB>) -> std::cmp::Ordering
1450         where PB: key::KeyParts,
1451               RB: key::KeyRole,
1452     {
1453         match (self, b) {
1454             (Key::V4(a), Key::V4(b)) => a.public_cmp(b),
1455             (Key::__Nonexhaustive, _) => unreachable!(),
1456             (_, Key::__Nonexhaustive) => unreachable!(),
1457         }
1458     }
1459 
1460     /// This method tests for self and other values to be equal modulo
1461     /// the secret key material.
1462     ///
1463     /// This returns true if the public MPIs, creation time and
1464     /// algorithm of the two `Key`s match.  This does not consider
1465     /// the packet's encoding, packet's tag or the secret key
1466     /// material.
public_eq<PB, RB>(&self, b: &Key<PB, RB>) -> bool where PB: key::KeyParts, RB: key::KeyRole,1467     pub fn public_eq<PB, RB>(&self, b: &Key<PB, RB>) -> bool
1468         where PB: key::KeyParts,
1469               RB: key::KeyRole,
1470     {
1471         self.public_cmp(b) == std::cmp::Ordering::Equal
1472     }
1473 }
1474 
1475 impl From<Key<key::PublicParts, key::PrimaryRole>> for Packet {
1476     /// Convert the `Key` struct to a `Packet`.
from(k: Key<key::PublicParts, key::PrimaryRole>) -> Self1477     fn from(k: Key<key::PublicParts, key::PrimaryRole>) -> Self {
1478         Packet::PublicKey(k.into())
1479     }
1480 }
1481 
1482 impl From<Key<key::PublicParts, key::SubordinateRole>> for Packet {
1483     /// Convert the `Key` struct to a `Packet`.
from(k: Key<key::PublicParts, key::SubordinateRole>) -> Self1484     fn from(k: Key<key::PublicParts, key::SubordinateRole>) -> Self {
1485         Packet::PublicSubkey(k.into())
1486     }
1487 }
1488 
1489 impl From<Key<key::SecretParts, key::PrimaryRole>> for Packet {
1490     /// Convert the `Key` struct to a `Packet`.
from(k: Key<key::SecretParts, key::PrimaryRole>) -> Self1491     fn from(k: Key<key::SecretParts, key::PrimaryRole>) -> Self {
1492         Packet::SecretKey(k.into())
1493     }
1494 }
1495 
1496 impl From<Key<key::SecretParts, key::SubordinateRole>> for Packet {
1497     /// Convert the `Key` struct to a `Packet`.
from(k: Key<key::SecretParts, key::SubordinateRole>) -> Self1498     fn from(k: Key<key::SecretParts, key::SubordinateRole>) -> Self {
1499         Packet::SecretSubkey(k.into())
1500     }
1501 }
1502 
1503 impl<R: key::KeyRole> Key<key::SecretParts, R> {
1504     /// Creates a new key pair from a `Key` with an unencrypted
1505     /// secret key.
1506     ///
1507     /// If the `Key` is password protected, you first need to decrypt
1508     /// it using [`Key::decrypt_secret`].
1509     ///
1510     /// [`Key::decrypt_secret`]: #method.decrypt_secret
1511     ///
1512     /// # Errors
1513     ///
1514     /// Fails if the secret key is encrypted.
1515     ///
1516     /// # Examples
1517     ///
1518     /// Revoke a certificate by signing a new revocation certificate:
1519     ///
1520     /// ```rust
1521     /// use std::time;
1522     /// use sequoia_openpgp as openpgp;
1523     /// # use openpgp::Result;
1524     /// use openpgp::cert::prelude::*;
1525     /// use openpgp::crypto::KeyPair;
1526     /// use openpgp::types::ReasonForRevocation;
1527     ///
1528     /// # fn main() -> Result<()> {
1529     /// // Generate a certificate.
1530     /// let (cert, _) =
1531     ///     CertBuilder::general_purpose(None,
1532     ///                                  Some("Alice Lovelace <alice@example.org>"))
1533     ///         .generate()?;
1534     ///
1535     /// // Use the secret key material to sign a revocation certificate.
1536     /// let mut keypair = cert.primary_key()
1537     ///     .key().clone().parts_into_secret()?
1538     ///     .into_keypair()?;
1539     /// let rev = cert.revoke(&mut keypair,
1540     ///                       ReasonForRevocation::KeyCompromised,
1541     ///                       b"It was the maid :/")?;
1542     /// # Ok(())
1543     /// # }
1544     /// ```
into_keypair(self) -> Result<KeyPair>1545     pub fn into_keypair(self) -> Result<KeyPair> {
1546         match self {
1547             Key::V4(k) => k.into_keypair(),
1548             // Match exhaustively so that when we add support for a
1549             // new variant, the compiler reminds us to add support for
1550             // it here.
1551             Key::__Nonexhaustive => unreachable!(),
1552         }
1553     }
1554 
1555     /// Decrypts the secret key material.
1556     ///
1557     /// In OpenPGP, secret key material can be [protected with a
1558     /// password].  The password is usually hardened using a [KDF].
1559     ///
1560     /// [protected with a password]: https://tools.ietf.org/html/rfc4880#section-5.5.3
1561     /// [KDF]: https://tools.ietf.org/html/rfc4880#section-3.7
1562     ///
1563     /// This function takes ownership of the `Key`, decrypts the
1564     /// secret key material using the password, and returns a new key
1565     /// whose secret key material is not password protected.
1566     ///
1567     /// If the secret key material is not password protected or if the
1568     /// password is wrong, this function returns an error.
1569     ///
1570     /// # Examples
1571     ///
1572     /// Sign a new revocation certificate using a password-protected
1573     /// key:
1574     ///
1575     /// ```rust
1576     /// use sequoia_openpgp as openpgp;
1577     /// # use openpgp::Result;
1578     /// use openpgp::cert::prelude::*;
1579     /// use openpgp::types::ReasonForRevocation;
1580     ///
1581     /// # fn main() -> Result<()> {
1582     /// // Generate a certificate whose secret key material is
1583     /// // password protected.
1584     /// let (cert, _) =
1585     ///     CertBuilder::general_purpose(None,
1586     ///                                  Some("Alice Lovelace <alice@example.org>"))
1587     ///         .set_password(Some("1234".into()))
1588     ///         .generate()?;
1589     ///
1590     /// // Use the secret key material to sign a revocation certificate.
1591     /// let key = cert.primary_key().key().clone().parts_into_secret()?;
1592     ///
1593     /// // We can't turn it into a keypair without decrypting it.
1594     /// assert!(key.clone().into_keypair().is_err());
1595     ///
1596     /// // And, we need to use the right password.
1597     /// assert!(key.clone()
1598     ///     .decrypt_secret(&"correct horse battery staple".into())
1599     ///     .is_err());
1600     ///
1601     /// // Let's do it right:
1602     /// let mut keypair = key.decrypt_secret(&"1234".into())?.into_keypair()?;
1603     /// let rev = cert.revoke(&mut keypair,
1604     ///                       ReasonForRevocation::KeyCompromised,
1605     ///                       b"It was the maid :/")?;
1606     /// # Ok(())
1607     /// # }
1608     /// ```
decrypt_secret(self, password: &Password) -> Result<Self>1609     pub fn decrypt_secret(self, password: &Password) -> Result<Self>
1610     {
1611         match self {
1612             Key::V4(k) => Ok(Key::V4(k.decrypt_secret(password)?)),
1613             // Match exhaustively so that when we add support for a
1614             // new variant, the compiler reminds us to add support for
1615             // it here.
1616             Key::__Nonexhaustive => unreachable!(),
1617         }
1618     }
1619 
1620     /// Encrypts the secret key material.
1621     ///
1622     /// In OpenPGP, secret key material can be [protected with a
1623     /// password].  The password is usually hardened using a [KDF].
1624     ///
1625     /// [protected with a password]: https://tools.ietf.org/html/rfc4880#section-5.5.3
1626     /// [KDF]: https://tools.ietf.org/html/rfc4880#section-3.7
1627     ///
1628     /// This function takes ownership of the `Key`, encrypts the
1629     /// secret key material using the password, and returns a new key
1630     /// whose secret key material is protected with the password.
1631     ///
1632     /// If the secret key material is already password protected, this
1633     /// function returns an error.
1634     ///
1635     /// # Examples
1636     ///
1637     /// Encrypt the primary key:
1638     ///
1639     /// ```rust
1640     /// use sequoia_openpgp as openpgp;
1641     /// # use openpgp::Result;
1642     /// use openpgp::cert::prelude::*;
1643     /// use openpgp::packet::Packet;
1644     ///
1645     /// # fn main() -> Result<()> {
1646     /// // Generate a certificate whose secret key material is
1647     /// // not password protected.
1648     /// let (cert, _) =
1649     ///     CertBuilder::general_purpose(None,
1650     ///                                  Some("Alice Lovelace <alice@example.org>"))
1651     ///         .generate()?;
1652     /// let key = cert.primary_key().key().clone().parts_into_secret()?;
1653     /// assert!(key.has_unencrypted_secret());
1654     ///
1655     /// // Encrypt the key's secret key material.
1656     /// let key = key.encrypt_secret(&"1234".into())?;
1657     /// assert!(! key.has_unencrypted_secret());
1658     ///
1659     /// // Merge it into the certificate.  Note: `Cert::merge_packets`
1660     /// // prefers added versions of keys.  So, the encrypted version
1661     /// // will override the decrypted version.
1662     /// let cert = cert.merge_packets(Packet::from(key))?;
1663     ///
1664     /// // Now the primary key's secret key material is encrypted.
1665     /// let key = cert.primary_key().key().parts_as_secret()?;
1666     /// assert!(! key.has_unencrypted_secret());
1667     ///
1668     /// // We can't turn it into a keypair without decrypting it.
1669     /// assert!(key.clone().into_keypair().is_err());
1670     ///
1671     /// // And, we need to use the right password.
1672     /// assert!(key.clone()
1673     ///     .decrypt_secret(&"correct horse battery staple".into())
1674     ///     .is_err());
1675     ///
1676     /// // Let's do it right:
1677     /// let mut keypair = key.clone()
1678     ///     .decrypt_secret(&"1234".into())?.into_keypair()?;
1679     /// # Ok(())
1680     /// # }
1681     /// ```
encrypt_secret(self, password: &Password) -> Result<Self>1682     pub fn encrypt_secret(self, password: &Password) -> Result<Self>
1683     {
1684         match self {
1685             Key::V4(k) => Ok(Key::V4(k.encrypt_secret(password)?)),
1686             // Match exhaustively so that when we add support for a
1687             // new variant, the compiler reminds us to add support for
1688             // it here.
1689             Key::__Nonexhaustive => unreachable!(),
1690         }
1691     }
1692 }
1693 
1694 impl<R: key::KeyRole> Key4<key::SecretParts, R> {
1695     /// Creates a new key pair from a secret `Key` with an unencrypted
1696     /// secret key.
1697     ///
1698     /// # Errors
1699     ///
1700     /// Fails if the secret key is encrypted.  You can use
1701     /// [`Key::decrypt_secret`] to decrypt a key.
1702     ///
1703     /// [`Key::decrypt_secret`]: ../enum.Key.html#method.decrypt_secret
into_keypair(self) -> Result<KeyPair>1704     pub fn into_keypair(self) -> Result<KeyPair> {
1705         let (key, secret) = self.take_secret();
1706         let secret = match secret {
1707             SecretKeyMaterial::Unencrypted(secret) => secret,
1708             SecretKeyMaterial::Encrypted(_) =>
1709                 return Err(Error::InvalidArgument(
1710                     "secret key material is encrypted".into()).into()),
1711         };
1712 
1713         KeyPair::new(key.role_into_unspecified().into(), secret)
1714     }
1715 }
1716 
1717 macro_rules! impl_common_secret_functions {
1718     ($t: path) => {
1719         /// Secret key handling.
1720         impl<R: key::KeyRole> Key<$t, R> {
1721             /// Takes the key packet's `SecretKeyMaterial`, if any.
1722             pub fn take_secret(self)
1723                                -> (Key<key::PublicParts, R>,
1724                                    Option<key::SecretKeyMaterial>)
1725             {
1726                 match self {
1727                     Key::V4(k) => {
1728                         let (k, s) = k.take_secret();
1729                         (k.into(), s)
1730                     },
1731                     Key::__Nonexhaustive => unreachable!(),
1732                 }
1733             }
1734 
1735             /// Adds `SecretKeyMaterial` to the packet, returning the old if
1736             /// any.
1737             pub fn add_secret(self, secret: key::SecretKeyMaterial)
1738                               -> (Key<key::SecretParts, R>,
1739                                   Option<key::SecretKeyMaterial>)
1740             {
1741                 match self {
1742                     Key::V4(k) => {
1743                         let (k, s) = k.add_secret(secret);
1744                         (k.into(), s)
1745                     },
1746                     Key::__Nonexhaustive => unreachable!(),
1747                 }
1748             }
1749         }
1750     }
1751 }
1752 impl_common_secret_functions!(key::PublicParts);
1753 impl_common_secret_functions!(key::UnspecifiedParts);
1754 
1755 /// Secret key handling.
1756 impl<R: key::KeyRole> Key<key::SecretParts, R> {
1757     /// Takes the key packet's `SecretKeyMaterial`.
take_secret(self) -> (Key<key::PublicParts, R>, key::SecretKeyMaterial)1758     pub fn take_secret(self)
1759                        -> (Key<key::PublicParts, R>, key::SecretKeyMaterial)
1760     {
1761         match self {
1762             Key::V4(k) => {
1763                 let (k, s) = k.take_secret();
1764                 (k.into(), s)
1765             },
1766             Key::__Nonexhaustive => unreachable!(),
1767         }
1768     }
1769 
1770     /// Adds `SecretKeyMaterial` to the packet, returning the old.
add_secret(self, secret: key::SecretKeyMaterial) -> (Key<key::SecretParts, R>, key::SecretKeyMaterial)1771     pub fn add_secret(self, secret: key::SecretKeyMaterial)
1772                       -> (Key<key::SecretParts, R>, key::SecretKeyMaterial)
1773     {
1774         match self {
1775             Key::V4(k) => {
1776                 let (k, s) = k.add_secret(secret);
1777                 (k.into(), s)
1778             },
1779             Key::__Nonexhaustive => unreachable!(),
1780         }
1781     }
1782 }
1783 
1784 
1785 // Trivial forwarder for singleton enum.
1786 impl<P: key::KeyParts, R: key::KeyRole> Deref for Key<P, R> {
1787     type Target = Key4<P, R>;
1788 
deref(&self) -> &Self::Target1789     fn deref(&self) -> &Self::Target {
1790         match self {
1791             Key::V4(ref p) => p,
1792             Key::__Nonexhaustive => unreachable!(),
1793         }
1794     }
1795 }
1796 
1797 // Trivial forwarder for singleton enum.
1798 impl<P: key::KeyParts, R: key::KeyRole> DerefMut for Key<P, R> {
deref_mut(&mut self) -> &mut Self::Target1799     fn deref_mut(&mut self) -> &mut Self::Target {
1800         match self {
1801             Key::V4(ref mut p) => p,
1802             Key::__Nonexhaustive => unreachable!(),
1803         }
1804     }
1805 }
1806 
1807 /// Holds a SEIP packet.
1808 ///
1809 /// A SEIP packet holds encrypted data.  The data contains additional
1810 /// OpenPGP packets.  See [Section 5.13 of RFC 4880] for details.
1811 ///
1812 /// A SEIP packet is not normally instantiated directly.  In most
1813 /// cases, you'll create one as a side-effect of encrypting a message
1814 /// using the [streaming serializer], or parsing an encrypted message
1815 /// using the [`PacketParser`].
1816 ///
1817 /// [Section 5.13 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.13
1818 /// [streaming serializer]: ../serialize/stream/index.html
1819 /// [`PacketParser`]: ../parse/index.html
1820 #[derive(PartialEq, Eq, Hash, Clone, Debug)]
1821 pub enum SEIP {
1822     /// SEIP packet version 1.
1823     V1(self::seip::SEIP1),
1824 }
1825 
1826 impl SEIP {
1827     /// Gets the version.
version(&self) -> u81828     pub fn version(&self) -> u8 {
1829         match self {
1830             SEIP::V1(_) => 1,
1831         }
1832     }
1833 }
1834 
1835 impl From<SEIP> for Packet {
from(p: SEIP) -> Self1836     fn from(p: SEIP) -> Self {
1837         Packet::SEIP(p)
1838     }
1839 }
1840 
1841 // Trivial forwarder for singleton enum.
1842 impl Deref for SEIP {
1843     type Target = self::seip::SEIP1;
1844 
deref(&self) -> &Self::Target1845     fn deref(&self) -> &Self::Target {
1846         match self {
1847             SEIP::V1(ref p) => p,
1848         }
1849     }
1850 }
1851 
1852 // Trivial forwarder for singleton enum.
1853 impl DerefMut for SEIP {
deref_mut(&mut self) -> &mut Self::Target1854     fn deref_mut(&mut self) -> &mut Self::Target {
1855         match self {
1856             SEIP::V1(ref mut p) => p,
1857         }
1858     }
1859 }
1860 
1861 /// Holds an AEAD encrypted data packet.
1862 ///
1863 /// An AEAD packet holds encrypted data.  It is contains additional
1864 /// OpenPGP packets.  See [Section 5.16 of RFC 4880bis] for details.
1865 ///
1866 /// [Section 5.16 of RFC 4880bis]: https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-05#section-5.16
1867 ///
1868 /// Note: This enum cannot be exhaustively matched to allow future
1869 /// extensions.
1870 ///
1871 /// An AEAD packet is not normally instantiated directly.  In most
1872 /// cases, you'll create one as a side-effect of encrypting a message
1873 /// using the [streaming serializer], or parsing an encrypted message
1874 /// using the [`PacketParser`].
1875 ///
1876 /// [streaming serializer]: ../serialize/stream/index.html
1877 /// [`PacketParser`]: ../parse/index.html
1878 ///
1879 /// This feature is [experimental](../index.html#experimental-features).
1880 #[derive(PartialEq, Eq, Hash, Clone, Debug)]
1881 pub enum AED {
1882     /// AED packet version 1.
1883     V1(self::aed::AED1),
1884 
1885     /// This marks this enum as non-exhaustive.  Do not use this
1886     /// variant.
1887     #[doc(hidden)] __Nonexhaustive,
1888 }
1889 
1890 impl AED {
1891     /// Gets the version.
version(&self) -> u81892     pub fn version(&self) -> u8 {
1893         match self {
1894             AED::V1(_) => 1,
1895             AED::__Nonexhaustive => unreachable!(),
1896         }
1897     }
1898 }
1899 
1900 impl From<AED> for Packet {
from(p: AED) -> Self1901     fn from(p: AED) -> Self {
1902         Packet::AED(p)
1903     }
1904 }
1905 
1906 // Trivial forwarder for singleton enum.
1907 impl Deref for AED {
1908     type Target = self::aed::AED1;
1909 
deref(&self) -> &Self::Target1910     fn deref(&self) -> &Self::Target {
1911         match self {
1912             AED::V1(ref p) => p,
1913             AED::__Nonexhaustive => unreachable!(),
1914         }
1915     }
1916 }
1917 
1918 // Trivial forwarder for singleton enum.
1919 impl DerefMut for AED {
deref_mut(&mut self) -> &mut Self::Target1920     fn deref_mut(&mut self) -> &mut Self::Target {
1921         match self {
1922             AED::V1(ref mut p) => p,
1923             AED::__Nonexhaustive => unreachable!(),
1924         }
1925     }
1926 }
1927 
1928 #[cfg(test)]
1929 mod test {
1930     use super::*;
1931     use crate::serialize::SerializeInto;
1932     use crate::parse::Parse;
1933 
1934     #[test]
packet_is_send_and_sync()1935     fn packet_is_send_and_sync() {
1936         fn f<T: Send + Sync>(_: T) {}
1937         f(Packet::Marker(Default::default()));
1938     }
1939 
1940     quickcheck! {
1941         fn roundtrip(p: Packet) -> bool {
1942             let buf = p.to_vec().expect("Failed to serialize packet");
1943             let q = Packet::from_bytes(&buf).unwrap();
1944             assert_eq!(p, q);
1945             true
1946         }
1947     }
1948 
1949     quickcheck! {
1950         /// Given a packet and a position, induces a bit flip in the
1951         /// serialized form, then checks that PartialEq detects that.
1952         /// Recall that for packets, PartialEq is defined using the
1953         /// serialized form.
1954         fn mutate_eq_discriminates(p: Packet, i: usize) -> bool {
1955             if p.tag() == Tag::CompressedData {
1956                 // Mutating compressed data streams is not that
1957                 // trivial, because there are bits we can flip without
1958                 // changing the decompressed data.
1959                 return true;
1960             }
1961 
1962             let mut buf = p.to_vec().unwrap();
1963             let bit =
1964                 // Avoid first two bytes so that we don't change the
1965                 // type and reduce the chance of changing the length.
1966                 i.saturating_add(16)
1967                 % (buf.len() * 8);
1968             buf[bit / 8] ^= 1 << (bit % 8);
1969             match Packet::from_bytes(&buf) {
1970                 Ok(q) => p != q,
1971                 Err(_) => true, // Packet failed to parse.
1972             }
1973         }
1974     }
1975 }
1976