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