1 //! Key-related functionality.
2 //!
3 //! # Data Types
4 //!
5 //! The main data type is the [`Key`] enum.  This enum abstracts away
6 //! the differences between the key formats (the deprecated [version
7 //! 3], the current [version 4], and the proposed [version 5]
8 //! formats).  Nevertheless, some functionality remains format
9 //! specific.  For instance, the `Key` enum doesn't provide a
10 //! mechanism to generate keys.  This functionality depends on the
11 //! format.
12 //!
13 //! This version of Sequoia only supports version 4 keys ([`Key4`]).
14 //! However, future versions may include limited support for version 3
15 //! keys to allow working with archived messages, and we intend to add
16 //! support for version 5 keys once the new version of the
17 //! specification has been finalized.
18 //!
19 //! OpenPGP specifies four different types of keys: [public keys],
20 //! [secret keys], [public subkeys], and [secret subkeys].  These are
21 //! all represented by the `Key` enum and the `Key4` struct using
22 //! marker types.  We use marker types rather than an enum, to better
23 //! exploit the type checking.  For instance, type-specific methods
24 //! like [`Key::secret`] are only exposed for those types that
25 //! actually support them.  See the documentation for [`Key`] for an
26 //! explanation of how the markers work.
27 //!
28 //! The [`SecretKeyMaterial`] data type allows working with secret key
29 //! material directly.  This enum has two variants: [`Unencrypted`],
30 //! and [`Encrypted`].  It is not normally necessary to use this data
31 //! structure directly.  The primary functionality that is of interest
32 //! to most users is decrypting secret key material.  This is usually
33 //! more conveniently done using [`Key::decrypt_secret`].
34 //!
35 //! [`Key`]: ../enum.Key.html
36 //! [`Key4`]: struct.Key4.html
37 //! [version 3]: https://tools.ietf.org/html/rfc1991#section-6.6
38 //! [version 4]: https://tools.ietf.org/html/rfc4880#section-5.5.2
39 //! [version 5]: https://www.ietf.org/id/draft-ietf-openpgp-rfc4880bis-09.html#name-public-key-packet-formats
40 //! [public keys]: https://tools.ietf.org/html/rfc4880#section-5.5.1.1
41 //! [secret keys]: https://tools.ietf.org/html/rfc4880#section-5.5.1.3
42 //! [public subkeys]: https://tools.ietf.org/html/rfc4880#section-5.5.1.2
43 //! [secret subkeys]: https://tools.ietf.org/html/rfc4880#section-5.5.1.4
44 //! [`Key::secret`]: ../enum.Key.html#method.secret
45 //! [`SecretKeyMaterial`]: enum.SecretKeyMaterial.html
46 //! [`Unencrypted`]: struct.Unencrypted.html
47 //! [`Encrypted`]: struct.Encrypted.html
48 //! [`Key::decrypt_secret`]: ../enum.Key.html#method.decrypt_secret
49 //!
50 //! # Key Creation
51 //!
52 //! Use [`Key4::generate_rsa`] or [`Key4::generate_ecc`] to create a
53 //! new key.
54 //!
55 //! Existing key material can be turned into an OpenPGP key using
56 //! [`Key4::import_public_cv25519`], [`Key4::import_public_ed25519`],
57 //! [`Key4::import_public_rsa`], [`Key4::import_secret_cv25519`],
58 //! [`Key4::import_secret_ed25519`], and [`Key4::import_secret_rsa`].
59 //!
60 //! Whether you create a new key or import existing key material, you
61 //! still need to create a binding signature, and, for signing keys, a
62 //! back signature for the key to be usable.
63 //!
64 //! [`Key4::generate_rsa`]: struct.Key4.html#method.generate_rsa
65 //! [`Key4::generate_ecc`]: struct.Key4.html#method.generate_ecc
66 //! [`Key4::import_public_cv25519`]: struct.Key4.html#method.import_public_cv25519
67 //! [`Key4::import_public_ed25519`]: struct.Key4.html#method.import_public_ed25519
68 //! [`Key4::import_public_rsa`]: struct.Key4.html#method.import_public_rsa
69 //! [`Key4::import_secret_cv25519`]: struct.Key4.html#method.import_secret_cv25519
70 //! [`Key4::import_secret_ed25519`]: struct.Key4.html#method.import_secret_ed25519
71 //! [`Key4::import_secret_rsa`]: struct.Key4.html#method.import_secret_rsa
72 //!
73 //! # In-Memory Protection of Secret Key Material
74 //!
75 //! Whether the secret key material is protected on disk or not,
76 //! Sequoia encrypts unencrypted secret key material ([`Unencrypted`])
77 //! while it is memory.  This helps protect against [heartbleed]-style
78 //! attacks where a buffer over-read allows an attacker to read from
79 //! the process's address space.  This protection is less important
80 //! for Rust programs, which are memory safe.  However, it is
81 //! essential when Sequoia is used via its FFI.
82 //!
83 //! See [`crypto::mem::Encrypted`] for details.
84 //!
85 //! [`Unencrypted`]: struct.Unencrypted.html
86 //! [heartbleed]: https://en.wikipedia.org/wiki/Heartbleed
87 //! [`crypto::mem::Encrypted`]: ../../crypto/mem/struct.Encrypted.html
88 
89 use std::fmt;
90 use std::cmp::Ordering;
91 use std::convert::TryInto;
92 use std::time;
93 
94 #[cfg(any(test, feature = "quickcheck"))]
95 use quickcheck::{Arbitrary, Gen};
96 
97 use crate::Error;
98 use crate::cert::prelude::*;
99 use crate::crypto::{self, mem, mpi, hash::Hash};
100 use crate::packet;
101 use crate::packet::prelude::*;
102 use crate::PublicKeyAlgorithm;
103 use crate::SymmetricAlgorithm;
104 use crate::HashAlgorithm;
105 use crate::types::{Curve, Timestamp};
106 use crate::crypto::S2K;
107 use crate::Result;
108 use crate::crypto::Password;
109 use crate::KeyID;
110 use crate::Fingerprint;
111 use crate::KeyHandle;
112 
113 mod conversions;
114 
115 /// A marker trait that captures whether a `Key` definitely contains
116 /// secret key material.
117 ///
118 /// A [`Key`] can be treated as if it only has public key material
119 /// ([`key::PublicParts`]) or also has secret key material
120 /// ([`key::SecretParts`]).  For those cases where the type
121 /// information needs to be erased (e.g., interfaces like
122 /// [`Cert::keys`]), we provide the [`key::UnspecifiedParts`] marker.
123 ///
124 /// Even if a `Key` does not have the `SecretKey` marker, it may still
125 /// have secret key material.  But, it will generally act as if it
126 /// didn't.  In particular, when serializing a `Key` without the
127 /// `SecretKey` marker, secret key material will be ignored.  See the
128 /// documentation for [`Key`] for a demonstration of this behavior.
129 ///
130 /// [`Cert::keys`]: ../../cert/struct.Cert.html#method.keys
131 /// [`Key`]: ../enum.Key.html
132 /// [`key::PublicParts`]: struct.PublicParts.html
133 /// [`key::SecretParts`]: struct.SecretParts.html
134 /// [`key::UnspecifiedParts`]: struct.UnspecifiedParts.html
135 pub trait KeyParts: fmt::Debug {
136     /// Converts a key with unspecified parts into this kind of key.
137     ///
138     /// This function is helpful when you need to convert a concrete
139     /// type into a generic type.  Using `From` works, but requires
140     /// adding a type bound to the generic type, which is ugly and
141     /// invasive.
142     ///
143     /// Converting a key with [`key::PublicParts`] or
144     /// [`key::UnspecifiedParts`] will always succeed.  However,
145     /// converting a key to one with [`key::SecretParts`] only
146     /// succeeds if the key actually contains secret key material.
147     ///
148     /// [`key::PublicParts`]: struct.PublicParts.html
149     /// [`key::UnspecifiedParts`]: struct.UnspecifiedParts.html
150     /// [`key::SecretParts`]: struct.SecretParts.html
151     ///
152     /// # Examples
153     ///
154     /// For a less construed example, refer to the [source code]:
155     ///
156     /// [source code]: https://gitlab.com/search?search=convert_key&project_id=4469613&search_code=true&repository_ref=master
157     ///
158     /// ```
159     /// use sequoia_openpgp as openpgp;
160     /// use openpgp::Result;
161     /// # use openpgp::cert::prelude::*;
162     /// use openpgp::packet::prelude::*;
163     ///
164     /// fn f<P>(cert: &Cert, mut key: Key<P, key::UnspecifiedRole>)
165     ///     -> Result<Key<P, key::UnspecifiedRole>>
166     ///     where P: key::KeyParts
167     /// {
168     ///     // ...
169     ///
170     /// # let criterium = true;
171     ///     if criterium {
172     ///         // Cert::primary_key's return type is concrete
173     ///         // (Key<key::PublicParts, key::PrimaryRole>).  We need to
174     ///         // convert it to the generic type Key<P, key::UnspecifiedRole>.
175     ///         // First, we "downcast" it to have unspecified parts and an
176     ///         // unspecified role, then we use a method defined by the
177     ///         // generic type to perform the conversion to the generic
178     ///         // type P.
179     ///         key = P::convert_key(
180     ///             cert.primary_key().key().clone()
181     ///                 .parts_into_unspecified()
182     ///                 .role_into_unspecified())?;
183     ///     }
184     /// #   else { unreachable!() }
185     ///
186     ///     // ...
187     ///
188     ///     Ok(key)
189     /// }
190     /// # fn main() -> openpgp::Result<()> {
191     /// # let (cert, _) =
192     /// #     CertBuilder::general_purpose(None, Some("alice@example.org"))
193     /// #     .generate()?;
194     /// # f(&cert, cert.primary_key().key().clone().role_into_unspecified()).unwrap();
195     /// # Ok(())
196     /// # }
197     /// ```
convert_key<R: KeyRole>(key: Key<UnspecifiedParts, R>) -> Result<Key<Self, R>> where Self: Sized198     fn convert_key<R: KeyRole>(key: Key<UnspecifiedParts, R>)
199                                -> Result<Key<Self, R>>
200         where Self: Sized;
201 
202     /// Converts a key reference with unspecified parts into this kind
203     /// of key reference.
204     ///
205     /// This function is helpful when you need to convert a concrete
206     /// type into a generic type.  Using `From` works, but requires
207     /// adding a type bound to the generic type, which is ugly and
208     /// invasive.
209     ///
210     /// Converting a key with [`key::PublicParts`] or
211     /// [`key::UnspecifiedParts`] will always succeed.  However,
212     /// converting a key to one with [`key::SecretParts`] only
213     /// succeeds if the key actually contains secret key material.
214     ///
215     /// [`key::PublicParts`]: struct.PublicParts.html
216     /// [`key::UnspecifiedParts`]: struct.UnspecifiedParts.html
217     /// [`key::SecretParts`]: struct.SecretParts.html
convert_key_ref<R: KeyRole>(key: &Key<UnspecifiedParts, R>) -> Result<&Key<Self, R>> where Self: Sized218     fn convert_key_ref<R: KeyRole>(key: &Key<UnspecifiedParts, R>)
219                                    -> Result<&Key<Self, R>>
220         where Self: Sized;
221 
222     /// Converts a key bundle with unspecified parts into this kind of
223     /// key bundle.
224     ///
225     /// This function is helpful when you need to convert a concrete
226     /// type into a generic type.  Using `From` works, but requires
227     /// adding a type bound to the generic type, which is ugly and
228     /// invasive.
229     ///
230     /// Converting a key bundle with [`key::PublicParts`] or
231     /// [`key::UnspecifiedParts`] will always succeed.  However,
232     /// converting a key bundle to one with [`key::SecretParts`] only
233     /// succeeds if the key bundle actually contains secret key
234     /// material.
235     ///
236     /// [`key::PublicParts`]: struct.PublicParts.html
237     /// [`key::UnspecifiedParts`]: struct.UnspecifiedParts.html
238     /// [`key::SecretParts`]: struct.SecretParts.html
convert_bundle<R: KeyRole>(bundle: KeyBundle<UnspecifiedParts, R>) -> Result<KeyBundle<Self, R>> where Self: Sized239     fn convert_bundle<R: KeyRole>(bundle: KeyBundle<UnspecifiedParts, R>)
240                                   -> Result<KeyBundle<Self, R>>
241         where Self: Sized;
242 
243     /// Converts a key bundle reference with unspecified parts into
244     /// this kind of key bundle reference.
245     ///
246     /// This function is helpful when you need to convert a concrete
247     /// type into a generic type.  Using `From` works, but requires
248     /// adding a type bound to the generic type, which is ugly and
249     /// invasive.
250     ///
251     /// Converting a key bundle with [`key::PublicParts`] or
252     /// [`key::UnspecifiedParts`] will always succeed.  However,
253     /// converting a key bundle to one with [`key::SecretParts`] only
254     /// succeeds if the key bundle actually contains secret key
255     /// material.
256     ///
257     /// [`key::PublicParts`]: struct.PublicParts.html
258     /// [`key::UnspecifiedParts`]: struct.UnspecifiedParts.html
259     /// [`key::SecretParts`]: struct.SecretParts.html
convert_bundle_ref<R: KeyRole>(bundle: &KeyBundle<UnspecifiedParts, R>) -> Result<&KeyBundle<Self, R>> where Self: Sized260     fn convert_bundle_ref<R: KeyRole>(bundle: &KeyBundle<UnspecifiedParts, R>)
261                                       -> Result<&KeyBundle<Self, R>>
262         where Self: Sized;
263 
264     /// Converts a key amalgamation with unspecified parts into this
265     /// kind of key amalgamation.
266     ///
267     /// This function is helpful when you need to convert a concrete
268     /// type into a generic type.  Using `From` works, but requires
269     /// adding a type bound to the generic type, which is ugly and
270     /// invasive.
271     ///
272     /// Converting a key amalgamation with [`key::PublicParts`] or
273     /// [`key::UnspecifiedParts`] will always succeed.  However,
274     /// converting a key amalgamation to one with [`key::SecretParts`]
275     /// only succeeds if the key amalgamation actually contains secret
276     /// key material.
277     ///
278     /// [`key::PublicParts`]: struct.PublicParts.html
279     /// [`key::UnspecifiedParts`]: struct.UnspecifiedParts.html
280     /// [`key::SecretParts`]: struct.SecretParts.html
convert_key_amalgamation<'a, R: KeyRole>( ka: ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>) -> Result<ComponentAmalgamation<'a, Key<Self, R>>> where Self: Sized281     fn convert_key_amalgamation<'a, R: KeyRole>(
282         ka: ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>)
283         -> Result<ComponentAmalgamation<'a, Key<Self, R>>>
284         where Self: Sized;
285 
286     /// Converts a key amalgamation reference with unspecified parts
287     /// into this kind of key amalgamation reference.
288     ///
289     /// This function is helpful when you need to convert a concrete
290     /// type into a generic type.  Using `From` works, but requires
291     /// adding a type bound to the generic type, which is ugly and
292     /// invasive.
293     ///
294     /// Converting a key amalgamation with [`key::PublicParts`] or
295     /// [`key::UnspecifiedParts`] will always succeed.  However,
296     /// converting a key amalgamation to one with [`key::SecretParts`]
297     /// only succeeds if the key amalgamation actually contains secret
298     /// key material.
299     ///
300     /// [`key::PublicParts`]: struct.PublicParts.html
301     /// [`key::UnspecifiedParts`]: struct.UnspecifiedParts.html
302     /// [`key::SecretParts`]: struct.SecretParts.html
convert_key_amalgamation_ref<'a, R: KeyRole>( ka: &'a ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>) -> Result<&'a ComponentAmalgamation<'a, Key<Self, R>>> where Self: Sized303     fn convert_key_amalgamation_ref<'a, R: KeyRole>(
304         ka: &'a ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>)
305         -> Result<&'a ComponentAmalgamation<'a, Key<Self, R>>>
306         where Self: Sized;
307 }
308 
309 /// A marker trait that captures a `Key`'s role.
310 ///
311 /// A [`Key`] can either be a primary key ([`key::PrimaryRole`]) or a
312 /// subordinate key ([`key::SubordinateRole`]).  For those cases where
313 /// the type information needs to be erased (e.g., interfaces like
314 /// [`Cert::keys`]), we provide the [`key::UnspecifiedRole`] marker.
315 ///
316 /// [`Key`]: ../enum.Key.html
317 /// [`key::PrimaryRole`]: struct.PrimaryRole.html
318 /// [`key::SubordinateRole`]: struct.SubordinateRole.html
319 /// [`Cert::keys`]: ../../cert/struct.Cert.html#method.keys
320 /// [`key::UnspecifiedRole`]: struct.UnspecifiedRole.html
321 pub trait KeyRole: fmt::Debug {
322     /// Converts a key with an unspecified role into this kind of key.
323     ///
324     /// This function is helpful when you need to convert a concrete
325     /// type into a generic type.  Using `From` works, but requires
326     /// adding a type bound to the generic type, which is ugly and
327     /// invasive.
328     ///
329     /// # Examples
330     ///
331     /// ```
332     /// use sequoia_openpgp as openpgp;
333     /// use openpgp::Result;
334     /// # use openpgp::cert::prelude::*;
335     /// use openpgp::packet::prelude::*;
336     ///
337     /// fn f<R>(cert: &Cert, mut key: Key<key::UnspecifiedParts, R>)
338     ///     -> Result<Key<key::UnspecifiedParts, R>>
339     ///     where R: key::KeyRole
340     /// {
341     ///     // ...
342     ///
343     /// # let criterium = true;
344     ///     if criterium {
345     ///         // Cert::primary_key's return type is concrete
346     ///         // (Key<key::PublicParts, key::PrimaryRole>).  We need to
347     ///         // convert it to the generic type Key<key::UnspecifiedParts, R>.
348     ///         // First, we "downcast" it to have unspecified parts and an
349     ///         // unspecified role, then we use a method defined by the
350     ///         // generic type to perform the conversion to the generic
351     ///         // type R.
352     ///         key = R::convert_key(
353     ///             cert.primary_key().key().clone()
354     ///                 .parts_into_unspecified()
355     ///                 .role_into_unspecified());
356     ///     }
357     /// #   else { unreachable!() }
358     ///
359     ///     // ...
360     ///
361     ///     Ok(key)
362     /// }
363     /// # fn main() -> openpgp::Result<()> {
364     /// # let (cert, _) =
365     /// #     CertBuilder::general_purpose(None, Some("alice@example.org"))
366     /// #     .generate()?;
367     /// # f(&cert, cert.primary_key().key().clone().parts_into_unspecified()).unwrap();
368     /// # Ok(())
369     /// # }
370     /// ```
convert_key<P: KeyParts>(key: Key<P, UnspecifiedRole>) -> Key<P, Self> where Self: Sized371     fn convert_key<P: KeyParts>(key: Key<P, UnspecifiedRole>)
372                                 -> Key<P, Self>
373         where Self: Sized;
374 
375     /// Converts a key reference with an unspecified role into this
376     /// kind of key reference.
377     ///
378     /// This function is helpful when you need to convert a concrete
379     /// type into a generic type.  Using `From` works, but requires
380     /// adding a type bound to the generic type, which is ugly and
381     /// invasive.
convert_key_ref<P: KeyParts>(key: &Key<P, UnspecifiedRole>) -> &Key<P, Self> where Self: Sized382     fn convert_key_ref<P: KeyParts>(key: &Key<P, UnspecifiedRole>)
383                                     -> &Key<P, Self>
384         where Self: Sized;
385 
386     /// Converts a key bundle with an unspecified role into this kind
387     /// of key bundle.
388     ///
389     /// This function is helpful when you need to convert a concrete
390     /// type into a generic type.  Using `From` works, but requires
391     /// adding a type bound to the generic type, which is ugly and
392     /// invasive.
convert_bundle<P: KeyParts>(bundle: KeyBundle<P, UnspecifiedRole>) -> KeyBundle<P, Self> where Self: Sized393     fn convert_bundle<P: KeyParts>(bundle: KeyBundle<P, UnspecifiedRole>)
394                                    -> KeyBundle<P, Self>
395         where Self: Sized;
396 
397     /// Converts a key bundle reference with an unspecified role into
398     /// this kind of key bundle reference.
399     ///
400     /// This function is helpful when you need to convert a concrete
401     /// type into a generic type.  Using `From` works, but requires
402     /// adding a type bound to the generic type, which is ugly and
403     /// invasive.
convert_bundle_ref<P: KeyParts>(bundle: &KeyBundle<P, UnspecifiedRole>) -> &KeyBundle<P, Self> where Self: Sized404     fn convert_bundle_ref<P: KeyParts>(bundle: &KeyBundle<P, UnspecifiedRole>)
405                                        -> &KeyBundle<P, Self>
406         where Self: Sized;
407 }
408 
409 /// A marker that indicates that a `Key` should be treated like a
410 /// public key.
411 ///
412 /// Note: this doesn't indicate whether the data structure contains
413 /// secret key material; it indicates whether any secret key material
414 /// should be ignored.  For instance, when exporting a key with the
415 /// `PublicParts` marker, secret key material will *not* be exported.
416 /// See the documentation for [`Key`] for a demonstration.
417 ///
418 /// Refer to [`KeyParts`] for details.
419 ///
420 /// [`Key`]: ../enum.Key.html
421 /// [`KeyParts`]: trait.KeyParts.html
422 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
423 pub struct PublicParts;
424 impl KeyParts for PublicParts {
convert_key<R: KeyRole>(key: Key<UnspecifiedParts, R>) -> Result<Key<Self, R>>425     fn convert_key<R: KeyRole>(key: Key<UnspecifiedParts, R>)
426                                -> Result<Key<Self, R>> {
427         Ok(key.into())
428     }
429 
convert_key_ref<R: KeyRole>(key: &Key<UnspecifiedParts, R>) -> Result<&Key<Self, R>>430     fn convert_key_ref<R: KeyRole>(key: &Key<UnspecifiedParts, R>)
431                                    -> Result<&Key<Self, R>> {
432         Ok(key.into())
433     }
434 
convert_bundle<R: KeyRole>(bundle: KeyBundle<UnspecifiedParts, R>) -> Result<KeyBundle<Self, R>>435     fn convert_bundle<R: KeyRole>(bundle: KeyBundle<UnspecifiedParts, R>)
436                                   -> Result<KeyBundle<Self, R>> {
437         Ok(bundle.into())
438     }
439 
convert_bundle_ref<R: KeyRole>(bundle: &KeyBundle<UnspecifiedParts, R>) -> Result<&KeyBundle<Self, R>>440     fn convert_bundle_ref<R: KeyRole>(bundle: &KeyBundle<UnspecifiedParts, R>)
441                                       -> Result<&KeyBundle<Self, R>> {
442         Ok(bundle.into())
443     }
444 
convert_key_amalgamation<'a, R: KeyRole>( ka: ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>) -> Result<ComponentAmalgamation<'a, Key<Self, R>>>445     fn convert_key_amalgamation<'a, R: KeyRole>(
446         ka: ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>)
447         -> Result<ComponentAmalgamation<'a, Key<Self, R>>> {
448         Ok(ka.into())
449     }
450 
convert_key_amalgamation_ref<'a, R: KeyRole>( ka: &'a ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>) -> Result<&'a ComponentAmalgamation<'a, Key<Self, R>>>451     fn convert_key_amalgamation_ref<'a, R: KeyRole>(
452         ka: &'a ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>)
453         -> Result<&'a ComponentAmalgamation<'a, Key<Self, R>>> {
454         Ok(ka.into())
455     }
456 }
457 
458 /// A marker that indicates that a `Key` should be treated like a
459 /// secret key.
460 ///
461 /// Unlike the [`key::PublicParts`] marker, this marker asserts that
462 /// the [`Key`] contains secret key material.  Because secret key
463 /// material is not protected by the self-signature, there is no
464 /// indication that the secret key material is actually valid.
465 ///
466 /// Refer to [`KeyParts`] for details.
467 ///
468 /// [`key::PublicParts`]: struct.PublicParts.html
469 /// [`Key`]: ../enum.Key.html
470 /// [`KeyParts`]: trait.KeyParts.html
471 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
472 pub struct SecretParts;
473 impl KeyParts for SecretParts {
convert_key<R: KeyRole>(key: Key<UnspecifiedParts, R>) -> Result<Key<Self, R>>474     fn convert_key<R: KeyRole>(key: Key<UnspecifiedParts, R>)
475                                -> Result<Key<Self, R>>{
476         key.try_into()
477     }
478 
convert_key_ref<R: KeyRole>(key: &Key<UnspecifiedParts, R>) -> Result<&Key<Self, R>>479     fn convert_key_ref<R: KeyRole>(key: &Key<UnspecifiedParts, R>)
480                                    -> Result<&Key<Self, R>> {
481         key.try_into()
482     }
483 
convert_bundle<R: KeyRole>(bundle: KeyBundle<UnspecifiedParts, R>) -> Result<KeyBundle<Self, R>>484     fn convert_bundle<R: KeyRole>(bundle: KeyBundle<UnspecifiedParts, R>)
485                                   -> Result<KeyBundle<Self, R>> {
486         bundle.try_into()
487     }
488 
convert_bundle_ref<R: KeyRole>(bundle: &KeyBundle<UnspecifiedParts, R>) -> Result<&KeyBundle<Self, R>>489     fn convert_bundle_ref<R: KeyRole>(bundle: &KeyBundle<UnspecifiedParts, R>)
490                                       -> Result<&KeyBundle<Self, R>> {
491         bundle.try_into()
492     }
493 
convert_key_amalgamation<'a, R: KeyRole>( ka: ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>) -> Result<ComponentAmalgamation<'a, Key<Self, R>>>494     fn convert_key_amalgamation<'a, R: KeyRole>(
495         ka: ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>)
496         -> Result<ComponentAmalgamation<'a, Key<Self, R>>> {
497         ka.try_into()
498     }
499 
convert_key_amalgamation_ref<'a, R: KeyRole>( ka: &'a ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>) -> Result<&'a ComponentAmalgamation<'a, Key<Self, R>>>500     fn convert_key_amalgamation_ref<'a, R: KeyRole>(
501         ka: &'a ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>)
502         -> Result<&'a ComponentAmalgamation<'a, Key<Self, R>>> {
503         ka.try_into()
504     }
505 }
506 
507 /// A marker that indicates that a `Key`'s parts are unspecified.
508 ///
509 /// Neither public key-specific nor secret key-specific operations are
510 /// allowed on these types of keys.  For instance, it is not possible
511 /// to export a key with the `UnspecifiedParts` marker, because it is
512 /// unclear how to treat any secret key material.  To export such a
513 /// key, you need to first change the marker to [`key::PublicParts`]
514 /// or [`key::SecretParts`].
515 ///
516 /// This marker is used when it is necessary to erase the type.  For
517 /// instance, we need to do this when mixing [`Key`]s with different
518 /// markers in the same collection.  See [`Cert::keys`] for an
519 /// example.
520 ///
521 /// Refer to [`KeyParts`] for details.
522 ///
523 /// [`key::PublicParts`]: struct.PublicParts.html
524 /// [`key::SecretParts`]: struct.SecretParts.html
525 /// [`KeyParts`]: trait.KeyParts.html
526 /// [`Key`]: ../enum.Key.html
527 /// [`Cert::keys`]: ../../struct.Cert.html#method.keys
528 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
529 pub struct UnspecifiedParts;
530 impl KeyParts for UnspecifiedParts {
convert_key<R: KeyRole>(key: Key<UnspecifiedParts, R>) -> Result<Key<Self, R>>531     fn convert_key<R: KeyRole>(key: Key<UnspecifiedParts, R>)
532                                -> Result<Key<Self, R>> {
533         Ok(key)
534     }
535 
convert_key_ref<R: KeyRole>(key: &Key<UnspecifiedParts, R>) -> Result<&Key<Self, R>>536     fn convert_key_ref<R: KeyRole>(key: &Key<UnspecifiedParts, R>)
537                                    -> Result<&Key<Self, R>> {
538         Ok(key)
539     }
540 
convert_bundle<R: KeyRole>(bundle: KeyBundle<UnspecifiedParts, R>) -> Result<KeyBundle<Self, R>>541     fn convert_bundle<R: KeyRole>(bundle: KeyBundle<UnspecifiedParts, R>)
542                                   -> Result<KeyBundle<Self, R>> {
543         Ok(bundle)
544     }
545 
convert_bundle_ref<R: KeyRole>(bundle: &KeyBundle<UnspecifiedParts, R>) -> Result<&KeyBundle<Self, R>>546     fn convert_bundle_ref<R: KeyRole>(bundle: &KeyBundle<UnspecifiedParts, R>)
547                                       -> Result<&KeyBundle<Self, R>> {
548         Ok(bundle)
549     }
550 
convert_key_amalgamation<'a, R: KeyRole>( ka: ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>) -> Result<ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>>551     fn convert_key_amalgamation<'a, R: KeyRole>(
552         ka: ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>)
553         -> Result<ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>> {
554         Ok(ka.into())
555     }
556 
convert_key_amalgamation_ref<'a, R: KeyRole>( ka: &'a ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>) -> Result<&'a ComponentAmalgamation<'a, Key<Self, R>>>557     fn convert_key_amalgamation_ref<'a, R: KeyRole>(
558         ka: &'a ComponentAmalgamation<'a, Key<UnspecifiedParts, R>>)
559         -> Result<&'a ComponentAmalgamation<'a, Key<Self, R>>> {
560         Ok(ka.into())
561     }
562 }
563 
564 /// A marker that indicates the `Key` should be treated like a primary key.
565 ///
566 /// Refer to [`KeyRole`] for details.
567 ///
568 /// [`KeyRole`]: trait.KeyRole.html
569 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
570 pub struct PrimaryRole;
571 impl KeyRole for PrimaryRole {
convert_key<P: KeyParts>(key: Key<P, UnspecifiedRole>) -> Key<P, Self>572     fn convert_key<P: KeyParts>(key: Key<P, UnspecifiedRole>)
573                                 -> Key<P, Self> {
574         key.into()
575     }
576 
convert_key_ref<P: KeyParts>(key: &Key<P, UnspecifiedRole>) -> &Key<P, Self>577     fn convert_key_ref<P: KeyParts>(key: &Key<P, UnspecifiedRole>)
578                                     -> &Key<P, Self> {
579         key.into()
580     }
581 
convert_bundle<P: KeyParts>(bundle: KeyBundle<P, UnspecifiedRole>) -> KeyBundle<P, Self>582     fn convert_bundle<P: KeyParts>(bundle: KeyBundle<P, UnspecifiedRole>)
583                                    -> KeyBundle<P, Self> {
584         bundle.into()
585     }
586 
convert_bundle_ref<P: KeyParts>(bundle: &KeyBundle<P, UnspecifiedRole>) -> &KeyBundle<P, Self>587     fn convert_bundle_ref<P: KeyParts>(bundle: &KeyBundle<P, UnspecifiedRole>)
588                                        -> &KeyBundle<P, Self> {
589         bundle.into()
590     }
591 }
592 
593 /// A marker that indicates the `Key` should treated like a subkey.
594 ///
595 /// Refer to [`KeyRole`] for details.
596 ///
597 /// [`KeyRole`]: trait.KeyRole.html
598 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
599 pub struct SubordinateRole;
600 impl KeyRole for SubordinateRole {
convert_key<P: KeyParts>(key: Key<P, UnspecifiedRole>) -> Key<P, Self>601     fn convert_key<P: KeyParts>(key: Key<P, UnspecifiedRole>)
602                                 -> Key<P, Self> {
603         key.into()
604     }
605 
convert_key_ref<P: KeyParts>(key: &Key<P, UnspecifiedRole>) -> &Key<P, Self>606     fn convert_key_ref<P: KeyParts>(key: &Key<P, UnspecifiedRole>)
607                                     -> &Key<P, Self> {
608         key.into()
609     }
610 
convert_bundle<P: KeyParts>(bundle: KeyBundle<P, UnspecifiedRole>) -> KeyBundle<P, Self>611     fn convert_bundle<P: KeyParts>(bundle: KeyBundle<P, UnspecifiedRole>)
612                                    -> KeyBundle<P, Self> {
613         bundle.into()
614     }
615 
convert_bundle_ref<P: KeyParts>(bundle: &KeyBundle<P, UnspecifiedRole>) -> &KeyBundle<P, Self>616     fn convert_bundle_ref<P: KeyParts>(bundle: &KeyBundle<P, UnspecifiedRole>)
617                                        -> &KeyBundle<P, Self> {
618         bundle.into()
619     }
620 }
621 
622 /// A marker that indicates the `Key`'s role is unspecified.
623 ///
624 /// Neither primary key-specific nor subkey-specific operations are
625 /// allowed.  To perform those operations, the marker first has to be
626 /// changed to either [`key::PrimaryRole`] or
627 /// [`key::SubordinateRole`], as appropriate.
628 ///
629 /// Refer to [`KeyRole`] for details.
630 ///
631 /// [`key::PrimaryRole`]: struct.PrimaryRole.html
632 /// [`key::SubordinateRole`]: struct.SubordinateRole.html
633 /// [`KeyRole`]: trait.KeyRole.html
634 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
635 pub struct UnspecifiedRole;
636 impl KeyRole for UnspecifiedRole {
convert_key<P: KeyParts>(key: Key<P, UnspecifiedRole>) -> Key<P, Self>637     fn convert_key<P: KeyParts>(key: Key<P, UnspecifiedRole>)
638                                 -> Key<P, Self> {
639         key
640     }
641 
convert_key_ref<P: KeyParts>(key: &Key<P, UnspecifiedRole>) -> &Key<P, Self>642     fn convert_key_ref<P: KeyParts>(key: &Key<P, UnspecifiedRole>)
643                                     -> &Key<P, Self> {
644         key
645     }
646 
convert_bundle<P: KeyParts>(bundle: KeyBundle<P, UnspecifiedRole>) -> KeyBundle<P, Self>647     fn convert_bundle<P: KeyParts>(bundle: KeyBundle<P, UnspecifiedRole>)
648                                    -> KeyBundle<P, Self> {
649         bundle
650     }
651 
convert_bundle_ref<P: KeyParts>(bundle: &KeyBundle<P, UnspecifiedRole>) -> &KeyBundle<P, Self>652     fn convert_bundle_ref<P: KeyParts>(bundle: &KeyBundle<P, UnspecifiedRole>)
653                                        -> &KeyBundle<P, Self> {
654         bundle
655     }
656 }
657 
658 /// A Public Key.
659 pub(crate) type PublicKey = Key<PublicParts, PrimaryRole>;
660 /// A Public Subkey.
661 pub(crate) type PublicSubkey = Key<PublicParts, SubordinateRole>;
662 /// A Secret Key.
663 pub(crate) type SecretKey = Key<SecretParts, PrimaryRole>;
664 /// A Secret Subkey.
665 pub(crate) type SecretSubkey = Key<SecretParts, SubordinateRole>;
666 
667 /// A key with public parts, and an unspecified role
668 /// (`UnspecifiedRole`).
669 #[allow(dead_code)]
670 pub(crate) type UnspecifiedPublic = Key<PublicParts, UnspecifiedRole>;
671 /// A key with secret parts, and an unspecified role
672 /// (`UnspecifiedRole`).
673 pub(crate) type UnspecifiedSecret = Key<SecretParts, UnspecifiedRole>;
674 
675 /// A primary key with unspecified parts (`UnspecifiedParts`).
676 #[allow(dead_code)]
677 pub(crate) type UnspecifiedPrimary = Key<UnspecifiedParts, PrimaryRole>;
678 /// A subkey key with unspecified parts (`UnspecifiedParts`).
679 #[allow(dead_code)]
680 pub(crate) type UnspecifiedSecondary = Key<UnspecifiedParts, SubordinateRole>;
681 
682 /// A key whose parts and role are unspecified
683 /// (`UnspecifiedParts`, `UnspecifiedRole`).
684 #[allow(dead_code)]
685 pub(crate) type UnspecifiedKey = Key<UnspecifiedParts, UnspecifiedRole>;
686 
687 
688 /// Holds a public key, public subkey, private key or private subkey
689 /// packet.
690 ///
691 /// Use [`Key4::generate_rsa`] or [`Key4::generate_ecc`] to create a
692 /// new key.
693 ///
694 /// Existing key material can be turned into an OpenPGP key using
695 /// [`Key4::with_secret`], [`Key4::import_public_cv25519`],
696 /// [`Key4::import_public_ed25519`], [`Key4::import_public_rsa`],
697 /// [`Key4::import_secret_cv25519`], [`Key4::import_secret_ed25519`],
698 /// and [`Key4::import_secret_rsa`].
699 ///
700 /// Whether you create a new key or import existing key material, you
701 /// still need to create a binding signature, and, for signing keys, a
702 /// back signature before integrating the key into a certificate.
703 ///
704 /// Normally, you won't directly use `Key4`, but [`Key`], which is a
705 /// relatively thin wrapper around `Key4`.
706 ///
707 /// See [Section 5.5 of RFC 4880] and [the documentation for `Key`]
708 /// for more details.
709 ///
710 /// [`Key4::with_secret`]: #method.with_secret
711 /// [`Key4::generate_rsa`]: #method.generate_rsa
712 /// [`Key4::generate_ecc`]: #method.generate_ecc
713 /// [`Key4::import_public_cv25519`]: #method.import_public_cv25519
714 /// [`Key4::import_public_ed25519`]: #method.import_public_ed25519
715 /// [`Key4::import_public_rsa`]: #method.import_public_rsa
716 /// [`Key4::import_secret_cv25519`]: #method.import_secret_cv25519
717 /// [`Key4::import_secret_ed25519`]: #method.import_secret_ed25519
718 /// [`Key4::import_secret_rsa`]: #method.import_secret_rsa
719 /// [Section 5.5 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.5
720 /// [the documentation for `Key`]: ../enum.Key.html
721 /// [`Key`]: ../enum.Key.html
722 #[derive(Clone)]
723 pub struct Key4<P, R>
724     where P: KeyParts, R: KeyRole
725 {
726     /// CTB packet header fields.
727     pub(crate) common: packet::Common,
728     /// When the key was created.
729     creation_time: Timestamp,
730     /// Public key algorithm of this signature.
731     pk_algo: PublicKeyAlgorithm,
732     /// Public key MPIs.
733     mpis: mpi::PublicKey,
734     /// Optional secret part of the key.
735     secret: Option<SecretKeyMaterial>,
736 
737     p: std::marker::PhantomData<P>,
738     r: std::marker::PhantomData<R>,
739 }
740 
741 impl<P: KeyParts, R: KeyRole> PartialEq for Key4<P, R> {
eq(&self, other: &Key4<P, R>) -> bool742     fn eq(&self, other: &Key4<P, R>) -> bool {
743         self.creation_time == other.creation_time
744             && self.pk_algo == other.pk_algo
745             && self.mpis == other.mpis
746             && self.secret == other.secret
747     }
748 }
749 
750 impl<P: KeyParts, R: KeyRole> Eq for Key4<P, R> {}
751 
752 impl<P: KeyParts, R: KeyRole> std::hash::Hash for Key4<P, R> {
hash<H: std::hash::Hasher>(&self, state: &mut H)753     fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
754         std::hash::Hash::hash(&self.creation_time, state);
755         std::hash::Hash::hash(&self.pk_algo, state);
756         std::hash::Hash::hash(&self.mpis, state);
757         std::hash::Hash::hash(&self.secret, state);
758     }
759 }
760 
761 impl<P, R> fmt::Debug for Key4<P, R>
762     where P: key::KeyParts,
763           R: key::KeyRole,
764 {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result765     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
766         f.debug_struct("Key4")
767             .field("fingerprint", &self.fingerprint())
768             .field("creation_time", &self.creation_time)
769             .field("pk_algo", &self.pk_algo)
770             .field("mpis", &self.mpis)
771             .field("secret", &self.secret)
772             .finish()
773     }
774 }
775 
776 impl<P, R> fmt::Display for Key4<P, R>
777     where P: key::KeyParts,
778           R: key::KeyRole,
779 {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result780     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
781         write!(f, "{}", self.fingerprint())
782     }
783 }
784 
785 impl<P, R> Key4<P, R>
786     where P: key::KeyParts,
787           R: key::KeyRole,
788 {
789     /// Compares the public bits of two keys.
790     ///
791     /// This returns `Ordering::Equal` if the public MPIs, creation
792     /// time, and algorithm of the two `Key4`s match.  This does not
793     /// consider the packets' encodings, packets' tags or their secret
794     /// key material.
public_cmp<PB, RB>(&self, b: &Key4<PB, RB>) -> Ordering where PB: key::KeyParts, RB: key::KeyRole,795     pub fn public_cmp<PB, RB>(&self, b: &Key4<PB, RB>) -> Ordering
796         where PB: key::KeyParts,
797               RB: key::KeyRole,
798     {
799         match self.mpis.cmp(&b.mpis) {
800             Ordering::Equal => (),
801             o => return o,
802         }
803 
804         match self.creation_time.cmp(&b.creation_time) {
805             Ordering::Equal => (),
806             o => return o,
807         }
808 
809         self.pk_algo.cmp(&b.pk_algo)
810     }
811 
812     /// Tests whether two keys are equal modulo their secret key
813     /// material.
814     ///
815     /// This returns true if the public MPIs, creation time and
816     /// algorithm of the two `Key4`s match.  This does not consider
817     /// the packets' encodings, packets' tags or their secret key
818     /// material.
public_eq<PB, RB>(&self, b: &Key4<PB, RB>) -> bool where PB: key::KeyParts, RB: key::KeyRole,819     pub fn public_eq<PB, RB>(&self, b: &Key4<PB, RB>) -> bool
820         where PB: key::KeyParts,
821               RB: key::KeyRole,
822     {
823         self.public_cmp(b) == Ordering::Equal
824     }
825 }
826 
827 impl<R> Key4<key::PublicParts, R>
828     where R: key::KeyRole,
829 {
830     /// Creates an OpenPGP public key from the specified key material.
new<T>(creation_time: T, pk_algo: PublicKeyAlgorithm, mpis: mpi::PublicKey) -> Result<Self> where T: Into<time::SystemTime>831     pub fn new<T>(creation_time: T, pk_algo: PublicKeyAlgorithm,
832                   mpis: mpi::PublicKey)
833                   -> Result<Self>
834         where T: Into<time::SystemTime>
835     {
836         Ok(Key4 {
837             common: Default::default(),
838             creation_time: creation_time.into().try_into()?,
839             pk_algo,
840             mpis,
841             secret: None,
842             p: std::marker::PhantomData,
843             r: std::marker::PhantomData,
844         })
845     }
846 
847     /// Creates an OpenPGP public key packet from existing X25519 key
848     /// material.
849     ///
850     /// The ECDH key will use hash algorithm `hash` and symmetric
851     /// algorithm `sym`.  If one or both are `None` secure defaults
852     /// will be used.  The key will have its creation date set to
853     /// `ctime` or the current time if `None` is given.
import_public_cv25519<H, S, T>(public_key: &[u8], hash: H, sym: S, ctime: T) -> Result<Self> where H: Into<Option<HashAlgorithm>>, S: Into<Option<SymmetricAlgorithm>>, T: Into<Option<time::SystemTime>>854     pub fn import_public_cv25519<H, S, T>(public_key: &[u8],
855                                           hash: H, sym: S, ctime: T)
856         -> Result<Self> where H: Into<Option<HashAlgorithm>>,
857                               S: Into<Option<SymmetricAlgorithm>>,
858                               T: Into<Option<time::SystemTime>>
859     {
860         let mut point = Vec::from(public_key);
861         point.insert(0, 0x40);
862 
863         Self::new(
864             ctime.into().unwrap_or_else(time::SystemTime::now),
865             PublicKeyAlgorithm::ECDH,
866             mpi::PublicKey::ECDH {
867                 curve: Curve::Cv25519,
868                 hash: hash.into().unwrap_or(HashAlgorithm::SHA512),
869                 sym: sym.into().unwrap_or(SymmetricAlgorithm::AES256),
870                 q: mpi::MPI::new(&point),
871             })
872     }
873 
874     /// Creates an OpenPGP public key packet from existing Ed25519 key
875     /// material.
876     ///
877     /// The ECDH key will use hash algorithm `hash` and symmetric
878     /// algorithm `sym`.  If one or both are `None` secure defaults
879     /// will be used.  The key will have its creation date set to
880     /// `ctime` or the current time if `None` is given.
import_public_ed25519<T>(public_key: &[u8], ctime: T) -> Result<Self> where T: Into<Option<time::SystemTime>>881     pub fn import_public_ed25519<T>(public_key: &[u8], ctime: T) -> Result<Self>
882         where  T: Into<Option<time::SystemTime>>
883     {
884         let mut point = Vec::from(public_key);
885         point.insert(0, 0x40);
886 
887         Self::new(
888             ctime.into().unwrap_or_else(time::SystemTime::now),
889             PublicKeyAlgorithm::EdDSA,
890             mpi::PublicKey::EdDSA {
891                 curve: Curve::Ed25519,
892                 q: mpi::MPI::new(&point),
893             })
894     }
895 
896     /// Creates an OpenPGP public key packet from existing RSA key
897     /// material.
898     ///
899     /// The RSA key will use the public exponent `e` and the modulo
900     /// `n`. The key will have its creation date set to `ctime` or the
901     /// current time if `None` is given.
import_public_rsa<T>(e: &[u8], n: &[u8], ctime: T) -> Result<Self> where T: Into<Option<time::SystemTime>>902     pub fn import_public_rsa<T>(e: &[u8], n: &[u8], ctime: T)
903         -> Result<Self> where T: Into<Option<time::SystemTime>>
904     {
905         Self::new(
906             ctime.into().unwrap_or_else(time::SystemTime::now),
907             PublicKeyAlgorithm::RSAEncryptSign,
908             mpi::PublicKey::RSA {
909                 e: mpi::MPI::new(e),
910                 n: mpi::MPI::new(n),
911             })
912     }
913 }
914 
915 impl<R> Key4<SecretParts, R>
916     where R: key::KeyRole,
917 {
918     /// Creates an OpenPGP key packet from the specified secret key
919     /// material.
with_secret<T>(creation_time: T, pk_algo: PublicKeyAlgorithm, mpis: mpi::PublicKey, secret: SecretKeyMaterial) -> Result<Self> where T: Into<time::SystemTime>920     pub fn with_secret<T>(creation_time: T, pk_algo: PublicKeyAlgorithm,
921                           mpis: mpi::PublicKey,
922                           secret: SecretKeyMaterial)
923                           -> Result<Self>
924         where T: Into<time::SystemTime>
925     {
926         Ok(Key4 {
927             common: Default::default(),
928             creation_time: creation_time.into().try_into()?,
929             pk_algo,
930             mpis,
931             secret: Some(secret),
932             p: std::marker::PhantomData,
933             r: std::marker::PhantomData,
934         })
935     }
936 }
937 
938 impl<P, R> Key4<P, R>
939      where P: key::KeyParts,
940            R: key::KeyRole,
941 {
942     /// Gets the `Key`'s creation time.
creation_time(&self) -> time::SystemTime943     pub fn creation_time(&self) -> time::SystemTime {
944         self.creation_time.into()
945     }
946 
947     /// Sets the `Key`'s creation time.
948     ///
949     /// `timestamp` is converted to OpenPGP's internal format,
950     /// [`Timestamp`]: a 32-bit quantity containing the number of
951     /// seconds since the Unix epoch.
952     ///
953     /// `timestamp` is silently rounded to match the internal
954     /// resolution.  An error is returned if `timestamp` is out of
955     /// range.
956     ///
957     /// [`Timestamp`]: ../../types/struct.Timestamp.html
set_creation_time<T>(&mut self, timestamp: T) -> Result<time::SystemTime> where T: Into<time::SystemTime>958     pub fn set_creation_time<T>(&mut self, timestamp: T)
959                                 -> Result<time::SystemTime>
960         where T: Into<time::SystemTime>
961     {
962         Ok(std::mem::replace(&mut self.creation_time,
963                              timestamp.into().try_into()?)
964            .into())
965     }
966 
967     /// Gets the public key algorithm.
pk_algo(&self) -> PublicKeyAlgorithm968     pub fn pk_algo(&self) -> PublicKeyAlgorithm {
969         self.pk_algo
970     }
971 
972     /// Sets the public key algorithm.
973     ///
974     /// Returns the old public key algorithm.
set_pk_algo(&mut self, pk_algo: PublicKeyAlgorithm) -> PublicKeyAlgorithm975     pub fn set_pk_algo(&mut self, pk_algo: PublicKeyAlgorithm)
976         -> PublicKeyAlgorithm
977     {
978         ::std::mem::replace(&mut self.pk_algo, pk_algo)
979     }
980 
981     /// Returns a reference to the `Key`'s MPIs.
mpis(&self) -> &mpi::PublicKey982     pub fn mpis(&self) -> &mpi::PublicKey {
983         &self.mpis
984     }
985 
986     /// Returns a mutable reference to the `Key`'s MPIs.
mpis_mut(&mut self) -> &mut mpi::PublicKey987     pub fn mpis_mut(&mut self) -> &mut mpi::PublicKey {
988         &mut self.mpis
989     }
990 
991     /// Sets the `Key`'s MPIs.
992     ///
993     /// This function returns the old MPIs, if any.
set_mpis(&mut self, mpis: mpi::PublicKey) -> mpi::PublicKey994     pub fn set_mpis(&mut self, mpis: mpi::PublicKey) -> mpi::PublicKey {
995         ::std::mem::replace(&mut self.mpis, mpis)
996     }
997 
998     /// Returns whether the `Key` contains secret key material.
has_secret(&self) -> bool999     pub fn has_secret(&self) -> bool {
1000         self.secret.is_some()
1001     }
1002 
1003     /// Returns whether the `Key` contains unencrypted secret key
1004     /// material.
1005     ///
1006     /// This returns false if the `Key` doesn't contain any secret key
1007     /// material.
has_unencrypted_secret(&self) -> bool1008     pub fn has_unencrypted_secret(&self) -> bool {
1009         match self.secret {
1010             Some(SecretKeyMaterial::Unencrypted { .. }) => true,
1011             _ => false,
1012         }
1013     }
1014 
1015     /// Returns `Key`'s secret key material, if any.
optional_secret(&self) -> Option<&SecretKeyMaterial>1016     pub fn optional_secret(&self) -> Option<&SecretKeyMaterial> {
1017         self.secret.as_ref()
1018     }
1019 
1020     /// Computes and returns the `Key`'s `Fingerprint` and returns it as
1021     /// a `KeyHandle`.
1022     ///
1023     /// See [Section 12.2 of RFC 4880].
1024     ///
1025     /// [Section 12.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-12.2
key_handle(&self) -> KeyHandle1026     pub fn key_handle(&self) -> KeyHandle {
1027         self.fingerprint().into()
1028     }
1029 
1030     /// Computes and returns the `Key`'s `Fingerprint`.
1031     ///
1032     /// See [Section 12.2 of RFC 4880].
1033     ///
1034     /// [Section 12.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-12.2
fingerprint(&self) -> Fingerprint1035     pub fn fingerprint(&self) -> Fingerprint {
1036         let mut h = HashAlgorithm::SHA1.context().unwrap();
1037 
1038         self.hash(&mut h);
1039 
1040         let mut digest = vec![0u8; h.digest_size()];
1041         h.digest(&mut digest);
1042         Fingerprint::from_bytes(digest.as_slice())
1043     }
1044 
1045     /// Computes and returns the `Key`'s `Key ID`.
1046     ///
1047     /// See [Section 12.2 of RFC 4880].
1048     ///
1049     /// [Section 12.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-12.2
keyid(&self) -> KeyID1050     pub fn keyid(&self) -> KeyID {
1051         self.fingerprint().into()
1052     }
1053 }
1054 
1055 macro_rules! impl_common_secret_functions {
1056     ($t: ident) => {
1057         /// Secret key material handling.
1058         impl<R> Key4<$t, R>
1059             where R: key::KeyRole,
1060         {
1061             /// Takes the `Key`'s `SecretKeyMaterial`, if any.
1062             pub fn take_secret(mut self)
1063                                -> (Key4<PublicParts, R>, Option<SecretKeyMaterial>)
1064             {
1065                 let old = std::mem::replace(&mut self.secret, None);
1066                 (self.parts_into_public(), old)
1067             }
1068 
1069             /// Adds the secret key material to the `Key`, returning
1070             /// the old secret key material, if any.
1071             pub fn add_secret(mut self, secret: SecretKeyMaterial)
1072                               -> (Key4<SecretParts, R>, Option<SecretKeyMaterial>)
1073             {
1074                 let old = std::mem::replace(&mut self.secret, Some(secret));
1075                 (self.parts_into_secret().expect("secret just set"), old)
1076             }
1077         }
1078     }
1079 }
1080 impl_common_secret_functions!(PublicParts);
1081 impl_common_secret_functions!(UnspecifiedParts);
1082 
1083 /// Secret key handling.
1084 impl<R> Key4<SecretParts, R>
1085     where R: key::KeyRole,
1086 {
1087     /// Gets the `Key`'s `SecretKeyMaterial`.
secret(&self) -> &SecretKeyMaterial1088     pub fn secret(&self) -> &SecretKeyMaterial {
1089         self.secret.as_ref().expect("has secret")
1090     }
1091 
1092     /// Gets a mutable reference to the `Key`'s `SecretKeyMaterial`.
secret_mut(&mut self) -> &mut SecretKeyMaterial1093     pub fn secret_mut(&mut self) -> &mut SecretKeyMaterial {
1094         self.secret.as_mut().expect("has secret")
1095     }
1096 
1097     /// Takes the `Key`'s `SecretKeyMaterial`.
take_secret(mut self) -> (Key4<PublicParts, R>, SecretKeyMaterial)1098     pub fn take_secret(mut self)
1099                        -> (Key4<PublicParts, R>, SecretKeyMaterial)
1100     {
1101         let old = std::mem::replace(&mut self.secret, None);
1102         (self.parts_into_public(),
1103          old.expect("Key<SecretParts, _> has a secret key material"))
1104     }
1105 
1106     /// Adds `SecretKeyMaterial` to the `Key`.
1107     ///
1108     /// This function returns the old secret key material, if any.
add_secret(mut self, secret: SecretKeyMaterial) -> (Key4<SecretParts, R>, SecretKeyMaterial)1109     pub fn add_secret(mut self, secret: SecretKeyMaterial)
1110                       -> (Key4<SecretParts, R>, SecretKeyMaterial)
1111     {
1112         let old = std::mem::replace(&mut self.secret, Some(secret));
1113         (self.parts_into_secret().expect("secret just set"),
1114          old.expect("Key<SecretParts, _> has a secret key material"))
1115     }
1116 
1117     /// Decrypts the secret key material using `password`.
1118     ///
1119     /// In OpenPGP, secret key material can be [protected with a
1120     /// password].  The password is usually hardened using a [KDF].
1121     ///
1122     /// Refer to the documentation of [`Key::decrypt_secret`] for
1123     /// details.
1124     ///
1125     /// This function returns an error if the secret key material is
1126     /// not encrypted or the password is incorrect.
1127     ///
1128     /// [protected with a password]: https://tools.ietf.org/html/rfc4880#section-5.5.3
1129     /// [KDF]: https://tools.ietf.org/html/rfc4880#section-3.7
1130     /// [`Key::decrypt_secret`]: ../enum.Key.html#method.decrypt_secret
decrypt_secret(mut self, password: &Password) -> Result<Self>1131     pub fn decrypt_secret(mut self, password: &Password) -> Result<Self> {
1132         let pk_algo = self.pk_algo;
1133         self.secret_mut().decrypt_in_place(pk_algo, password)?;
1134         Ok(self)
1135     }
1136 
1137     /// Encrypts the secret key material using `password`.
1138     ///
1139     /// In OpenPGP, secret key material can be [protected with a
1140     /// password].  The password is usually hardened using a [KDF].
1141     ///
1142     /// Refer to the documentation of [`Key::encrypt_secret`] for
1143     /// details.
1144     ///
1145     /// This returns an error if the secret key material is already
1146     /// encrypted.
1147     ///
1148     /// [protected with a password]: https://tools.ietf.org/html/rfc4880#section-5.5.3
1149     /// [KDF]: https://tools.ietf.org/html/rfc4880#section-3.7
1150     /// [`Key::encrypt_secret`]: ../enum.Key.html#method.encrypt_secret
encrypt_secret(mut self, password: &Password) -> Result<Key4<SecretParts, R>>1151     pub fn encrypt_secret(mut self, password: &Password)
1152         -> Result<Key4<SecretParts, R>>
1153     {
1154         self.secret_mut().encrypt_in_place(password)?;
1155         Ok(self)
1156     }
1157 }
1158 
1159 impl<P, R> From<Key4<P, R>> for super::Key<P, R>
1160     where P: key::KeyParts,
1161           R: key::KeyRole,
1162 {
from(p: Key4<P, R>) -> Self1163     fn from(p: Key4<P, R>) -> Self {
1164         super::Key::V4(p)
1165     }
1166 }
1167 
1168 /// Holds secret key material.
1169 ///
1170 /// This type allows postponing the decryption of the secret key
1171 /// material until it is actually needed.
1172 ///
1173 /// If the secret key material is not encrypted with a password, then
1174 /// we encrypt it in memory.  This helps protect against
1175 /// [heartbleed]-style attacks where a buffer over-read allows an
1176 /// attacker to read from the process's address space.  This
1177 /// protection is less important for Rust programs, which are memory
1178 /// safe.  However, it is essential when Sequoia is used via its FFI.
1179 ///
1180 /// See [`crypto::mem::Encrypted`] for details.
1181 ///
1182 /// [`Unencrypted`]: struct.Unencrypted.html
1183 /// [heartbleed]: https://en.wikipedia.org/wiki/Heartbleed
1184 /// [`crypto::mem::Encrypted`]: ../../crypto/mem/struct.Encrypted.html
1185 #[derive(PartialEq, Eq, Hash, Clone, Debug)]
1186 pub enum SecretKeyMaterial {
1187     /// Unencrypted secret key. Can be used as-is.
1188     Unencrypted(Unencrypted),
1189     /// The secret key is encrypted with a password.
1190     Encrypted(Encrypted),
1191 }
1192 
1193 impl From<mpi::SecretKeyMaterial> for SecretKeyMaterial {
from(mpis: mpi::SecretKeyMaterial) -> Self1194     fn from(mpis: mpi::SecretKeyMaterial) -> Self {
1195         SecretKeyMaterial::Unencrypted(mpis.into())
1196     }
1197 }
1198 
1199 impl From<Unencrypted> for SecretKeyMaterial {
from(key: Unencrypted) -> Self1200     fn from(key: Unencrypted) -> Self {
1201         SecretKeyMaterial::Unencrypted(key)
1202     }
1203 }
1204 
1205 impl From<Encrypted> for SecretKeyMaterial {
from(key: Encrypted) -> Self1206     fn from(key: Encrypted) -> Self {
1207         SecretKeyMaterial::Encrypted(key)
1208     }
1209 }
1210 
1211 impl SecretKeyMaterial {
1212     /// Decrypts the secret key material using `password`.
1213     ///
1214     /// The `SecretKeyMaterial` type does not know what kind of key it
1215     /// contains.  So, in order to know how many MPIs to parse, the
1216     /// public key algorithm needs to be provided explicitly.
1217     ///
1218     /// This returns an error if the secret key material is not
1219     /// encrypted or the password is incorrect.
decrypt(mut self, pk_algo: PublicKeyAlgorithm, password: &Password) -> Result<Self>1220     pub fn decrypt(mut self, pk_algo: PublicKeyAlgorithm,
1221                    password: &Password)
1222         -> Result<Self>
1223     {
1224         self.decrypt_in_place(pk_algo, password)?;
1225         Ok(self)
1226     }
1227 
1228     /// Decrypts the secret key material using `password`.
1229     ///
1230     /// The `SecretKeyMaterial` type does not know what kind of key it
1231     /// contains.  So, in order to know how many MPIs to parse, the
1232     /// public key algorithm needs to be provided explicitly.
1233     ///
1234     /// This returns an error if the secret key material is not
1235     /// encrypted or the password is incorrect.
decrypt_in_place(&mut self, pk_algo: PublicKeyAlgorithm, password: &Password) -> Result<()>1236     pub fn decrypt_in_place(&mut self, pk_algo: PublicKeyAlgorithm,
1237                             password: &Password)
1238         -> Result<()>
1239     {
1240         match self {
1241             SecretKeyMaterial::Encrypted(e) => {
1242                 *self = e.decrypt(pk_algo, password)?.into();
1243                 Ok(())
1244             }
1245             SecretKeyMaterial::Unencrypted(_) =>
1246                 Err(Error::InvalidArgument(
1247                     "secret key is not encrypted".into()).into()),
1248         }
1249     }
1250 
1251     /// Encrypts the secret key material using `password`.
1252     ///
1253     /// This returns an error if the secret key material is encrypted.
1254     ///
1255     /// See [`Unencrypted::encrypt`] for details.
1256     ///
1257     /// [`Unencrypted::encrypt`]: struct.Unencrypted.html#encrypt
encrypt(mut self, password: &Password) -> Result<Self>1258     pub fn encrypt(mut self, password: &Password) -> Result<Self> {
1259         self.encrypt_in_place(password)?;
1260         Ok(self)
1261     }
1262 
1263     /// Encrypts the secret key material using `password`.
1264     ///
1265     /// This returns an error if the secret key material is encrypted.
1266     ///
1267     /// See [`Unencrypted::encrypt`] for details.
1268     ///
1269     /// [`Unencrypted::encrypt`]: struct.Unencrypted.html#encrypt
encrypt_in_place(&mut self, password: &Password) -> Result<()>1270     pub fn encrypt_in_place(&mut self, password: &Password) -> Result<()> {
1271         match self {
1272             SecretKeyMaterial::Unencrypted(ref u) => {
1273                 *self = SecretKeyMaterial::Encrypted(
1274                     u.encrypt(password)?.into());
1275                 Ok(())
1276             }
1277             SecretKeyMaterial::Encrypted(_) =>
1278                 Err(Error::InvalidArgument(
1279                     "secret key is encrypted".into()).into()),
1280         }
1281     }
1282 
1283     /// Returns whether the secret key material is encrypted.
is_encrypted(&self) -> bool1284     pub fn is_encrypted(&self) -> bool {
1285         match self {
1286             SecretKeyMaterial::Encrypted(_) => true,
1287             SecretKeyMaterial::Unencrypted(_) => false,
1288         }
1289     }
1290 }
1291 
1292 /// Unencrypted secret key material.
1293 ///
1294 /// This data structure is used by the [`SecretKeyMaterial`] enum.
1295 ///
1296 /// Unlike an [`Encrypted`] key, this key an be used as-is.
1297 ///
1298 /// The secret key is encrypted in memory and only decrypted on
1299 /// demand.  This helps protect against [heartbleed]-style
1300 /// attacks where a buffer over-read allows an attacker to read from
1301 /// the process's address space.  This protection is less important
1302 /// for Rust programs, which are memory safe.  However, it is
1303 /// essential when Sequoia is used via its FFI.
1304 ///
1305 /// See [`crypto::mem::Encrypted`] for details.
1306 ///
1307 /// [`SecretKeyMaterial`]: enum.SecretKeyMaterial.html
1308 /// [`Encrypted`]: struct.Encrypted.html
1309 /// [heartbleed]: https://en.wikipedia.org/wiki/Heartbleed
1310 /// [`crypto::mem::Encrypted`]: ../../crypto/mem/struct.Encrypted.html
1311 // Note: PartialEq, Eq, and Hash on mem::Encrypted does the right
1312 // thing.
1313 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
1314 pub struct Unencrypted {
1315     /// MPIs of the secret key.
1316     mpis: mem::Encrypted,
1317 }
1318 
1319 impl From<mpi::SecretKeyMaterial> for Unencrypted {
from(mpis: mpi::SecretKeyMaterial) -> Self1320     fn from(mpis: mpi::SecretKeyMaterial) -> Self {
1321         use crate::serialize::Marshal;
1322         let mut plaintext = Vec::new();
1323         // We need to store the type.
1324         plaintext.push(
1325             mpis.algo().unwrap_or(PublicKeyAlgorithm::Unknown(0)).into());
1326         mpis.serialize(&mut plaintext)
1327             .expect("MPI serialization to vec failed");
1328         Unencrypted { mpis: mem::Encrypted::new(plaintext.into()), }
1329     }
1330 }
1331 
1332 impl Unencrypted {
1333     /// Maps the given function over the secret.
map<F, T>(&self, mut fun: F) -> T where F: FnMut(&mpi::SecretKeyMaterial) -> T1334     pub fn map<F, T>(&self, mut fun: F) -> T
1335         where F: FnMut(&mpi::SecretKeyMaterial) -> T
1336     {
1337         self.mpis.map(|plaintext| {
1338             let algo: PublicKeyAlgorithm = plaintext[0].into();
1339             let mpis = mpi::SecretKeyMaterial::parse(algo, &plaintext[1..])
1340                 .expect("Decrypted secret key is malformed");
1341             fun(&mpis)
1342         })
1343     }
1344 
1345     /// Encrypts the secret key material using `password`.
1346     ///
1347     /// This encrypts the secret key material using an [AES 256] key
1348     /// derived from the `password` using the default [`s2k`] scheme.
1349     ///
1350     /// [AES 256]: ../../types/enum.SymmetricAlgorithm.html#variant.AES256
1351     /// [`s2k`]: ../../crypto/enum.S2K.html
encrypt(&self, password: &Password) -> Result<Encrypted>1352     pub fn encrypt(&self, password: &Password)
1353         -> Result<Encrypted>
1354     {
1355         use std::io::Write;
1356         use crate::crypto::symmetric::Encryptor;
1357 
1358         let s2k = S2K::default();
1359         let algo = SymmetricAlgorithm::AES256;
1360         let key = s2k.derive_key(password, algo.key_size()?)?;
1361 
1362         // Ciphertext is preceded by a random block.
1363         let mut trash = vec![0u8; algo.block_size()?];
1364         crypto::random(&mut trash);
1365 
1366         let mut esk = Vec::new();
1367         {
1368             let mut encryptor = Encryptor::new(algo, &key, &mut esk)?;
1369             encryptor.write_all(&trash)?;
1370             self.map(|mpis| mpis.serialize_chksumd(&mut encryptor))?;
1371         }
1372 
1373         Ok(Encrypted::new(s2k, algo, esk.into_boxed_slice()))
1374     }
1375 }
1376 
1377 /// Secret key material encrypted with a password.
1378 ///
1379 /// This data structure is used by the [`SecretKeyMaterial`] enum.
1380 ///
1381 /// [`SecretKeyMaterial`]: enum.SecretKeyMaterial.html
1382 #[derive(Clone, Debug)]
1383 pub struct Encrypted {
1384     /// Key derivation mechanism to use.
1385     s2k: S2K,
1386     /// Symmetric algorithm used to encrypt the secret key material.
1387     algo: SymmetricAlgorithm,
1388     /// Encrypted MPIs prefixed with the IV.
1389     ///
1390     /// If we recognized the S2K object during parsing, we can
1391     /// successfully parse the data into S2K, IV, and ciphertext.
1392     /// However, if we do not recognize the S2K type, we do not know
1393     /// how large its parameters are, so we cannot cleanly parse it,
1394     /// and have to accept that the S2K's body bleeds into the rest of
1395     /// the data.
1396     ciphertext: std::result::Result<Box<[u8]>,  // IV + ciphertext.
1397                                     Box<[u8]>>, // S2K body + IV + ciphertext.
1398 }
1399 
1400 // Because the S2K and ciphertext cannot be cleanly separated at parse
1401 // time, we need to carefully compare and hash encrypted key packets.
1402 
1403 impl PartialEq for Encrypted {
eq(&self, other: &Encrypted) -> bool1404     fn eq(&self, other: &Encrypted) -> bool {
1405         self.algo == other.algo
1406             // Treat S2K and ciphertext as opaque blob.
1407             && {
1408                 // XXX: This would be nicer without the allocations.
1409                 use crate::serialize::MarshalInto;
1410                 let mut a = self.s2k.to_vec().unwrap();
1411                 let mut b = other.s2k.to_vec().unwrap();
1412                 a.extend_from_slice(self.raw_ciphertext());
1413                 b.extend_from_slice(other.raw_ciphertext());
1414                 a == b
1415             }
1416     }
1417 }
1418 
1419 impl Eq for Encrypted {}
1420 
1421 impl std::hash::Hash for Encrypted {
hash<H: std::hash::Hasher>(&self, state: &mut H)1422     fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1423         self.algo.hash(state);
1424         // Treat S2K and ciphertext as opaque blob.
1425         // XXX: This would be nicer without the allocations.
1426         use crate::serialize::MarshalInto;
1427         let mut a = self.s2k.to_vec().unwrap();
1428         a.extend_from_slice(self.raw_ciphertext());
1429         a.hash(state);
1430     }
1431 }
1432 
1433 impl Encrypted {
1434     /// Creates a new encrypted key object.
new(s2k: S2K, algo: SymmetricAlgorithm, ciphertext: Box<[u8]>) -> Self1435     pub fn new(s2k: S2K, algo: SymmetricAlgorithm, ciphertext: Box<[u8]>)
1436         -> Self
1437     {
1438         Self::new_raw(s2k, algo, Ok(ciphertext))
1439     }
1440 
1441     /// Creates a new encrypted key object.
new_raw(s2k: S2K, algo: SymmetricAlgorithm, ciphertext: std::result::Result<Box<[u8]>, Box<[u8]>>) -> Self1442     pub(crate) fn new_raw(s2k: S2K, algo: SymmetricAlgorithm,
1443                           ciphertext: std::result::Result<Box<[u8]>,
1444                                                           Box<[u8]>>)
1445         -> Self
1446     {
1447         Encrypted { s2k, algo, ciphertext }
1448     }
1449 
1450     /// Returns the key derivation mechanism.
s2k(&self) -> &S2K1451     pub fn s2k(&self) -> &S2K {
1452         &self.s2k
1453     }
1454 
1455     /// Returns the symmetric algorithm used to encrypt the secret
1456     /// key material.
algo(&self) -> SymmetricAlgorithm1457     pub fn algo(&self) -> SymmetricAlgorithm {
1458         self.algo
1459     }
1460 
1461     /// Returns the encrypted secret key material.
1462     ///
1463     /// If the [`S2K`] mechanism is not supported by Sequoia, this
1464     /// function will fail.  Note that the information is not lost,
1465     /// but stored in the packet.  If the packet is serialized again,
1466     /// it is written out.
1467     ///
1468     ///   [`S2K`]: ../../crypto/enum.S2K.html
ciphertext(&self) -> Result<&[u8]>1469     pub fn ciphertext(&self) -> Result<&[u8]> {
1470         self.ciphertext
1471             .as_ref()
1472             .map(|ciphertext| &ciphertext[..])
1473             .map_err(|_| Error::MalformedPacket(
1474                 format!("Unknown S2K: {:?}", self.s2k)).into())
1475     }
1476 
1477     /// Returns the encrypted secret key material, possibly including
1478     /// the body of the S2K object.
raw_ciphertext(&self) -> &[u8]1479     pub(crate) fn raw_ciphertext(&self) -> &[u8] {
1480         match self.ciphertext.as_ref() {
1481             Ok(ciphertext) => &ciphertext[..],
1482             Err(s2k_ciphertext) => &s2k_ciphertext[..],
1483         }
1484     }
1485 
1486     /// Decrypts the secret key material using `password`.
1487     ///
1488     /// The `Encrypted` key does not know what kind of key it is, so
1489     /// the public key algorithm is needed to parse the correct number
1490     /// of MPIs.
decrypt(&self, pk_algo: PublicKeyAlgorithm, password: &Password) -> Result<Unencrypted>1491     pub fn decrypt(&self, pk_algo: PublicKeyAlgorithm, password: &Password)
1492         -> Result<Unencrypted>
1493     {
1494         use std::io::{Cursor, Read};
1495         use crate::crypto::symmetric::Decryptor;
1496 
1497         let key = self.s2k.derive_key(password, self.algo.key_size()?)?;
1498         let cur = Cursor::new(self.ciphertext()?);
1499         let mut dec = Decryptor::new(self.algo, &key, cur)?;
1500 
1501         // Consume the first block.
1502         let mut trash = vec![0u8; self.algo.block_size()?];
1503         dec.read_exact(&mut trash)?;
1504 
1505         mpi::SecretKeyMaterial::parse_chksumd(pk_algo, &mut dec).map(|m| m.into())
1506     }
1507 }
1508 
1509 #[cfg(any(test, feature = "quickcheck"))]
1510 impl<P, R> Arbitrary for super::Key<P, R>
1511     where P: KeyParts, P: Clone,
1512           R: KeyRole, R: Clone,
1513           Key4<P, R>: Arbitrary,
1514 {
arbitrary<G: Gen>(g: &mut G) -> Self1515     fn arbitrary<G: Gen>(g: &mut G) -> Self {
1516         Key4::arbitrary(g).into()
1517     }
1518 }
1519 
1520 #[cfg(any(test, feature = "quickcheck"))]
1521 impl Arbitrary for Key4<PublicParts, UnspecifiedRole> {
arbitrary<G: Gen>(g: &mut G) -> Self1522     fn arbitrary<G: Gen>(g: &mut G) -> Self {
1523         let mpis = mpi::PublicKey::arbitrary(g);
1524         Key4 {
1525             common: Arbitrary::arbitrary(g),
1526             creation_time: Arbitrary::arbitrary(g),
1527             pk_algo: mpis.algo()
1528                 .expect("mpi::PublicKey::arbitrary only uses known algos"),
1529             mpis,
1530             secret: None,
1531             p: std::marker::PhantomData,
1532             r: std::marker::PhantomData,
1533         }
1534     }
1535 }
1536 
1537 #[cfg(any(test, feature = "quickcheck"))]
1538 impl Arbitrary for Key4<SecretParts, UnspecifiedRole> {
arbitrary<G: Gen>(g: &mut G) -> Self1539     fn arbitrary<G: Gen>(g: &mut G) -> Self {
1540         use rand::Rng;
1541         use PublicKeyAlgorithm::*;
1542         use mpi::MPI;
1543 
1544         let key = Key4::arbitrary(g);
1545         let mut secret: SecretKeyMaterial = match key.pk_algo() {
1546             RSAEncryptSign => mpi::SecretKeyMaterial::RSA {
1547                 d: MPI::arbitrary(g).into(),
1548                 p: MPI::arbitrary(g).into(),
1549                 q: MPI::arbitrary(g).into(),
1550                 u: MPI::arbitrary(g).into(),
1551             },
1552 
1553             DSA => mpi::SecretKeyMaterial::DSA {
1554                 x: MPI::arbitrary(g).into(),
1555             },
1556 
1557             ElGamalEncrypt => mpi::SecretKeyMaterial::ElGamal {
1558                 x: MPI::arbitrary(g).into(),
1559             },
1560 
1561             EdDSA => mpi::SecretKeyMaterial::EdDSA {
1562                 scalar: MPI::arbitrary(g).into(),
1563             },
1564 
1565             ECDSA => mpi::SecretKeyMaterial::ECDSA {
1566                 scalar: MPI::arbitrary(g).into(),
1567             },
1568 
1569             ECDH => mpi::SecretKeyMaterial::ECDH {
1570                 scalar: MPI::arbitrary(g).into(),
1571             },
1572 
1573             _ => unreachable!("only valid algos, normalizes to these values"),
1574         }.into();
1575 
1576         if g.gen() {
1577             secret.encrypt_in_place(&Password::from(Vec::arbitrary(g)))
1578                 .unwrap();
1579         }
1580 
1581         Key4::<PublicParts, UnspecifiedRole>::add_secret(key, secret).0
1582     }
1583 }
1584 
1585 #[cfg(test)]
1586 mod tests {
1587     use crate::packet::Key;
1588     use crate::Cert;
1589     use crate::packet::pkesk::PKESK3;
1590     use crate::packet::key;
1591     use crate::packet::key::SecretKeyMaterial;
1592     use crate::packet::Packet;
1593     use super::*;
1594     use crate::PacketPile;
1595     use crate::serialize::Serialize;
1596     use crate::parse::Parse;
1597 
1598     #[test]
encrypted_rsa_key()1599     fn encrypted_rsa_key() {
1600         let cert = Cert::from_bytes(
1601             crate::tests::key("testy-new-encrypted-with-123.pgp")).unwrap();
1602         let mut pair = cert.primary_key().key().clone();
1603         let pk_algo = pair.pk_algo();
1604         let secret = pair.secret.as_mut().unwrap();
1605 
1606         assert!(secret.is_encrypted());
1607         secret.decrypt_in_place(pk_algo, &"123".into()).unwrap();
1608         assert!(!secret.is_encrypted());
1609 
1610         match secret {
1611             SecretKeyMaterial::Unencrypted(ref u) => u.map(|mpis| match mpis {
1612                 mpi::SecretKeyMaterial::RSA { .. } => (),
1613                 _ => panic!(),
1614             }),
1615             _ => panic!(),
1616         }
1617     }
1618 
1619     #[test]
eq()1620     fn eq() {
1621         use crate::types::Curve::*;
1622 
1623         for curve in vec![NistP256, NistP384, NistP521] {
1624             let sign_key : Key4<_, key::UnspecifiedRole>
1625                 = Key4::generate_ecc(true, curve.clone()).unwrap();
1626             let enc_key : Key4<_, key::UnspecifiedRole>
1627                 = Key4::generate_ecc(false, curve).unwrap();
1628             let sign_clone = sign_key.clone();
1629             let enc_clone = enc_key.clone();
1630 
1631             assert_eq!(sign_key, sign_clone);
1632             assert_eq!(enc_key, enc_clone);
1633         }
1634 
1635         for bits in vec![1024, 2048, 3072, 4096] {
1636             let key : Key4<_, key::UnspecifiedRole>
1637                 = Key4::generate_rsa(bits).unwrap();
1638             let clone = key.clone();
1639             assert_eq!(key, clone);
1640         }
1641     }
1642 
1643     #[test]
roundtrip()1644     fn roundtrip() {
1645         use crate::types::Curve::*;
1646 
1647         let keys = vec![NistP256, NistP384, NistP521].into_iter().flat_map(|cv|
1648         {
1649             let sign_key : Key4<key::SecretParts, key::PrimaryRole>
1650                 = Key4::generate_ecc(true, cv.clone()).unwrap();
1651             let enc_key = Key4::generate_ecc(false, cv).unwrap();
1652 
1653             vec![sign_key, enc_key]
1654         }).chain(vec![1024, 2048, 3072, 4096].into_iter().map(|b| {
1655             Key4::generate_rsa(b).unwrap()
1656         }));
1657 
1658         for key in keys {
1659             let mut b = Vec::new();
1660             Packet::SecretKey(key.clone().into()).serialize(&mut b).unwrap();
1661 
1662             let pp = PacketPile::from_bytes(&b).unwrap();
1663             if let Some(Packet::SecretKey(Key::V4(ref parsed_key))) =
1664                 pp.path_ref(&[0])
1665             {
1666                 assert_eq!(key.creation_time, parsed_key.creation_time);
1667                 assert_eq!(key.pk_algo, parsed_key.pk_algo);
1668                 assert_eq!(key.mpis, parsed_key.mpis);
1669                 assert_eq!(key.secret, parsed_key.secret);
1670 
1671                 assert_eq!(&key, parsed_key);
1672             } else {
1673                 panic!("bad packet: {:?}", pp.path_ref(&[0]));
1674             }
1675 
1676             let mut b = Vec::new();
1677             let pk4 : Key4<PublicParts, PrimaryRole> = key.clone().into();
1678             Packet::PublicKey(pk4.into()).serialize(&mut b).unwrap();
1679 
1680             let pp = PacketPile::from_bytes(&b).unwrap();
1681             if let Some(Packet::PublicKey(Key::V4(ref parsed_key))) =
1682                 pp.path_ref(&[0])
1683             {
1684                 assert!(! parsed_key.has_secret());
1685 
1686                 let key = key.take_secret().0;
1687                 assert_eq!(&key, parsed_key);
1688             } else {
1689                 panic!("bad packet: {:?}", pp.path_ref(&[0]));
1690             }
1691         }
1692     }
1693 
1694     #[test]
encryption_roundtrip()1695     fn encryption_roundtrip() {
1696         use crate::crypto::SessionKey;
1697         use crate::types::Curve::*;
1698 
1699         let keys = vec![NistP256, NistP384, NistP521].into_iter().map(|cv| {
1700             Key4::generate_ecc(false, cv).unwrap()
1701         }).chain(vec![1024, 2048, 3072, 4096].into_iter().map(|b| {
1702             Key4::generate_rsa(b).unwrap()
1703         }));
1704 
1705         for key in keys.into_iter() {
1706             let key: Key<key::SecretParts, key::UnspecifiedRole> = key.into();
1707             let mut keypair = key.clone().into_keypair().unwrap();
1708             let cipher = SymmetricAlgorithm::AES256;
1709             let sk = SessionKey::new(cipher.key_size().unwrap());
1710 
1711             let pkesk = PKESK3::for_recipient(cipher, &sk, &key).unwrap();
1712             let (cipher_, sk_) = pkesk.decrypt(&mut keypair, None).unwrap();
1713 
1714             assert_eq!(cipher, cipher_);
1715             assert_eq!(sk, sk_);
1716 
1717             let (cipher_, sk_) =
1718                 pkesk.decrypt(&mut keypair, Some(cipher)).unwrap();
1719 
1720             assert_eq!(cipher, cipher_);
1721             assert_eq!(sk, sk_);
1722         }
1723     }
1724 
1725     #[test]
secret_encryption_roundtrip()1726     fn secret_encryption_roundtrip() {
1727         use crate::types::Curve::*;
1728 
1729         let keys = vec![NistP256, NistP384, NistP521].into_iter().map(|cv| {
1730             let k : Key4<key::SecretParts, key::PrimaryRole>
1731                 = Key4::generate_ecc(false, cv).unwrap();
1732             k
1733         }).chain(vec![1024, 2048, 3072, 4096].into_iter().map(|b| {
1734             Key4::generate_rsa(b).unwrap()
1735         }));
1736 
1737         for key in keys {
1738             assert!(! key.secret().is_encrypted());
1739 
1740             let password = Password::from("foobarbaz");
1741             let mut encrypted_key = key.clone();
1742 
1743             encrypted_key.secret_mut().encrypt_in_place(&password).unwrap();
1744             assert!(encrypted_key.secret().is_encrypted());
1745 
1746             encrypted_key.secret_mut()
1747                 .decrypt_in_place(key.pk_algo, &password).unwrap();
1748             assert!(! key.secret().is_encrypted());
1749             assert_eq!(key, encrypted_key);
1750             assert_eq!(key.secret(), encrypted_key.secret());
1751         }
1752     }
1753 
1754     #[test]
import_cv25519()1755     fn import_cv25519() {
1756         use crate::crypto::{ecdh, mem, SessionKey};
1757         use self::mpi::{MPI, Ciphertext};
1758 
1759         // X25519 key
1760         let ctime =
1761             time::UNIX_EPOCH + time::Duration::new(0x5c487129, 0);
1762         let public = b"\xed\x59\x0a\x15\x08\x95\xe9\x92\xd2\x2c\x14\x01\xb3\xe9\x3b\x7f\xff\xe6\x6f\x22\x65\xec\x69\xd9\xb8\xda\x24\x2c\x64\x84\x44\x11";
1763         let key : Key<_, key::UnspecifiedRole>
1764             = Key4::import_public_cv25519(&public[..],
1765                                           HashAlgorithm::SHA256,
1766                                           SymmetricAlgorithm::AES128,
1767                                           ctime).unwrap().into();
1768 
1769         // PKESK
1770         let eph_pubkey = MPI::new(&b"\x40\xda\x1c\x69\xc4\xe3\xb6\x9c\x6e\xd4\xc6\x69\x6c\x89\xc7\x09\xe9\xf8\x6a\xf1\xe3\x8d\xb6\xaa\xb5\xf7\x29\xae\xa6\xe7\xdd\xfe\x38"[..]);
1771         let ciphertext = Ciphertext::ECDH{
1772             e: eph_pubkey.clone(),
1773             key: Vec::from(&b"\x45\x8b\xd8\x4d\x88\xb3\xd2\x16\xb6\xc2\x3b\x99\x33\xd1\x23\x4b\x10\x15\x8e\x04\x16\xc5\x7c\x94\x88\xf6\x63\xf2\x68\x37\x08\x66\xfd\x5a\x7b\x40\x58\x21\x6b\x2c\xc0\xf4\xdc\x91\xd3\x48\xed\xc1"[..]).into_boxed_slice()
1774         };
1775         let shared_sec: mem::Protected = b"\x44\x0C\x99\x27\xF7\xD6\x1E\xAD\xD1\x1E\x9E\xC8\x22\x2C\x5D\x43\xCE\xB0\xE5\x45\x94\xEC\xAF\x67\xD9\x35\x1D\xA1\xA3\xA8\x10\x0B"[..].into();
1776 
1777         // Session key
1778         let dek = b"\x09\x0D\xDC\x40\xC5\x71\x51\x88\xAC\xBD\x45\x56\xD4\x2A\xDF\x77\xCD\xF4\x82\xA2\x1B\x8F\x2E\x48\x3B\xCA\xBF\xD3\xE8\x6D\x0A\x7C\xDF\x10\xe6";
1779         let sk = SessionKey::from(Vec::from(&dek[..]));
1780 
1781         // Expected
1782         let got_enc = ecdh::encrypt_wrap(&key.parts_into_public(),
1783                                            &sk, eph_pubkey, &shared_sec)
1784             .unwrap();
1785 
1786         assert_eq!(ciphertext, got_enc);
1787     }
1788 
1789     #[test]
import_cv25519_sec()1790     fn import_cv25519_sec() {
1791         use crate::crypto::ecdh;
1792         use self::mpi::{MPI, Ciphertext};
1793 
1794         // X25519 key
1795         let ctime =
1796             time::UNIX_EPOCH + time::Duration::new(0x5c487129, 0);
1797         let public = b"\xed\x59\x0a\x15\x08\x95\xe9\x92\xd2\x2c\x14\x01\xb3\xe9\x3b\x7f\xff\xe6\x6f\x22\x65\xec\x69\xd9\xb8\xda\x24\x2c\x64\x84\x44\x11";
1798         let secret = b"\xa0\x27\x13\x99\xc9\xe3\x2e\xd2\x47\xf6\xd6\x63\x9d\xe6\xec\xcb\x57\x0b\x92\xbb\x17\xfe\xb8\xf1\xc4\x1f\x06\x7c\x55\xfc\xdd\x58";
1799         let key: Key<_, UnspecifiedRole>
1800             = Key4::import_secret_cv25519(&secret[..],
1801                                           HashAlgorithm::SHA256,
1802                                           SymmetricAlgorithm::AES128,
1803                                           ctime).unwrap().into();
1804         match key.mpis {
1805             self::mpi::PublicKey::ECDH{ ref q,.. } =>
1806                 assert_eq!(&q.value()[1..], &public[..]),
1807             _ => unreachable!(),
1808         }
1809 
1810         // PKESK
1811         let eph_pubkey: &[u8; 33] = b"\x40\xda\x1c\x69\xc4\xe3\xb6\x9c\x6e\xd4\xc6\x69\x6c\x89\xc7\x09\xe9\xf8\x6a\xf1\xe3\x8d\xb6\xaa\xb5\xf7\x29\xae\xa6\xe7\xdd\xfe\x38";
1812         let ciphertext = Ciphertext::ECDH{
1813             e: MPI::new(&eph_pubkey[..]),
1814             key: Vec::from(&b"\x45\x8b\xd8\x4d\x88\xb3\xd2\x16\xb6\xc2\x3b\x99\x33\xd1\x23\x4b\x10\x15\x8e\x04\x16\xc5\x7c\x94\x88\xf6\x63\xf2\x68\x37\x08\x66\xfd\x5a\x7b\x40\x58\x21\x6b\x2c\xc0\xf4\xdc\x91\xd3\x48\xed\xc1"[..]).into_boxed_slice()
1815         };
1816 
1817         // Session key
1818         let dek = b"\x09\x0D\xDC\x40\xC5\x71\x51\x88\xAC\xBD\x45\x56\xD4\x2A\xDF\x77\xCD\xF4\x82\xA2\x1B\x8F\x2E\x48\x3B\xCA\xBF\xD3\xE8\x6D\x0A\x7C\xDF\x10\xe6";
1819 
1820         let key = key.parts_into_public();
1821         let got_dek = match key.optional_secret() {
1822             Some(SecretKeyMaterial::Unencrypted(ref u)) => u.map(|mpis| {
1823                 ecdh::decrypt(&key, mpis, &ciphertext)
1824                     .unwrap()
1825             }),
1826             _ => unreachable!(),
1827         };
1828 
1829         assert_eq!(&dek[..], &got_dek[..]);
1830     }
1831 
1832     #[test]
import_rsa()1833     fn import_rsa() {
1834         use crate::crypto::SessionKey;
1835         use self::mpi::{MPI, Ciphertext};
1836 
1837         // RSA key
1838         let ctime =
1839             time::UNIX_EPOCH + time::Duration::new(1548950502, 0);
1840         let d = b"\x14\xC4\x3A\x0C\x3A\x79\xA4\xF7\x63\x0D\x89\x93\x63\x8B\x56\x9C\x29\x2E\xCD\xCF\xBF\xB0\xEC\x66\x52\xC3\x70\x1B\x19\x21\x73\xDE\x8B\xAC\x0E\xF2\xE1\x28\x42\x66\x56\x55\x00\x3B\xFD\x50\xC4\x7C\xBC\x9D\xEB\x7D\xF4\x81\xFC\xC3\xBF\xF7\xFF\xD0\x41\x3E\x50\x3B\x5F\x5D\x5F\x56\x67\x5E\x00\xCE\xA4\x53\xB8\x59\xA0\x40\xC8\x96\x6D\x12\x09\x27\xBE\x1D\xF1\xC2\x68\xFC\xF0\x14\xD6\x52\x77\x07\xC8\x12\x36\x9C\x9A\x5C\xAF\x43\xCC\x95\x20\xBB\x0A\x44\x94\xDD\xB4\x4F\x45\x4E\x3A\x1A\x30\x0D\x66\x40\xAC\x68\xE8\xB0\xFD\xCD\x6C\x6B\x6C\xB5\xF7\xE4\x36\x95\xC2\x96\x98\xFD\xCA\x39\x6C\x1A\x2E\x55\xAD\xB6\xE0\xF8\x2C\xFF\xBC\xD3\x32\x15\x52\x39\xB3\x92\x35\xDB\x8B\x68\xAF\x2D\x4A\x6E\x64\xB8\x28\x63\xC4\x24\x94\x2D\xA9\xDB\x93\x56\xE3\xBC\xD0\xB6\x38\x84\x04\xA4\xC6\x18\x48\xFE\xB2\xF8\xE1\x60\x37\x52\x96\x41\xA5\x79\xF6\x3D\xB7\x2A\x71\x5B\x7A\x75\xBF\x7F\xA2\x5A\xC8\xA1\x38\xF2\x5A\xBD\x14\xFC\xAF\xB4\x54\x83\xA4\xBD\x49\xA2\x8B\x91\xB0\xE0\x4A\x1B\x21\x54\x07\x19\x70\x64\x7C\x3E\x9F\x8D\x8B\xE4\x70\xD1\xE7\xBE\x4E\x5C\xCE\xF1";
1841         let p = b"\xC8\x32\xD1\x17\x41\x4D\x8F\x37\x09\x18\x32\x4C\x4C\xF4\xA2\x15\x27\x43\x3D\xBB\xB5\xF6\x1F\xCF\xD2\xE4\x43\x61\x07\x0E\x9E\x35\x1F\x0A\x5D\xFB\x3A\x45\x74\x61\x73\x73\x7B\x5F\x1F\x87\xFB\x54\x8D\xA8\x85\x3E\xB0\xB7\xC7\xF5\xC9\x13\x99\x8D\x40\xE6\xA6\xD0\x71\x3A\xE3\x2D\x4A\xC3\xA3\xFF\xF7\x72\x82\x14\x52\xA4\xBA\x63\x0E\x17\xCA\xCA\x18\xC4\x3A\x40\x79\xF1\x86\xB3\x10\x4B\x9F\xB2\xAE\x2E\x13\x38\x8D\x2C\xF9\x88\x4C\x25\x53\xEF\xF9\xD1\x8B\x1A\x7C\xE7\xF6\x4B\x73\x51\x31\xFA\x44\x1D\x36\x65\x71\xDA\xFC\x6F";
1842         let q = b"\xCC\x30\xE9\xCC\xCB\x31\x28\xB5\x90\xFF\x06\x62\x42\x5B\x24\x0E\x00\xFE\xE2\x37\xC4\xAC\xBB\x3B\x8F\xF2\x0E\x3F\x78\xCF\x6B\x7C\xE8\x75\x57\x7C\x15\x9D\x1A\x66\xF2\x0A\xE5\xD3\x0B\xE7\x40\xF7\xE7\x00\xB6\x86\xB5\xD9\x20\x67\xE0\x4A\xC0\x90\xA4\x13\x4D\xC9\xB0\x12\xC5\xCD\x4C\xEB\xA1\x91\x2D\x43\x58\x6E\xB6\x75\xA0\x93\xF0\x5B\xC5\x31\xCA\xB7\xC6\x22\x0C\xD3\xEC\x84\xC5\x91\xA1\x5F\x2C\x8E\x07\x5D\xA1\x98\x67\xC5\x7A\x58\x16\x71\x3D\xED\x91\x03\x0D\xD4\x25\x07\x89\x9B\x33\x98\xA3\x70\xD9\xE7\xC8\x17\xA3\xD9";
1843         let key: key::SecretKey
1844             = Key4::import_secret_rsa(&d[..], &p[..], &q[..], ctime)
1845             .unwrap().into();
1846 
1847         // PKESK
1848         let c = b"\x8A\x1A\xD4\x82\x91\x6B\xBF\xA1\x65\xD3\x82\x8C\x97\xAB\xD0\x91\xE4\xB4\xC4\x9D\x08\xD8\x8B\xB7\xE6\x13\x3F\x6F\x52\x14\xED\xC4\x77\xB7\x31\x00\xC1\x43\xF9\x62\x53\xBF\x21\x21\x52\x74\x35\xD8\xC7\xA2\x11\x89\xA5\xD5\x21\x98\x6D\x3C\x9F\xF0\xED\xDB\xD7\x0F\xAC\x3C\x15\x25\x34\x52\xC7\x7C\x82\x07\x5A\x99\xC1\xC6\xF6\xF2\x6D\x46\xC8\x56\x59\xE7\xC6\x34\x0C\xCA\x37\x70\xB4\x97\xDA\x18\x14\xC4\x03\x0A\xCB\xE5\x0C\x41\x43\x61\xBA\x32\xB6\x9A\xF3\xDF\x0C\xB0\xCE\xBD\xFE\x72\x6C\xCC\xC1\xE8\xF0\x05\x97\x61\xEA\x30\x10\xB9\x43\xC4\x9A\x41\xED\x72\x27\xA4\xD5\xE7\x08\x41\x6C\x57\x80\xF3\x64\xF0\x45\x70\x27\x36\xBD\x64\x59\x74\xCF\xCD\x39\xE6\xEB\x7C\x62\xC8\x38\x23\xF8\x4C\xB7\x30\x9F\xF1\x40\x4A\xE9\x72\x66\x99\xF7\x2A\x47\x1C\xE7\x12\x20\x58\xBA\x87\x00\xB8\xFC\x54\xBC\xA5\x1D\x7D\x8B\x50\xA4\x4B\xB3\xD7\x44\xC7\x68\x5E\x2D\xBB\xE9\x6E\xC4\xD0\x31\xB0\xD0\xB6\x02\xD1\x74\x6B\xC9\x3D\x19\x32\x3B\xF1\x0E\x74\xF6\x12\x13\xE6\x40\x8F\xA6\x97\xAD\x83\xB0\x84\xD6\xD9\xE5\x25\x8E\x57\x0B\x7A\x7B\xD0\x5C\x29\x96\xED\x29\xED";
1849         let ciphertext = Ciphertext::RSA{
1850             c: MPI::new(&c[..]),
1851         };
1852         let pkesk = PKESK3::new(key.keyid(), PublicKeyAlgorithm::RSAEncryptSign,
1853                                 ciphertext).unwrap();
1854 
1855         // Session key
1856         let dek = b"\xA5\x58\x3A\x04\x35\x8B\xC7\x3F\x4A\xEF\x0C\x5A\xEB\xED\x59\xCA\xFD\x96\xB5\x32\x23\x26\x0C\x91\x78\xD1\x31\x12\xF0\x41\x42\x9D";
1857         let sk = SessionKey::from(Vec::from(&dek[..]));
1858 
1859         // Expected
1860         let mut decryptor = key.into_keypair().unwrap();
1861         let got_sk = pkesk.decrypt(&mut decryptor, None).unwrap();
1862         assert_eq!(got_sk.1, sk);
1863     }
1864 
1865     #[test]
import_ed25519()1866     fn import_ed25519() {
1867         use crate::types::SignatureType;
1868         use crate::packet::signature::Signature4;
1869         use crate::packet::signature::subpacket::{
1870             Subpacket, SubpacketValue, SubpacketArea};
1871 
1872         // Ed25519 key
1873         let ctime =
1874             time::UNIX_EPOCH + time::Duration::new(1548249630, 0);
1875         let q = b"\x57\x15\x45\x1B\x68\xA5\x13\xA2\x20\x0F\x71\x9D\xE3\x05\x3B\xED\xA2\x21\xDE\x61\x5A\xF5\x67\x45\xBB\x97\x99\x43\x53\x59\x7C\x3F";
1876         let key: key::PublicKey
1877             = Key4::import_public_ed25519(q, ctime).unwrap().into();
1878 
1879         let mut hashed = SubpacketArea::default();
1880         let mut unhashed = SubpacketArea::default();
1881         let fpr = "D81A 5DC0 DEBF EE5F 9AC8  20EB 6769 5DB9 920D 4FAC"
1882             .parse().unwrap();
1883         let kid = "6769 5DB9 920D 4FAC".parse().unwrap();
1884         let ctime = 1549460479.into();
1885         let r = b"\x5A\xF9\xC7\x42\x70\x24\x73\xFF\x7F\x27\xF9\x20\x9D\x20\x0F\xE3\x8F\x71\x3C\x5F\x97\xFD\x60\x80\x39\x29\xC2\x14\xFD\xC2\x4D\x70";
1886         let s = b"\x6E\x68\x74\x11\x72\xF4\x9C\xE1\x99\x99\x1F\x67\xFC\x3A\x68\x33\xF9\x3F\x3A\xB9\x1A\xA5\x72\x4E\x78\xD4\x81\xCB\x7B\xA5\xE5\x0A";
1887 
1888         hashed.add(Subpacket::new(SubpacketValue::IssuerFingerprint(fpr), false).unwrap()).unwrap();
1889         hashed.add(Subpacket::new(SubpacketValue::SignatureCreationTime(ctime), false).unwrap()).unwrap();
1890         unhashed.add(Subpacket::new(SubpacketValue::Issuer(kid), false).unwrap()).unwrap();
1891 
1892         eprintln!("fpr: {}", key.fingerprint());
1893         let sig = Signature4::new(SignatureType::Binary, PublicKeyAlgorithm::EdDSA,
1894                                   HashAlgorithm::SHA256, hashed, unhashed,
1895                                   [0xa7,0x19],
1896                                   mpi::Signature::EdDSA{
1897                                       r: mpi::MPI::new(r), s: mpi::MPI::new(s)
1898                                   });
1899         let sig: Signature = sig.into();
1900         sig.verify_message(&key, b"Hello, World\n").unwrap();
1901     }
1902 
1903     #[test]
fingerprint_test()1904     fn fingerprint_test() {
1905         let pile =
1906             PacketPile::from_bytes(crate::tests::key("public-key.gpg")).unwrap();
1907 
1908         // The blob contains a public key and a three subkeys.
1909         let mut pki = 0;
1910         let mut ski = 0;
1911 
1912         let pks = [ "8F17 7771 18A3 3DDA 9BA4  8E62 AACB 3243 6300 52D9" ];
1913         let sks = [ "C03F A641 1B03 AE12 5764  6118 7223 B566 78E0 2528",
1914                     "50E6 D924 308D BF22 3CFB  510A C2B8 1905 6C65 2598",
1915                     "2DC5 0AB5 5BE2 F3B0 4C2D  2CF8 A350 6AFB 820A BD08"];
1916 
1917         for p in pile.descendants() {
1918             if let &Packet::PublicKey(ref p) = p {
1919                 let fp = p.fingerprint().to_string();
1920                 // eprintln!("PK: {:?}", fp);
1921 
1922                 assert!(pki < pks.len());
1923                 assert_eq!(fp, pks[pki]);
1924                 pki += 1;
1925             }
1926 
1927             if let &Packet::PublicSubkey(ref p) = p {
1928                 let fp = p.fingerprint().to_string();
1929                 // eprintln!("SK: {:?}", fp);
1930 
1931                 assert!(ski < sks.len());
1932                 assert_eq!(fp, sks[ski]);
1933                 ski += 1;
1934             }
1935         }
1936         assert!(pki == pks.len() && ski == sks.len());
1937     }
1938 
1939     #[test]
encrypt_huge_plaintext() -> Result<()>1940     fn encrypt_huge_plaintext() -> Result<()> {
1941         let sk = crate::crypto::SessionKey::new(256);
1942         let rsa2k: Key<SecretParts, UnspecifiedRole> =
1943             Key4::generate_rsa(2048)?.into();
1944         assert!(destructures_to!(
1945             crate::Error::InvalidArgument(_) =
1946                 rsa2k.encrypt(&sk).unwrap_err().downcast().unwrap()));
1947 
1948         let cv25519: Key<SecretParts, UnspecifiedRole> =
1949             Key4::generate_ecc(false, Curve::Cv25519)?.into();
1950         assert!(destructures_to!(
1951             crate::Error::InvalidArgument(_) =
1952                 cv25519.encrypt(&sk).unwrap_err().downcast().unwrap()));
1953 
1954         Ok(())
1955     }
1956 }
1957