sequoia_openpgp/cert/
builder.rs

1use std::time;
2use std::marker::PhantomData;
3
4use crate::packet;
5use crate::packet::{
6    Key,
7    key::Key4,
8    key::Key6,
9    key::UnspecifiedRole,
10    key::SecretKey as KeySecretKey,
11    key::SecretParts as KeySecretParts,
12};
13use crate::Profile;
14use crate::Result;
15use crate::packet::Signature;
16use crate::packet::signature::{
17    self,
18    SignatureBuilder,
19    subpacket::SubpacketTag,
20};
21use crate::cert::prelude::*;
22use crate::Error;
23use crate::crypto::{Password, Signer};
24use crate::types::{
25    Features,
26    HashAlgorithm,
27    KeyFlags,
28    SignatureType,
29    SymmetricAlgorithm,
30    RevocationKey,
31};
32
33mod key;
34pub use key::{
35    KeyBuilder,
36    SubkeyBuilder,
37};
38
39/// Groups symmetric and asymmetric algorithms.
40///
41/// This is used to select a suite of ciphers.
42///
43/// # Examples
44///
45/// ```
46/// use sequoia_openpgp as openpgp;
47/// use openpgp::cert::prelude::*;
48/// use openpgp::types::PublicKeyAlgorithm;
49///
50/// # fn main() -> openpgp::Result<()> {
51/// let (ecc, _) =
52///     CertBuilder::general_purpose(Some("alice@example.org"))
53///         .set_cipher_suite(CipherSuite::Cv25519)
54///         .generate()?;
55/// assert_eq!(ecc.primary_key().key().pk_algo(), PublicKeyAlgorithm::EdDSA);
56///
57/// let (rsa, _) =
58///     CertBuilder::general_purpose(Some("alice@example.org"))
59///         .set_cipher_suite(CipherSuite::RSA4k)
60///         .generate()?;
61/// assert_eq!(rsa.primary_key().key().pk_algo(), PublicKeyAlgorithm::RSAEncryptSign);
62/// # Ok(())
63/// # }
64/// ```
65#[derive(Clone, Copy, PartialEq, Eq, Debug)]
66#[non_exhaustive]
67pub enum CipherSuite {
68    /// EdDSA and ECDH over Curve25519 with SHA512 and AES256
69    Cv25519,
70    /// 3072 bit RSA with SHA512 and AES256
71    RSA3k,
72    /// EdDSA and ECDH over NIST P-256 with SHA256 and AES256
73    P256,
74    /// EdDSA and ECDH over NIST P-384 with SHA384 and AES256
75    P384,
76    /// EdDSA and ECDH over NIST P-521 with SHA512 and AES256
77    P521,
78    /// 2048 bit RSA with SHA512 and AES256
79    RSA2k,
80    /// 4096 bit RSA with SHA512 and AES256
81    RSA4k,
82
83    // If you add a variant here, be sure to update
84    // CipherSuite::variants below.
85}
86assert_send_and_sync!(CipherSuite);
87
88impl Default for CipherSuite {
89    fn default() -> Self {
90        CipherSuite::Cv25519
91    }
92}
93
94impl CipherSuite {
95    /// Returns an iterator over `CipherSuite`'s  variants.
96    pub fn variants() -> impl Iterator<Item=CipherSuite> {
97        use CipherSuite::*;
98
99        [ Cv25519, RSA3k, P256, P384, P521, RSA2k, RSA4k ]
100            .into_iter()
101    }
102
103    /// Returns whether the currently selected cryptographic backend
104    /// supports the encryption and signing algorithms that the cipher
105    /// suite selects.
106    pub fn is_supported(&self) -> Result<()> {
107        use crate::types::{Curve, PublicKeyAlgorithm};
108        use CipherSuite::*;
109
110        macro_rules! check_pk {
111            ($pk: expr) => {
112                if ! $pk.is_supported() {
113                    return Err(Error::UnsupportedPublicKeyAlgorithm($pk)
114                               .into());
115                }
116            }
117        }
118
119        macro_rules! check_curve {
120            ($curve: expr) => {
121                if ! $curve.is_supported() {
122                    return Err(Error::UnsupportedEllipticCurve($curve)
123                               .into());
124                }
125            }
126        }
127
128        match self {
129            Cv25519 => {
130                check_pk!(PublicKeyAlgorithm::EdDSA);
131                check_curve!(Curve::Ed25519);
132                check_pk!(PublicKeyAlgorithm::ECDH);
133                check_curve!(Curve::Cv25519);
134            },
135            RSA2k | RSA3k | RSA4k => {
136                check_pk!(PublicKeyAlgorithm::RSAEncryptSign);
137            },
138            P256 => {
139                check_pk!(PublicKeyAlgorithm::ECDSA);
140                check_curve!(Curve::NistP256);
141                check_pk!(PublicKeyAlgorithm::ECDH);
142            },
143            P384 => {
144                check_pk!(PublicKeyAlgorithm::ECDSA);
145                check_curve!(Curve::NistP384);
146                check_pk!(PublicKeyAlgorithm::ECDH);
147            },
148            P521 => {
149                check_pk!(PublicKeyAlgorithm::ECDSA);
150                check_curve!(Curve::NistP521);
151                check_pk!(PublicKeyAlgorithm::ECDH);
152            },
153        }
154        Ok(())
155    }
156
157    fn generate_key<K>(self, flags: K, profile: Profile)
158        -> Result<Key<KeySecretParts, UnspecifiedRole>>
159        where K: AsRef<KeyFlags>,
160    {
161        match profile {
162            Profile::RFC9580 => Ok(self.generate_v6_key(flags)?.into()),
163            Profile::RFC4880 => Ok(self.generate_v4_key(flags)?.into()),
164        }
165    }
166
167    fn generate_v4_key<K>(self, flags: K)
168        -> Result<Key4<KeySecretParts, UnspecifiedRole>>
169        where K: AsRef<KeyFlags>,
170    {
171        use crate::types::Curve;
172
173        match self {
174            CipherSuite::RSA2k =>
175                Key4::generate_rsa(2048),
176            CipherSuite::RSA3k =>
177                Key4::generate_rsa(3072),
178            CipherSuite::RSA4k =>
179                Key4::generate_rsa(4096),
180            CipherSuite::Cv25519 | CipherSuite::P256 |
181            CipherSuite::P384 | CipherSuite::P521 => {
182                let flags = flags.as_ref();
183                let sign = flags.for_certification() || flags.for_signing()
184                    || flags.for_authentication();
185                let encrypt = flags.for_transport_encryption()
186                    || flags.for_storage_encryption();
187                let curve = match self {
188                    CipherSuite::Cv25519 if sign => Curve::Ed25519,
189                    CipherSuite::Cv25519 if encrypt => Curve::Cv25519,
190                    CipherSuite::Cv25519 => {
191                        return Err(Error::InvalidOperation(
192                            "No key flags set".into())
193                            .into());
194                    }
195                    CipherSuite::P256 => Curve::NistP256,
196                    CipherSuite::P384 => Curve::NistP384,
197                    CipherSuite::P521 => Curve::NistP521,
198                    _ => unreachable!(),
199                };
200
201                match (sign, encrypt) {
202                    (true, false) => Key4::generate_ecc(true, curve),
203                    (false, true) => Key4::generate_ecc(false, curve),
204                    (true, true) =>
205                        Err(Error::InvalidOperation(
206                            "Can't use key for encryption and signing".into())
207                            .into()),
208                    (false, false) =>
209                        Err(Error::InvalidOperation(
210                            "No key flags set".into())
211                            .into()),
212                }
213            },
214        }
215    }
216
217    fn generate_v6_key<K>(self, flags: K)
218        -> Result<Key6<KeySecretParts, UnspecifiedRole>>
219        where K: AsRef<KeyFlags>,
220    {
221        use crate::types::Curve;
222
223        let flags = flags.as_ref();
224        let sign = flags.for_certification() || flags.for_signing()
225            || flags.for_authentication();
226        let encrypt = flags.for_transport_encryption()
227            || flags.for_storage_encryption();
228
229        match self {
230            CipherSuite::Cv25519 => match (sign, encrypt) {
231                (true, false) => Key6::generate_ed25519(),
232                (false, true) => Key6::generate_x25519(),
233                (true, true) =>
234                    Err(Error::InvalidOperation(
235                        "Can't use key for encryption and signing".into())
236                        .into()),
237                (false, false) =>
238                    Err(Error::InvalidOperation(
239                        "No key flags set".into())
240                        .into()),
241            },
242            CipherSuite::RSA2k =>
243                Key6::generate_rsa(2048),
244            CipherSuite::RSA3k =>
245                Key6::generate_rsa(3072),
246            CipherSuite::RSA4k =>
247                Key6::generate_rsa(4096),
248            CipherSuite::P256 | CipherSuite::P384 | CipherSuite::P521 => {
249                let curve = match self {
250                    CipherSuite::Cv25519 if sign => Curve::Ed25519,
251                    CipherSuite::Cv25519 if encrypt => Curve::Cv25519,
252                    CipherSuite::Cv25519 => {
253                        return Err(Error::InvalidOperation(
254                            "No key flags set".into())
255                            .into());
256                    }
257                    CipherSuite::P256 => Curve::NistP256,
258                    CipherSuite::P384 => Curve::NistP384,
259                    CipherSuite::P521 => Curve::NistP521,
260                    _ => unreachable!(),
261                };
262
263                match (sign, encrypt) {
264                    (true, false) => Key6::generate_ecc(true, curve),
265                    (false, true) => Key6::generate_ecc(false, curve),
266                    (true, true) =>
267                        Err(Error::InvalidOperation(
268                            "Can't use key for encryption and signing".into())
269                            .into()),
270                    (false, false) =>
271                        Err(Error::InvalidOperation(
272                            "No key flags set".into())
273                            .into()),
274                }
275            },
276        }
277    }
278}
279
280#[derive(Clone, Debug)]
281pub struct KeyBlueprint {
282    flags: KeyFlags,
283    validity: Option<time::Duration>,
284    // If not None, uses the specified ciphersuite.  Otherwise, uses
285    // CertBuilder::ciphersuite.
286    ciphersuite: Option<CipherSuite>,
287}
288assert_send_and_sync!(KeyBlueprint);
289
290/// Simplifies the generation of OpenPGP certificates.
291///
292/// A builder to generate complex certificate hierarchies with multiple
293/// [`UserID`s], [`UserAttribute`s], and [`Key`s].
294///
295/// This builder does not aim to be as flexible as creating
296/// certificates manually, but it should be sufficiently powerful to
297/// cover most use cases.
298///
299/// [`UserID`s]: crate::packet::UserID
300/// [`UserAttribute`s]: crate::packet::user_attribute::UserAttribute
301/// [`Key`s]: crate::packet::Key
302///
303/// # Security considerations
304///
305/// ## Expiration
306///
307/// There are two ways to invalidate cryptographic key material:
308/// revocation and freshness.  Both variants come with their own
309/// challenges.  Revocations rely on a robust channel to update
310/// certificates (and attackers may interfere with that).
311///
312/// On the other hand, freshness involves creating key material that
313/// expires after a certain time, then periodically extending the
314/// expiration time.  Again, consumers need a way to update
315/// certificates, but should that fail (maybe because it was
316/// interfered with), the consumer errs on the side of no longer
317/// trusting that key material.
318///
319/// Because of the way metadata is added to OpenPGP certificates,
320/// attackers who control the certificate lookup and update mechanism
321/// may strip components like signatures from the certificate.  This
322/// has implications for the robustness of relying on freshness.
323///
324/// If you first create a certificate that does not expire, and then
325/// change your mind and set an expiration time, an attacker can
326/// simply strip off that update, yielding the original certificate
327/// that does not expire.
328///
329/// Hence, to ensure robust key expiration, you must set an expiration
330/// with [`CertBuilder::set_validity_period`] when you create the
331/// certificate.
332///
333/// By default, the `CertBuilder` creates certificates that do not
334/// expire, because the expiration time is a policy decision and
335/// depends on the use case.  For general purpose certificates,
336/// [`CertBuilder::general_purpose`] sets the validity period to
337/// roughly three years.
338///
339/// # Examples
340///
341/// Generate a general-purpose certificate with one User ID:
342///
343/// ```
344/// use sequoia_openpgp as openpgp;
345/// use openpgp::cert::prelude::*;
346///
347/// # fn main() -> openpgp::Result<()> {
348/// let (cert, rev) =
349///     CertBuilder::general_purpose(Some("alice@example.org"))
350///         .generate()?;
351/// # Ok(())
352/// # }
353/// ```
354pub struct CertBuilder<'a> {
355    creation_time: Option<std::time::SystemTime>,
356    ciphersuite: CipherSuite,
357    profile: Profile,
358
359    /// Advertised features.
360    features: Features,
361    primary: KeyBlueprint,
362    subkeys: Vec<(Option<SignatureBuilder>, KeyBlueprint)>,
363    userids: Vec<(Option<SignatureBuilder>, packet::UserID)>,
364    user_attributes: Vec<(Option<SignatureBuilder>, packet::UserAttribute)>,
365    password: Option<Password>,
366    revocation_keys: Option<Vec<RevocationKey>>,
367    exportable: bool,
368    phantom: PhantomData<&'a ()>,
369}
370assert_send_and_sync!(CertBuilder<'_>);
371
372impl CertBuilder<'_> {
373    /// Returns a new `CertBuilder`.
374    ///
375    /// The returned builder is configured to generate a minimal
376    /// OpenPGP certificate, a certificate with just a
377    /// certification-capable primary key.  You'll typically want to
378    /// add at least one User ID (using
379    /// [`CertBuilder::add_userid`]). and some subkeys (using
380    /// [`CertBuilder::add_signing_subkey`],
381    /// [`CertBuilder::add_transport_encryption_subkey`], etc.).
382    ///
383    /// By default, the generated certificate does not expire.  It is
384    /// recommended to set a suitable validity period using
385    /// [`CertBuilder::set_validity_period`].  See [this
386    /// section](CertBuilder#expiration) of the type's documentation
387    /// for security considerations of key expiration.
388    ///
389    /// # Examples
390    ///
391    /// ```
392    /// use sequoia_openpgp as openpgp;
393    /// use openpgp::cert::prelude::*;
394    ///
395    /// # fn main() -> openpgp::Result<()> {
396    /// let (cert, rev) =
397    ///     CertBuilder::new()
398    ///         .add_userid("Alice Lovelace <alice@lovelace.name>")
399    ///         .add_signing_subkey()
400    ///         .add_transport_encryption_subkey()
401    ///         .add_storage_encryption_subkey()
402    ///         .generate()?;
403    /// # assert_eq!(cert.keys().count(), 1 + 3);
404    /// # assert_eq!(cert.userids().count(), 1);
405    /// # assert_eq!(cert.user_attributes().count(), 0);
406    /// # Ok(())
407    /// # }
408    /// ```
409    pub fn new() -> Self {
410        CertBuilder {
411            creation_time: None,
412            ciphersuite: CipherSuite::default(),
413            profile: Default::default(),
414            features: Features::sequoia(),
415            primary: KeyBlueprint{
416                flags: KeyFlags::empty().set_certification(),
417                validity: None,
418                ciphersuite: None,
419            },
420            subkeys: vec![],
421            userids: vec![],
422            user_attributes: vec![],
423            password: None,
424            revocation_keys: None,
425            exportable: true,
426            phantom: PhantomData,
427        }
428    }
429
430    /// Generates a general-purpose certificate.
431    ///
432    /// The returned builder is set to generate a certificate with a
433    /// certification-capable primary key, a signing-capable subkey,
434    /// and an encryption-capable subkey.  The encryption subkey is
435    /// marked as being appropriate for both data in transit and data
436    /// at rest.
437    ///
438    /// The certificate and all subkeys are valid for approximately
439    /// three years.
440    ///
441    /// # Examples
442    ///
443    /// ```
444    /// use sequoia_openpgp as openpgp;
445    /// use openpgp::cert::prelude::*;
446    ///
447    /// # fn main() -> openpgp::Result<()> {
448    /// let (cert, rev) =
449    ///     CertBuilder::general_purpose(["Alice Lovelace", "<alice@example.org>"])
450    ///         .generate()?;
451    /// # assert_eq!(cert.keys().count(), 3);
452    /// # assert_eq!(cert.userids().count(), 2);
453    ///
454    /// let (cert, rev) =
455    ///     CertBuilder::general_purpose(["Alice Lovelace <alice@example.org>"])
456    ///         .generate()?;
457    /// # assert_eq!(cert.keys().count(), 3);
458    /// # assert_eq!(cert.userids().count(), 1);
459    /// # Ok(())
460    /// # }
461    /// ```
462    pub fn general_purpose<U>(userids: U) -> Self
463    where
464        U: IntoIterator,
465        U::Item: Into<packet::UserID>,
466    {
467        let mut builder = Self::new()
468            .set_primary_key_flags(KeyFlags::empty().set_certification())
469            .set_validity_period(
470                time::Duration::new(3 * 52 * 7 * 24 * 60 * 60, 0))
471            .add_signing_subkey()
472            .add_subkey(KeyFlags::empty()
473                        .set_transport_encryption()
474                        .set_storage_encryption(), None, None);
475
476        for u in userids {
477            builder = builder.add_userid(u.into());
478        }
479
480        builder
481    }
482
483    /// Sets the creation time.
484    ///
485    /// If `creation_time` is not `None`, this causes the
486    /// `CertBuilder` to use that time when [`CertBuilder::generate`]
487    /// is called.  If it is `None`, the default, then the current
488    /// time minus 60 seconds is used as creation time.  Backdating
489    /// the certificate by a minute has the advantage that the
490    /// certificate can immediately be customized:
491    ///
492    /// In order to reliably override a binding signature, the
493    /// overriding binding signature must be newer than the existing
494    /// signature.  If, however, the existing signature is created
495    /// `now`, any newer signature must have a future creation time,
496    /// and is considered invalid by Sequoia.  To avoid this, we
497    /// backdate certificate creation times (and hence binding
498    /// signature creation times), so that there is "space" between
499    /// the creation time and now for signature updates.
500    ///
501    /// Warning: this function takes a [`SystemTime`].  A `SystemTime`
502    /// has a higher resolution, and a larger range than an OpenPGP
503    /// [`Timestamp`].  Assuming the `creation_time` is in range, it
504    /// will automatically be truncated to the nearest time that is
505    /// representable by a `Timestamp`.  If it is not in range,
506    /// [`generate`] will return an error.
507    ///
508    /// [`CertBuilder::generate`]: CertBuilder::generate()
509    /// [`SystemTime`]: std::time::SystemTime
510    /// [`Timestamp`]: crate::types::Timestamp
511    /// [`generate`]: CertBuilder::generate()
512    ///
513    /// # Examples
514    ///
515    /// Generate a backdated certificate:
516    ///
517    /// ```
518    /// use std::time::{SystemTime, Duration};
519    /// use std::convert::TryFrom;
520    ///
521    /// use sequoia_openpgp as openpgp;
522    /// use openpgp::cert::prelude::*;
523    /// use openpgp::types::Timestamp;
524    ///
525    /// # fn main() -> openpgp::Result<()> {
526    /// let t = SystemTime::now() - Duration::from_secs(365 * 24 * 60 * 60);
527    /// // Roundtrip the time so that the assert below works.
528    /// let t = SystemTime::from(Timestamp::try_from(t)?);
529    ///
530    /// let (cert, rev) =
531    ///     CertBuilder::general_purpose(Some("Alice Lovelace <alice@example.org>"))
532    ///         .set_creation_time(t)
533    ///         .generate()?;
534    /// assert_eq!(cert.primary_key().self_signatures().nth(0).unwrap()
535    ///            .signature_creation_time(),
536    ///            Some(t));
537    /// # Ok(())
538    /// # }
539    /// ```
540    pub fn set_creation_time<T>(mut self, creation_time: T) -> Self
541        where T: Into<Option<std::time::SystemTime>>,
542    {
543        self.creation_time = creation_time.into();
544        self
545    }
546
547    /// Returns the configured creation time, if any.
548    ///
549    /// # Examples
550    ///
551    /// ```
552    /// use std::time::SystemTime;
553    ///
554    /// use sequoia_openpgp as openpgp;
555    /// use openpgp::cert::prelude::*;
556    ///
557    /// # fn main() -> openpgp::Result<()> {
558    /// let mut builder = CertBuilder::new();
559    /// assert!(builder.creation_time().is_none());
560    ///
561    /// let now = std::time::SystemTime::now();
562    /// builder = builder.set_creation_time(Some(now));
563    /// assert_eq!(builder.creation_time(), Some(now));
564    ///
565    /// builder = builder.set_creation_time(None);
566    /// assert!(builder.creation_time().is_none());
567    /// # Ok(())
568    /// # }
569    /// ```
570    pub fn creation_time(&self) -> Option<std::time::SystemTime>
571    {
572        self.creation_time
573    }
574
575    /// Sets the default asymmetric algorithms.
576    ///
577    /// This method controls the set of algorithms that is used to
578    /// generate the certificate's keys.
579    ///
580    /// # Examples
581    ///
582    /// ```
583    /// use sequoia_openpgp as openpgp;
584    /// use openpgp::cert::prelude::*;
585    /// use openpgp::types::PublicKeyAlgorithm;
586    ///
587    /// # fn main() -> openpgp::Result<()> {
588    /// let (ecc, _) =
589    ///     CertBuilder::general_purpose(Some("alice@example.org"))
590    ///         .set_cipher_suite(CipherSuite::Cv25519)
591    ///         .generate()?;
592    /// assert_eq!(ecc.primary_key().key().pk_algo(), PublicKeyAlgorithm::EdDSA);
593    ///
594    /// let (rsa, _) =
595    ///     CertBuilder::general_purpose(Some("alice@example.org"))
596    ///         .set_cipher_suite(CipherSuite::RSA2k)
597    ///         .generate()?;
598    /// assert_eq!(rsa.primary_key().key().pk_algo(), PublicKeyAlgorithm::RSAEncryptSign);
599    /// # Ok(())
600    /// # }
601    /// ```
602    pub fn set_cipher_suite(mut self, cs: CipherSuite) -> Self {
603        self.ciphersuite = cs;
604        self
605    }
606
607    /// Sets whether the certificate is exportable.
608    ///
609    /// This method controls whether the certificate is exportable.
610    /// If the certificate builder is configured to make a
611    /// non-exportable certificate, then all the signatures that it
612    /// creates include the [Exportable Certification] subpacket
613    /// that is set to `false`.
614    ///
615    /// [Exportable Certification]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.19
616    ///
617    /// # Examples
618    ///
619    /// When exporting a non-exportable certificate, nothing will be
620    /// exported.  This is also the case when the output is ASCII
621    /// armored.
622    ///
623    /// ```
624    /// use sequoia_openpgp as openpgp;
625    /// use openpgp::Result;
626    /// use openpgp::cert::prelude::*;
627    /// use openpgp::parse::Parse;
628    /// use openpgp::serialize::Serialize;
629    ///
630    /// # fn main() -> openpgp::Result<()> {
631    /// let (cert, _) =
632    ///     CertBuilder::general_purpose(Some("alice@example.org"))
633    ///         .set_exportable(false)
634    ///         .generate()?;
635    /// let mut exported = Vec::new();
636    /// cert.armored().export(&mut exported)?;
637    ///
638    /// let certs = CertParser::from_bytes(&exported)?
639    ///     .collect::<Result<Vec<Cert>>>()?;
640    /// assert_eq!(certs.len(), 0);
641    /// assert_eq!(exported.len(), 0, "{}", String::from_utf8_lossy(&exported));
642    /// # Ok(())
643    /// # }
644    /// ```
645    pub fn set_exportable(mut self, exportable: bool) -> Self {
646        self.exportable = exportable;
647        self
648    }
649
650    /// Sets the version of OpenPGP to generate keys for.
651    ///
652    /// Supported are [`Profile::RFC9580`] which will generate version
653    /// 6 keys, and [`Profile::RFC4880`] which will version 4 keys.
654    /// By default, we generate version 6 keys.
655    ///
656    /// # Examples
657    ///
658    /// ```
659    /// use sequoia_openpgp as openpgp;
660    /// use openpgp::cert::prelude::*;
661    ///
662    /// # fn main() -> openpgp::Result<()> {
663    /// let (key, _) =
664    ///     CertBuilder::general_purpose(Some("alice@example.org"))
665    ///         .set_profile(openpgp::Profile::RFC9580)?
666    ///         .generate()?;
667    /// assert_eq!(key.primary_key().key().version(), 6);
668    ///
669    /// let (key, _) =
670    ///     CertBuilder::general_purpose(Some("bob@example.org"))
671    ///         .set_profile(openpgp::Profile::RFC4880)?
672    ///         .generate()?;
673    /// assert_eq!(key.primary_key().key().version(), 4);
674    /// # Ok(())
675    /// # }
676    /// ```
677    pub fn set_profile(mut self, profile: Profile) -> Result<Self> {
678        self.profile = profile;
679        Ok(self)
680    }
681
682    /// Sets the features the certificate will advertise.
683    ///
684    /// # Examples
685    ///
686    /// ```
687    /// use sequoia_openpgp as openpgp;
688    /// use openpgp::cert::prelude::*;
689    /// use openpgp::types::Features;
690    ///
691    /// # fn main() -> openpgp::Result<()> {
692    /// let (key, _) =
693    ///     CertBuilder::general_purpose(Some("alice@example.org"))
694    ///         .set_profile(openpgp::Profile::RFC9580)?
695    ///         .generate()?;
696    /// assert_eq!(key.primary_key().key().version(), 6);
697    ///
698    /// // Bob is old-school: he needs this key to work on an old
699    /// // phone.  Therefore, he doesn't want to get SEIPDv2 messages,
700    /// // which his phone doesn't handle.  He advertises support for
701    /// // SEIPDv1 only.
702    /// let (key, _) =
703    ///     CertBuilder::general_purpose(Some("bob@example.org"))
704    ///         .set_profile(openpgp::Profile::RFC4880)?
705    ///         .set_features(Features::empty().set_seipdv1())?
706    ///         .generate()?;
707    /// assert_eq!(key.primary_key().key().version(), 4);
708    /// # Ok(())
709    /// # }
710    /// ```
711    pub fn set_features(mut self, features: Features) -> Result<Self> {
712        self.features = features;
713        Ok(self)
714    }
715
716    /// Adds a User ID.
717    ///
718    /// Adds a User ID to the certificate.  The first User ID that is
719    /// added, whether via this interface or another interface, e.g.,
720    /// [`CertBuilder::general_purpose`], will have the [primary User
721    /// ID flag] set.
722    ///
723    /// [`CertBuilder::general_purpose`]: CertBuilder::general_purpose()
724    /// [primary User ID flag]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.27
725    ///
726    /// # Examples
727    ///
728    /// ```
729    /// use sequoia_openpgp as openpgp;
730    /// use openpgp::cert::prelude::*;
731    /// use openpgp::packet::prelude::*;
732    /// use openpgp::policy::StandardPolicy;
733    ///
734    /// # fn main() -> openpgp::Result<()> {
735    /// let p = &StandardPolicy::new();
736    ///
737    /// let (cert, rev) =
738    ///     CertBuilder::general_purpose(Some("Alice Lovelace <alice@example.org>"))
739    ///         .add_userid("Alice Lovelace <alice@lovelace.name>")
740    ///         .generate()?;
741    ///
742    /// assert_eq!(cert.userids().count(), 2);
743    /// let mut userids = cert.with_policy(p, None)?.userids().collect::<Vec<_>>();
744    /// // Sort lexicographically.
745    /// userids.sort_by(|a, b| a.userid().value().cmp(b.userid().value()));
746    /// assert_eq!(userids[0].userid(),
747    ///            &UserID::from("Alice Lovelace <alice@example.org>"));
748    /// assert_eq!(userids[1].userid(),
749    ///            &UserID::from("Alice Lovelace <alice@lovelace.name>"));
750    ///
751    ///
752    /// assert_eq!(userids[0].binding_signature().primary_userid().unwrap_or(false), true);
753    /// assert_eq!(userids[1].binding_signature().primary_userid().unwrap_or(false), false);
754    /// # Ok(())
755    /// # }
756    /// ```
757    pub fn add_userid<U>(mut self, uid: U) -> Self
758        where U: Into<packet::UserID>
759    {
760        self.userids.push((None, uid.into()));
761        self
762    }
763
764    /// Adds a User ID with a binding signature based on `builder`.
765    ///
766    /// Adds a User ID to the certificate, creating the binding
767    /// signature using `builder`.  The `builder`s signature type must
768    /// be a certification signature (i.e. either
769    /// [`GenericCertification`], [`PersonaCertification`],
770    /// [`CasualCertification`], or [`PositiveCertification`]).
771    ///
772    /// The key generation step uses `builder` as a template, but
773    /// tweaks it so the signature is a valid binding signature.  If
774    /// you need more control, consider using
775    /// [`UserID::bind`](crate::packet::UserID::bind).
776    ///
777    /// The following modifications are performed on `builder`:
778    ///
779    ///   - An appropriate hash algorithm is selected.
780    ///
781    ///   - The creation time is set.
782    ///
783    ///   - Primary key metadata is added (key flags, key validity period).
784    ///
785    ///   - Certificate metadata is added (feature flags, algorithm
786    ///     preferences).
787    ///
788    ///   - The [`CertBuilder`] marks exactly one User ID or User
789    ///     Attribute as primary: The first one provided to
790    ///     [`CertBuilder::add_userid_with`] or
791    ///     [`CertBuilder::add_user_attribute_with`] (the UserID takes
792    ///     precedence) that is marked as primary, or the first User
793    ///     ID or User Attribute added to the [`CertBuilder`].
794    ///
795    ///   [`GenericCertification`]: crate::types::SignatureType::GenericCertification
796    ///   [`PersonaCertification`]: crate::types::SignatureType::PersonaCertification
797    ///   [`CasualCertification`]: crate::types::SignatureType::CasualCertification
798    ///   [`PositiveCertification`]: crate::types::SignatureType::PositiveCertification
799    ///   [primary User ID flag]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.27
800    ///
801    /// # Examples
802    ///
803    /// This example very casually binds a User ID to a certificate.
804    ///
805    /// ```
806    /// # fn main() -> sequoia_openpgp::Result<()> {
807    /// # use sequoia_openpgp as openpgp;
808    /// # use openpgp::cert::prelude::*;
809    /// # use openpgp::packet::{prelude::*, signature::subpacket::*};
810    /// # use openpgp::policy::StandardPolicy;
811    /// # use openpgp::types::*;
812    /// # let policy = &StandardPolicy::new();
813    /// #
814    /// let (cert, revocation_cert) =
815    ///     CertBuilder::general_purpose(
816    ///         Some("Alice Lovelace <alice@example.org>"))
817    ///     .add_userid_with(
818    ///         "trinity",
819    ///         SignatureBuilder::new(SignatureType::CasualCertification)
820    ///             .set_notation("rabbit@example.org", b"follow me",
821    ///                           NotationDataFlags::empty().set_human_readable(),
822    ///                           false)?)?
823    ///     .generate()?;
824    ///
825    /// assert_eq!(cert.userids().count(), 2);
826    /// let mut userids = cert.with_policy(policy, None)?.userids().collect::<Vec<_>>();
827    /// // Sort lexicographically.
828    /// userids.sort_by(|a, b| a.userid().value().cmp(b.userid().value()));
829    /// assert_eq!(userids[0].userid(),
830    ///            &UserID::from("Alice Lovelace <alice@example.org>"));
831    /// assert_eq!(userids[1].userid(),
832    ///            &UserID::from("trinity"));
833    ///
834    /// assert!(userids[0].binding_signature().primary_userid().unwrap_or(false));
835    /// assert!(! userids[1].binding_signature().primary_userid().unwrap_or(false));
836    /// assert_eq!(userids[1].binding_signature().notation("rabbit@example.org")
837    ///            .next().unwrap(), b"follow me");
838    /// # Ok(()) }
839    /// ```
840    pub fn add_userid_with<U, B>(mut self, uid: U, builder: B)
841                                 -> Result<Self>
842    where U: Into<packet::UserID>,
843          B: Into<SignatureBuilder>,
844    {
845        let builder = builder.into();
846        match builder.typ() {
847            SignatureType::GenericCertification
848                | SignatureType::PersonaCertification
849                | SignatureType::CasualCertification
850                | SignatureType::PositiveCertification =>
851            {
852                self.userids.push((Some(builder), uid.into()));
853                Ok(self)
854            },
855            t =>
856                Err(Error::InvalidArgument(format!(
857                    "Signature type is not a certification: {}", t)).into()),
858        }
859    }
860
861    /// Adds a new User Attribute.
862    ///
863    /// Adds a User Attribute to the certificate.  If there are no
864    /// User IDs, the first User attribute that is added, whether via
865    /// this interface or another interface, will have the [primary
866    /// User ID flag] set.
867    ///
868    /// [primary User ID flag]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.27
869    ///
870    /// # Examples
871    ///
872    /// When there are no User IDs, the first User Attribute has the
873    /// primary User ID flag set:
874    ///
875    /// ```
876    /// # use openpgp::packet::user_attribute::Subpacket;
877    /// use sequoia_openpgp as openpgp;
878    /// use openpgp::cert::prelude::*;
879    /// use openpgp::packet::prelude::*;
880    /// use openpgp::policy::StandardPolicy;
881    ///
882    /// # fn main() -> openpgp::Result<()> {
883    /// let p = &StandardPolicy::new();
884    /// #
885    /// # // Create some user attribute. Doctests do not pass cfg(test),
886    /// # // so UserAttribute::arbitrary is not available
887    /// # let sp = Subpacket::Unknown(7, vec![7; 7].into_boxed_slice());
888    /// # let user_attribute = UserAttribute::new(&[sp])?;
889    ///
890    /// let (cert, rev) =
891    ///     CertBuilder::new()
892    ///         .add_user_attribute(user_attribute)
893    ///         .generate()?;
894    ///
895    /// assert_eq!(cert.userids().count(), 0);
896    /// assert_eq!(cert.user_attributes().count(), 1);
897    /// let mut uas = cert.with_policy(p, None)?.user_attributes().collect::<Vec<_>>();
898    /// assert_eq!(uas[0].binding_signature().primary_userid().unwrap_or(false), true);
899    /// # Ok(())
900    /// # }
901    /// ```
902    ///
903    /// Where there are User IDs, then the primary User ID flag is not
904    /// set:
905    ///
906    /// ```
907    /// # use openpgp::packet::user_attribute::Subpacket;
908    /// use sequoia_openpgp as openpgp;
909    /// use openpgp::cert::prelude::*;
910    /// use openpgp::packet::prelude::*;
911    /// use openpgp::policy::StandardPolicy;
912    ///
913    /// # fn main() -> openpgp::Result<()> {
914    /// let p = &StandardPolicy::new();
915    /// #
916    /// # // Create some user attribute. Doctests do not pass cfg(test),
917    /// # // so UserAttribute::arbitrary is not available
918    /// # let sp = Subpacket::Unknown(7, vec![7; 7].into_boxed_slice());
919    /// # let user_attribute = UserAttribute::new(&[sp])?;
920    ///
921    /// let (cert, rev) =
922    ///     CertBuilder::new()
923    ///         .add_userid("alice@example.org")
924    ///         .add_user_attribute(user_attribute)
925    ///         .generate()?;
926    ///
927    /// assert_eq!(cert.userids().count(), 1);
928    /// assert_eq!(cert.user_attributes().count(), 1);
929    /// let mut uas = cert.with_policy(p, None)?.user_attributes().collect::<Vec<_>>();
930    /// assert_eq!(uas[0].binding_signature().primary_userid().unwrap_or(false), false);
931    /// # Ok(())
932    /// # }
933    /// ```
934    pub fn add_user_attribute<U>(mut self, ua: U) -> Self
935        where U: Into<packet::UserAttribute>
936    {
937        self.user_attributes.push((None, ua.into()));
938        self
939    }
940
941    /// Adds a User Attribute with a binding signature based on `builder`.
942    ///
943    /// Adds a User Attribute to the certificate, creating the binding
944    /// signature using `builder`.  The `builder`s signature type must
945    /// be a certification signature (i.e. either
946    /// [`GenericCertification`], [`PersonaCertification`],
947    /// [`CasualCertification`], or [`PositiveCertification`]).
948    ///
949    /// The key generation step uses `builder` as a template, but
950    /// tweaks it so the signature is a valid binding signature.  If
951    /// you need more control, consider using
952    /// [`UserAttribute::bind`](crate::packet::UserAttribute::bind).
953    ///
954    /// The following modifications are performed on `builder`:
955    ///
956    ///   - An appropriate hash algorithm is selected.
957    ///
958    ///   - The creation time is set.
959    ///
960    ///   - Primary key metadata is added (key flags, key validity period).
961    ///
962    ///   - Certificate metadata is added (feature flags, algorithm
963    ///     preferences).
964    ///
965    ///   - The [`CertBuilder`] marks exactly one User ID or User
966    ///     Attribute as primary: The first one provided to
967    ///     [`CertBuilder::add_userid_with`] or
968    ///     [`CertBuilder::add_user_attribute_with`] (the UserID takes
969    ///     precedence) that is marked as primary, or the first User
970    ///     ID or User Attribute added to the [`CertBuilder`].
971    ///
972    ///   [`GenericCertification`]: crate::types::SignatureType::GenericCertification
973    ///   [`PersonaCertification`]: crate::types::SignatureType::PersonaCertification
974    ///   [`CasualCertification`]: crate::types::SignatureType::CasualCertification
975    ///   [`PositiveCertification`]: crate::types::SignatureType::PositiveCertification
976    ///   [primary User ID flag]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.27
977    ///
978    /// # Examples
979    ///
980    /// This example very casually binds a user attribute to a
981    /// certificate.
982    ///
983    /// ```
984    /// # fn main() -> sequoia_openpgp::Result<()> {
985    /// # use sequoia_openpgp as openpgp;
986    /// # use openpgp::packet::user_attribute::Subpacket;
987    /// # use openpgp::cert::prelude::*;
988    /// # use openpgp::packet::{prelude::*, signature::subpacket::*};
989    /// # use openpgp::policy::StandardPolicy;
990    /// # use openpgp::types::*;
991    /// #
992    /// # let policy = &StandardPolicy::new();
993    /// #
994    /// # // Create some user attribute. Doctests do not pass cfg(test),
995    /// # // so UserAttribute::arbitrary is not available
996    /// # let user_attribute =
997    /// #   UserAttribute::new(&[Subpacket::Unknown(7, vec![7; 7].into())])?;
998    /// let (cert, revocation_cert) =
999    ///     CertBuilder::general_purpose(
1000    ///         Some("Alice Lovelace <alice@example.org>"))
1001    ///     .add_user_attribute_with(
1002    ///         user_attribute,
1003    ///         SignatureBuilder::new(SignatureType::CasualCertification)
1004    ///             .set_notation("rabbit@example.org", b"follow me",
1005    ///                           NotationDataFlags::empty().set_human_readable(),
1006    ///                           false)?)?
1007    ///     .generate()?;
1008    ///
1009    /// let uas = cert.with_policy(policy, None)?.user_attributes().collect::<Vec<_>>();
1010    /// assert_eq!(uas.len(), 1);
1011    /// assert!(! uas[0].binding_signature().primary_userid().unwrap_or(false));
1012    /// assert_eq!(uas[0].binding_signature().notation("rabbit@example.org")
1013    ///            .next().unwrap(), b"follow me");
1014    /// # Ok(()) }
1015    /// ```
1016    pub fn add_user_attribute_with<U, B>(mut self, ua: U, builder: B)
1017                                         -> Result<Self>
1018    where U: Into<packet::UserAttribute>,
1019          B: Into<SignatureBuilder>,
1020    {
1021        let builder = builder.into();
1022        match builder.typ() {
1023            SignatureType::GenericCertification
1024                | SignatureType::PersonaCertification
1025                | SignatureType::CasualCertification
1026                | SignatureType::PositiveCertification =>
1027            {
1028                self.user_attributes.push((Some(builder), ua.into()));
1029                Ok(self)
1030            },
1031            t =>
1032                Err(Error::InvalidArgument(format!(
1033                    "Signature type is not a certification: {}", t)).into()),
1034        }
1035    }
1036
1037    /// Adds a signing-capable subkey.
1038    ///
1039    /// The key uses the default cipher suite (see
1040    /// [`CertBuilder::set_cipher_suite`]), and is not set to expire.
1041    /// Use [`CertBuilder::add_subkey`] if you need to change these
1042    /// parameters.
1043    ///
1044    /// [`CertBuilder::set_cipher_suite`]: CertBuilder::set_cipher_suite()
1045    /// [`CertBuilder::add_subkey`]: CertBuilder::add_subkey()
1046    ///
1047    /// # Examples
1048    ///
1049    /// ```
1050    /// use sequoia_openpgp as openpgp;
1051    /// use openpgp::cert::prelude::*;
1052    /// use openpgp::policy::StandardPolicy;
1053    /// use openpgp::types::KeyFlags;
1054    ///
1055    /// # fn main() -> openpgp::Result<()> {
1056    /// let p = &StandardPolicy::new();
1057    ///
1058    /// let (cert, rev) =
1059    ///     CertBuilder::new()
1060    ///         .add_signing_subkey()
1061    ///         .generate()?;
1062    ///
1063    /// assert_eq!(cert.keys().count(), 2);
1064    /// let ka = cert.with_policy(p, None)?.keys().nth(1).unwrap();
1065    /// assert_eq!(ka.key_flags(),
1066    ///            Some(KeyFlags::empty().set_signing()));
1067    /// # Ok(())
1068    /// # }
1069    /// ```
1070    pub fn add_signing_subkey(self) -> Self {
1071        self.add_subkey(KeyFlags::empty().set_signing(), None, None)
1072    }
1073
1074    /// Adds a subkey suitable for transport encryption.
1075    ///
1076    /// The key uses the default cipher suite (see
1077    /// [`CertBuilder::set_cipher_suite`]), and is not set to expire.
1078    /// Use [`CertBuilder::add_subkey`] if you need to change these
1079    /// parameters.
1080    ///
1081    /// [`CertBuilder::set_cipher_suite`]: CertBuilder::set_cipher_suite()
1082    /// [`CertBuilder::add_subkey`]: CertBuilder::add_subkey()
1083    ///
1084    ///
1085    /// # Examples
1086    ///
1087    /// ```
1088    /// use sequoia_openpgp as openpgp;
1089    /// use openpgp::cert::prelude::*;
1090    /// use openpgp::policy::StandardPolicy;
1091    /// use openpgp::types::KeyFlags;
1092    ///
1093    /// # fn main() -> openpgp::Result<()> {
1094    /// let p = &StandardPolicy::new();
1095    ///
1096    /// let (cert, rev) =
1097    ///     CertBuilder::new()
1098    ///         .add_transport_encryption_subkey()
1099    ///         .generate()?;
1100    ///
1101    /// assert_eq!(cert.keys().count(), 2);
1102    /// let ka = cert.with_policy(p, None)?.keys().nth(1).unwrap();
1103    /// assert_eq!(ka.key_flags(),
1104    ///            Some(KeyFlags::empty().set_transport_encryption()));
1105    /// # Ok(())
1106    /// # }
1107    /// ```
1108    pub fn add_transport_encryption_subkey(self) -> Self {
1109        self.add_subkey(KeyFlags::empty().set_transport_encryption(),
1110                        None, None)
1111    }
1112
1113    /// Adds a subkey suitable for storage encryption.
1114    ///
1115    /// The key uses the default cipher suite (see
1116    /// [`CertBuilder::set_cipher_suite`]), and is not set to expire.
1117    /// Use [`CertBuilder::add_subkey`] if you need to change these
1118    /// parameters.
1119    ///
1120    /// [`CertBuilder::set_cipher_suite`]: CertBuilder::set_cipher_suite()
1121    /// [`CertBuilder::add_subkey`]: CertBuilder::add_subkey()
1122    ///
1123    ///
1124    /// # Examples
1125    ///
1126    /// ```
1127    /// use sequoia_openpgp as openpgp;
1128    /// use openpgp::cert::prelude::*;
1129    /// use openpgp::policy::StandardPolicy;
1130    /// use openpgp::types::KeyFlags;
1131    ///
1132    /// # fn main() -> openpgp::Result<()> {
1133    /// let p = &StandardPolicy::new();
1134    ///
1135    /// let (cert, rev) =
1136    ///     CertBuilder::new()
1137    ///         .add_storage_encryption_subkey()
1138    ///         .generate()?;
1139    ///
1140    /// assert_eq!(cert.keys().count(), 2);
1141    /// let ka = cert.with_policy(p, None)?.keys().nth(1).unwrap();
1142    /// assert_eq!(ka.key_flags(),
1143    ///            Some(KeyFlags::empty().set_storage_encryption()));
1144    /// # Ok(())
1145    /// # }
1146    /// ```
1147    pub fn add_storage_encryption_subkey(self) -> Self {
1148        self.add_subkey(KeyFlags::empty().set_storage_encryption(),
1149                        None, None)
1150    }
1151
1152    /// Adds a certification-capable subkey.
1153    ///
1154    /// The key uses the default cipher suite (see
1155    /// [`CertBuilder::set_cipher_suite`]), and is not set to expire.
1156    /// Use [`CertBuilder::add_subkey`] if you need to change these
1157    /// parameters.
1158    ///
1159    /// [`CertBuilder::set_cipher_suite`]: CertBuilder::set_cipher_suite()
1160    /// [`CertBuilder::add_subkey`]: CertBuilder::add_subkey()
1161    ///
1162    ///
1163    /// # Examples
1164    ///
1165    /// ```
1166    /// use sequoia_openpgp as openpgp;
1167    /// use openpgp::cert::prelude::*;
1168    /// use openpgp::policy::StandardPolicy;
1169    /// use openpgp::types::KeyFlags;
1170    ///
1171    /// # fn main() -> openpgp::Result<()> {
1172    /// let p = &StandardPolicy::new();
1173    ///
1174    /// let (cert, rev) =
1175    ///     CertBuilder::new()
1176    ///         .add_certification_subkey()
1177    ///         .generate()?;
1178    ///
1179    /// assert_eq!(cert.keys().count(), 2);
1180    /// let ka = cert.with_policy(p, None)?.keys().nth(1).unwrap();
1181    /// assert_eq!(ka.key_flags(),
1182    ///            Some(KeyFlags::empty().set_certification()));
1183    /// # Ok(())
1184    /// # }
1185    /// ```
1186    pub fn add_certification_subkey(self) -> Self {
1187        self.add_subkey(KeyFlags::empty().set_certification(), None, None)
1188    }
1189
1190    /// Adds an authentication-capable subkey.
1191    ///
1192    /// The key uses the default cipher suite (see
1193    /// [`CertBuilder::set_cipher_suite`]), and is not set to expire.
1194    /// Use [`CertBuilder::add_subkey`] if you need to change these
1195    /// parameters.
1196    ///
1197    /// [`CertBuilder::set_cipher_suite`]: CertBuilder::set_cipher_suite()
1198    /// [`CertBuilder::add_subkey`]: CertBuilder::add_subkey()
1199    ///
1200    ///
1201    /// # Examples
1202    ///
1203    /// ```
1204    /// use sequoia_openpgp as openpgp;
1205    /// use openpgp::cert::prelude::*;
1206    /// use openpgp::policy::StandardPolicy;
1207    /// use openpgp::types::KeyFlags;
1208    ///
1209    /// # fn main() -> openpgp::Result<()> {
1210    /// let p = &StandardPolicy::new();
1211    ///
1212    /// let (cert, rev) =
1213    ///     CertBuilder::new()
1214    ///         .add_authentication_subkey()
1215    ///         .generate()?;
1216    ///
1217    /// assert_eq!(cert.keys().count(), 2);
1218    /// let ka = cert.with_policy(p, None)?.keys().nth(1).unwrap();
1219    /// assert_eq!(ka.key_flags(),
1220    ///            Some(KeyFlags::empty().set_authentication()));
1221    /// # Ok(())
1222    /// # }
1223    /// ```
1224    pub fn add_authentication_subkey(self) -> Self {
1225        self.add_subkey(KeyFlags::empty().set_authentication(), None, None)
1226    }
1227
1228    /// Adds a custom subkey.
1229    ///
1230    /// If `validity` is `None`, the subkey will be valid for the same
1231    /// period as the primary key.
1232    ///
1233    /// Likewise, if `cs` is `None`, the same cipher suite is used as
1234    /// for the primary key.
1235    ///
1236    /// # Examples
1237    ///
1238    /// Generates a certificate with an encryption subkey that is for
1239    /// protecting *both* data in transit and data at rest, and
1240    /// expires at a different time from the primary key:
1241    ///
1242    /// ```
1243    /// use sequoia_openpgp as openpgp;
1244    /// # use openpgp::Result;
1245    /// use openpgp::cert::prelude::*;
1246    /// use openpgp::policy::StandardPolicy;
1247    /// use openpgp::types::KeyFlags;
1248    ///
1249    /// # fn main() -> Result<()> {
1250    /// let p = &StandardPolicy::new();
1251    ///
1252    /// let now = std::time::SystemTime::now();
1253    /// let y = std::time::Duration::new(365 * 24 * 60 * 60, 0);
1254    ///
1255    /// // Make the certificate expire in 2 years, and the subkey
1256    /// // expire in a year.
1257    /// let (cert,_) = CertBuilder::new()
1258    ///     .set_creation_time(now)
1259    ///     .set_validity_period(2 * y)
1260    ///     .add_subkey(KeyFlags::empty()
1261    ///                     .set_storage_encryption()
1262    ///                     .set_transport_encryption(),
1263    ///                 y,
1264    ///                 None)
1265    ///     .generate()?;
1266    ///
1267    /// assert_eq!(cert.with_policy(p, now)?.keys().alive().count(), 2);
1268    /// assert_eq!(cert.with_policy(p, now + y)?.keys().alive().count(), 1);
1269    /// assert_eq!(cert.with_policy(p, now + 2 * y)?.keys().alive().count(), 0);
1270    ///
1271    /// let ka = cert.with_policy(p, None)?.keys().nth(1).unwrap();
1272    /// assert_eq!(ka.key_flags(),
1273    ///            Some(KeyFlags::empty()
1274    ///                     .set_storage_encryption()
1275    ///                     .set_transport_encryption()));
1276    /// # Ok(()) }
1277    /// ```
1278    pub fn add_subkey<T, C>(mut self, flags: KeyFlags, validity: T, cs: C)
1279        -> Self
1280        where T: Into<Option<time::Duration>>,
1281              C: Into<Option<CipherSuite>>,
1282    {
1283        self.subkeys.push((None, KeyBlueprint {
1284            flags,
1285            validity: validity.into(),
1286            ciphersuite: cs.into(),
1287        }));
1288        self
1289    }
1290
1291    /// Adds a subkey with a binding signature based on `builder`.
1292    ///
1293    /// Adds a subkey to the certificate, creating the binding
1294    /// signature using `builder`.  The `builder`s signature type must
1295    /// be [`SubkeyBinding`].
1296    ///
1297    /// The key generation step uses `builder` as a template, but adds
1298    /// all subpackets that the signature needs to be a valid binding
1299    /// signature.  If you need more control, or want to adopt
1300    /// existing keys, consider using
1301    /// [`Key::bind`](crate::packet::Key::bind).
1302    ///
1303    /// The following modifications are performed on `builder`:
1304    ///
1305    ///   - An appropriate hash algorithm is selected.
1306    ///
1307    ///   - The creation time is set.
1308    ///
1309    ///   - Key metadata is added (key flags, key validity period).
1310    ///
1311    ///   [`SubkeyBinding`]: crate::types::SignatureType::SubkeyBinding
1312    ///
1313    /// If `validity` is `None`, the subkey will be valid for the same
1314    /// period as the primary key.
1315    ///
1316    /// # Examples
1317    ///
1318    /// This example binds a signing subkey to a certificate,
1319    /// restricting its use to authentication of software.
1320    ///
1321    /// ```
1322    /// # fn main() -> sequoia_openpgp::Result<()> {
1323    /// # use sequoia_openpgp as openpgp;
1324    /// # use openpgp::packet::user_attribute::Subpacket;
1325    /// # use openpgp::cert::prelude::*;
1326    /// # use openpgp::packet::{prelude::*, signature::subpacket::*};
1327    /// # use openpgp::policy::StandardPolicy;
1328    /// # use openpgp::types::*;
1329    /// let (cert, revocation_cert) =
1330    ///     CertBuilder::general_purpose(
1331    ///         Some("Alice Lovelace <alice@example.org>"))
1332    ///     .add_subkey_with(
1333    ///         KeyFlags::empty().set_signing(), None, None,
1334    ///         SignatureBuilder::new(SignatureType::SubkeyBinding)
1335    ///             // Add a critical notation!
1336    ///             .set_notation("code-signing@policy.example.org", b"",
1337    ///                           NotationDataFlags::empty(), true)?)?
1338    ///     .generate()?;
1339    ///
1340    /// // Under the standard policy, the additional signing subkey
1341    /// // is not bound.
1342    /// let p = StandardPolicy::new();
1343    /// assert_eq!(cert.with_policy(&p, None)?.keys().for_signing().count(), 1);
1344    ///
1345    /// // However, software implementing the notation see the additional
1346    /// // signing subkey.
1347    /// let mut p = StandardPolicy::new();
1348    /// p.good_critical_notations(&["code-signing@policy.example.org"]);
1349    /// assert_eq!(cert.with_policy(&p, None)?.keys().for_signing().count(), 2);
1350    /// # Ok(()) }
1351    /// ```
1352    pub fn add_subkey_with<T, C, B>(mut self, flags: KeyFlags, validity: T,
1353                                    cs: C, builder: B) -> Result<Self>
1354        where T: Into<Option<time::Duration>>,
1355              C: Into<Option<CipherSuite>>,
1356              B: Into<SignatureBuilder>,
1357    {
1358        let builder = builder.into();
1359        match builder.typ() {
1360            SignatureType::SubkeyBinding => {
1361                self.subkeys.push((Some(builder), KeyBlueprint {
1362                    flags,
1363                    validity: validity.into(),
1364                    ciphersuite: cs.into(),
1365                }));
1366                Ok(self)
1367            },
1368            t =>
1369                Err(Error::InvalidArgument(format!(
1370                    "Signature type is not a subkey binding: {}", t)).into()),
1371        }
1372    }
1373
1374    /// Sets the primary key's key flags.
1375    ///
1376    /// By default, the primary key is set to only be certification
1377    /// capable.  This allows the caller to set additional flags.
1378    ///
1379    /// # Examples
1380    ///
1381    /// Makes the primary key signing-capable but not
1382    /// certification-capable.
1383    ///
1384    /// ```
1385    /// use sequoia_openpgp as openpgp;
1386    /// # use openpgp::Result;
1387    /// use openpgp::cert::prelude::*;
1388    /// use openpgp::policy::StandardPolicy;
1389    /// use openpgp::types::KeyFlags;
1390    ///
1391    /// # fn main() -> Result<()> {
1392    /// let p = &StandardPolicy::new();
1393    ///
1394    /// let (cert, rev) =
1395    ///     CertBuilder::general_purpose(Some("Alice Lovelace <alice@example.org>"))
1396    ///         .set_primary_key_flags(KeyFlags::empty().set_signing())
1397    ///         .generate()?;
1398    ///
1399    /// // Observe that the primary key's certification capability is
1400    /// // set implicitly.
1401    /// assert_eq!(cert.with_policy(p, None)?.primary_key().key_flags(),
1402    ///            Some(KeyFlags::empty().set_signing()));
1403    /// # Ok(()) }
1404    /// ```
1405    pub fn set_primary_key_flags(mut self, flags: KeyFlags) -> Self {
1406        self.primary.flags = flags;
1407        self
1408    }
1409
1410    /// Sets a password to encrypt the secret keys with.
1411    ///
1412    /// The password is used to encrypt all secret key material.
1413    ///
1414    /// # Examples
1415    ///
1416    /// ```
1417    /// use sequoia_openpgp as openpgp;
1418    /// # use openpgp::Result;
1419    /// use openpgp::cert::prelude::*;
1420    ///
1421    /// # fn main() -> Result<()> {
1422    /// // Make the certificate expire in 10 minutes.
1423    /// let (cert, rev) =
1424    ///     CertBuilder::general_purpose(Some("Alice Lovelace <alice@example.org>"))
1425    ///         .set_password(Some("1234".into()))
1426    ///         .generate()?;
1427    ///
1428    /// for ka in cert.keys() {
1429    ///     assert!(ka.key().has_secret());
1430    /// }
1431    /// # Ok(()) }
1432    /// ```
1433    pub fn set_password(mut self, password: Option<Password>) -> Self {
1434        self.password = password;
1435        self
1436    }
1437
1438    /// Sets the certificate's validity period.
1439    ///
1440    /// The determines how long the certificate is valid.  That is,
1441    /// after the validity period, the certificate is considered to be
1442    /// expired.
1443    ///
1444    /// The validity period starts with the creation time (see
1445    /// [`CertBuilder::set_creation_time`]).
1446    ///
1447    /// A value of `None` means that the certificate never expires.
1448    ///
1449    /// See [this section](CertBuilder#expiration) of the type's
1450    /// documentation for security considerations of key expiration.
1451    ///
1452    /// # Examples
1453    ///
1454    /// ```
1455    /// use sequoia_openpgp as openpgp;
1456    /// # use openpgp::Result;
1457    /// use openpgp::cert::prelude::*;
1458    /// use openpgp::policy::StandardPolicy;
1459    /// use openpgp::types::RevocationKey;
1460    ///
1461    /// # fn main() -> Result<()> {
1462    /// let p = &StandardPolicy::new();
1463    ///
1464    /// let now = std::time::SystemTime::now();
1465    /// let s = std::time::Duration::new(1, 0);
1466    ///
1467    /// // Make the certificate expire in 10 minutes.
1468    /// let (cert,_) = CertBuilder::new()
1469    ///     .set_creation_time(now)
1470    ///     .set_validity_period(600 * s)
1471    ///     .generate()?;
1472    ///
1473    /// assert!(cert.with_policy(p, now)?.primary_key().alive().is_ok());
1474    /// assert!(cert.with_policy(p, now + 599 * s)?.primary_key().alive().is_ok());
1475    /// assert!(cert.with_policy(p, now + 600 * s)?.primary_key().alive().is_err());
1476    /// # Ok(()) }
1477    /// ```
1478    pub fn set_validity_period<T>(mut self, validity: T) -> Self
1479        where T: Into<Option<time::Duration>>
1480    {
1481        self.primary.validity = validity.into();
1482        self
1483    }
1484
1485    /// Sets designated revokers.
1486    ///
1487    /// Adds designated revokers to the primary key.  This allows the
1488    /// designated revoker to issue revocation certificates on behalf
1489    /// of the primary key.
1490    ///
1491    /// # Examples
1492    ///
1493    /// Make Alice a designated revoker for Bob:
1494    ///
1495    /// ```
1496    /// use sequoia_openpgp as openpgp;
1497    /// # use openpgp::Result;
1498    /// use openpgp::cert::prelude::*;
1499    /// use openpgp::policy::StandardPolicy;
1500    /// use openpgp::types::RevocationKey;
1501    ///
1502    /// # fn main() -> Result<()> {
1503    /// let p = &StandardPolicy::new();
1504    ///
1505    /// let (alice, _) =
1506    ///     CertBuilder::general_purpose(Some("alice@example.org"))
1507    ///         .generate()?;
1508    /// let (bob, _) =
1509    ///     CertBuilder::general_purpose(Some("bob@example.org"))
1510    ///         .set_revocation_keys(vec![(&alice).into()])
1511    ///         .generate()?;
1512    ///
1513    /// // Make sure Alice is listed as a designated revoker for Bob.
1514    /// assert_eq!(bob.revocation_keys(p).collect::<Vec<&RevocationKey>>(),
1515    ///            vec![&(&alice).into()]);
1516    /// # Ok(()) }
1517    /// ```
1518    pub fn set_revocation_keys(mut self, revocation_keys: Vec<RevocationKey>)
1519        -> Self
1520    {
1521        self.revocation_keys = Some(revocation_keys);
1522        self
1523    }
1524
1525    /// Generates a certificate.
1526    ///
1527    /// # Examples
1528    ///
1529    /// ```
1530    /// use sequoia_openpgp as openpgp;
1531    /// # use openpgp::Result;
1532    /// use openpgp::cert::prelude::*;
1533    /// use openpgp::policy::StandardPolicy;
1534    /// use openpgp::types::RevocationKey;
1535    ///
1536    /// # fn main() -> Result<()> {
1537    /// let p = &StandardPolicy::new();
1538    ///
1539    /// let (alice, _) =
1540    ///     CertBuilder::general_purpose(Some("alice@example.org"))
1541    ///         .generate()?;
1542    /// # Ok(()) }
1543    /// ```
1544    pub fn generate(mut self) -> Result<(Cert, Signature)> {
1545        use crate::Packet;
1546        use crate::types::ReasonForRevocation;
1547
1548        let creation_time =
1549            self.creation_time.unwrap_or_else(|| {
1550                use crate::packet::signature::SIG_BACKDATE_BY;
1551                crate::now() -
1552                    time::Duration::new(SIG_BACKDATE_BY, 0)
1553            });
1554
1555        // Generate & self-sign primary key.
1556        let (primary, sig, mut signer) = self.primary_key(creation_time)?;
1557
1558        // Construct a skeleton cert.  We need this to bind the new
1559        // components to.
1560        let cert = Cert::try_from(vec![
1561            Packet::SecretKey({
1562                let mut primary = primary.clone();
1563                if let Some(ref password) = self.password {
1564                    let (k, mut secret) = primary.take_secret();
1565                    secret.encrypt_in_place(&k, password)?;
1566                    primary = k.add_secret(secret).0;
1567                }
1568                primary
1569            }),
1570        ])?;
1571        // We will, however, collect any signatures and components in
1572        // a separate vector, and only add them in the end, so that we
1573        // canonicalize the new certificate just once.
1574        let mut acc = vec![
1575            Packet::from(sig),
1576        ];
1577
1578        // We want to mark exactly one User ID or Attribute as primary.
1579        // First, figure out whether one of the binding signature
1580        // templates have the primary flag set.
1581        let have_primary_user_thing = {
1582            let is_primary = |osig: &Option<SignatureBuilder>| -> bool {
1583                osig.as_ref().and_then(|s| s.primary_userid()).unwrap_or(false)
1584            };
1585
1586            self.userids.iter().map(|(s, _)| s).any(is_primary)
1587                || self.user_attributes.iter().map(|(s, _)| s).any(is_primary)
1588        };
1589        let mut emitted_primary_user_thing = false;
1590
1591        // Sign UserIDs.
1592        for (template, uid) in std::mem::take(&mut self.userids).into_iter() {
1593            let sig = template.unwrap_or_else(
1594                || SignatureBuilder::new(SignatureType::PositiveCertification));
1595            let sig = Self::signature_common(sig, creation_time,
1596                                             self.exportable)?;
1597            let mut sig = self.add_primary_key_metadata(sig)?;
1598
1599            // Make sure we mark exactly one User ID or Attribute as
1600            // primary.
1601            if emitted_primary_user_thing {
1602                sig = sig.modify_hashed_area(|mut a| {
1603                    a.remove_all(SubpacketTag::PrimaryUserID);
1604                    Ok(a)
1605                })?;
1606            } else if have_primary_user_thing {
1607                // Check if this is the first explicitly selected
1608                // user thing.
1609                emitted_primary_user_thing |=
1610                    sig.primary_userid().unwrap_or(false);
1611            } else {
1612                // Implicitly mark the first as primary.
1613                sig = sig.set_primary_userid(true)?;
1614                emitted_primary_user_thing = true;
1615            }
1616
1617            let signature = uid.bind(&mut signer, &cert, sig)?;
1618            acc.push(uid.into());
1619            acc.push(signature.into());
1620        }
1621
1622        // Sign UserAttributes.
1623        for (template, ua) in std::mem::take(&mut self.user_attributes) {
1624            let sig = template.unwrap_or_else(
1625                || SignatureBuilder::new(SignatureType::PositiveCertification));
1626            let sig = Self::signature_common(
1627                sig, creation_time, self.exportable)?;
1628            let mut sig = self.add_primary_key_metadata(sig)?;
1629
1630            // Make sure we mark exactly one User ID or Attribute as
1631            // primary.
1632            if emitted_primary_user_thing {
1633                sig = sig.modify_hashed_area(|mut a| {
1634                    a.remove_all(SubpacketTag::PrimaryUserID);
1635                    Ok(a)
1636                })?;
1637            } else if have_primary_user_thing {
1638                // Check if this is the first explicitly selected
1639                // user thing.
1640                emitted_primary_user_thing |=
1641                    sig.primary_userid().unwrap_or(false);
1642            } else {
1643                // Implicitly mark the first as primary.
1644                sig = sig.set_primary_userid(true)?;
1645                emitted_primary_user_thing = true;
1646            }
1647
1648            let signature = ua.bind(&mut signer, &cert, sig)?;
1649            acc.push(ua.into());
1650            acc.push(signature.into());
1651        }
1652
1653        // Sign subkeys.
1654        for (template, blueprint) in self.subkeys {
1655            let flags = &blueprint.flags;
1656            let mut subkey = blueprint.ciphersuite
1657                .unwrap_or(self.ciphersuite)
1658                .generate_key(flags, self.profile)?
1659                .role_into_subordinate();
1660            subkey.set_creation_time(creation_time)?;
1661
1662            let sig = template.unwrap_or_else(
1663                || SignatureBuilder::new(SignatureType::SubkeyBinding));
1664            let sig = Self::signature_common(
1665                sig, creation_time, self.exportable)?;
1666            let mut builder = sig
1667                .set_key_flags(flags.clone())?
1668                .set_key_validity_period(blueprint.validity.or(self.primary.validity))?;
1669
1670            if flags.for_certification() || flags.for_signing()
1671                || flags.for_authentication()
1672            {
1673                // We need to create a primary key binding signature.
1674                let mut subkey_signer = subkey.clone().into_keypair().unwrap();
1675                let backsig =
1676                    signature::SignatureBuilder::new(SignatureType::PrimaryKeyBinding)
1677                    .set_signature_creation_time(creation_time)?
1678                    // GnuPG wants at least a 512-bit hash for P521 keys.
1679                    .set_hash_algo(HashAlgorithm::SHA512)
1680                    .sign_primary_key_binding(&mut subkey_signer, &primary,
1681                                              &subkey)?;
1682                builder = builder.set_embedded_signature(backsig)?;
1683            }
1684
1685            let signature = subkey.bind(&mut signer, &cert, builder)?;
1686
1687            if let Some(ref password) = self.password {
1688                let (k, mut secret) = subkey.take_secret();
1689                secret.encrypt_in_place(&k, password)?;
1690                subkey = k.add_secret(secret).0;
1691            }
1692            acc.push(subkey.into());
1693            acc.push(signature.into());
1694        }
1695
1696        // Now add the new components and canonicalize once.
1697        let cert = cert.insert_packets(acc)?.0;
1698
1699        let revocation = CertRevocationBuilder::new()
1700            .set_signature_creation_time(creation_time)?
1701            .set_reason_for_revocation(
1702                ReasonForRevocation::Unspecified, b"Unspecified")?
1703            .build(&mut signer, &cert, None)?;
1704
1705        // keys generated by the builder are never invalid
1706        assert!(cert.bad.is_empty());
1707        assert!(cert.unknowns.is_empty());
1708
1709        Ok((cert, revocation))
1710    }
1711
1712    /// Creates the primary key and a direct key signature.
1713    fn primary_key(&self, creation_time: std::time::SystemTime)
1714        -> Result<(KeySecretKey, Signature, Box<dyn Signer>)>
1715    {
1716        let mut key = self.primary.ciphersuite
1717            .unwrap_or(self.ciphersuite)
1718            .generate_key(KeyFlags::empty().set_certification(),
1719                          self.profile)?
1720            .role_into_primary();
1721        key.set_creation_time(creation_time)?;
1722        let sig = SignatureBuilder::new(SignatureType::DirectKey);
1723        let sig = Self::signature_common(
1724            sig, creation_time, self.exportable)?;
1725        let mut sig = self.add_primary_key_metadata(sig)?;
1726
1727        if let Some(ref revocation_keys) = self.revocation_keys {
1728            for k in revocation_keys.into_iter().cloned() {
1729                sig = sig.add_revocation_key(k)?;
1730            }
1731        }
1732
1733        let mut signer = key.clone().into_keypair()
1734            .expect("key generated above has a secret");
1735        let sig = sig.sign_direct_key(&mut signer, key.parts_as_public())?;
1736
1737        Ok((key, sig, Box::new(signer)))
1738    }
1739
1740    /// Common settings for generated signatures.
1741    fn signature_common(builder: SignatureBuilder,
1742                        creation_time: time::SystemTime,
1743                        exportable: bool)
1744                        -> Result<SignatureBuilder>
1745    {
1746        let mut builder = builder
1747            // GnuPG wants at least a 512-bit hash for P521 keys.
1748            .set_hash_algo(HashAlgorithm::SHA512)
1749            .set_signature_creation_time(creation_time)?;
1750        if ! exportable {
1751            builder = builder.set_exportable_certification(false)?;
1752        }
1753        Ok(builder)
1754    }
1755
1756
1757    /// Adds primary key metadata to the signature.
1758    fn add_primary_key_metadata(&self,
1759                                builder: SignatureBuilder)
1760                                -> Result<SignatureBuilder>
1761    {
1762        builder
1763            .set_features(self.features.clone())?
1764            .set_key_flags(self.primary.flags.clone())?
1765            .set_key_validity_period(self.primary.validity)?
1766            .set_preferred_hash_algorithms(vec![
1767                HashAlgorithm::SHA512,
1768                HashAlgorithm::SHA256,
1769            ])?
1770            .set_preferred_symmetric_algorithms(vec![
1771                SymmetricAlgorithm::AES256,
1772                SymmetricAlgorithm::AES128,
1773            ])
1774    }
1775}
1776
1777#[cfg(test)]
1778mod tests {
1779    use std::str::FromStr;
1780
1781    use super::*;
1782    use crate::Fingerprint;
1783    use crate::packet::signature::subpacket::{SubpacketTag, SubpacketValue};
1784    use crate::types::PublicKeyAlgorithm;
1785    use crate::parse::Parse;
1786    use crate::policy::StandardPolicy as P;
1787    use crate::serialize::Serialize;
1788
1789    #[test]
1790    fn all_opts() {
1791        let p = &P::new();
1792
1793        let (cert, _) = CertBuilder::new()
1794            .set_cipher_suite(CipherSuite::Cv25519)
1795            .add_userid("test1@example.com")
1796            .add_userid("test2@example.com")
1797            .add_signing_subkey()
1798            .add_transport_encryption_subkey()
1799            .add_certification_subkey()
1800            .generate().unwrap();
1801
1802        let mut userids = cert.userids().with_policy(p, None)
1803            .map(|u| String::from_utf8_lossy(u.userid().value()).into_owned())
1804            .collect::<Vec<String>>();
1805        userids.sort();
1806
1807        assert_eq!(userids,
1808                   &[ "test1@example.com",
1809                      "test2@example.com",
1810                   ][..]);
1811        assert_eq!(cert.subkeys().count(), 3);
1812    }
1813
1814    #[test]
1815    fn direct_key_sig() {
1816        let p = &P::new();
1817
1818        let (cert, _) = CertBuilder::new()
1819            .set_cipher_suite(CipherSuite::Cv25519)
1820            .add_signing_subkey()
1821            .add_transport_encryption_subkey()
1822            .add_certification_subkey()
1823            .generate().unwrap();
1824
1825        assert_eq!(cert.userids().count(), 0);
1826        assert_eq!(cert.subkeys().count(), 3);
1827        let sig =
1828            cert.primary_key().with_policy(p, None).unwrap().binding_signature();
1829        assert_eq!(sig.typ(), crate::types::SignatureType::DirectKey);
1830        assert!(sig.features().unwrap().supports_seipdv1());
1831    }
1832
1833    #[test]
1834    fn setter() {
1835        let (cert1, _) = CertBuilder::new()
1836            .set_cipher_suite(CipherSuite::Cv25519)
1837            .set_cipher_suite(CipherSuite::RSA3k)
1838            .set_cipher_suite(CipherSuite::Cv25519)
1839            .generate().unwrap();
1840        assert_eq!(cert1.primary_key().key().pk_algo(), PublicKeyAlgorithm::EdDSA);
1841
1842        let (cert2, _) = CertBuilder::new()
1843            .set_cipher_suite(CipherSuite::RSA3k)
1844            .add_userid("test2@example.com")
1845            .add_transport_encryption_subkey()
1846            .generate().unwrap();
1847        assert_eq!(cert2.primary_key().key().pk_algo(),
1848                   PublicKeyAlgorithm::RSAEncryptSign);
1849        assert_eq!(cert2.subkeys().next().unwrap().key().pk_algo(),
1850                   PublicKeyAlgorithm::RSAEncryptSign);
1851    }
1852
1853    #[test]
1854    fn defaults() {
1855        let p = &P::new();
1856        let (cert1, _) = CertBuilder::new()
1857            .add_userid("test2@example.com")
1858            .generate().unwrap();
1859        assert_eq!(cert1.primary_key().key().pk_algo(),
1860                   PublicKeyAlgorithm::EdDSA);
1861        assert!(cert1.subkeys().next().is_none());
1862        assert!(cert1.with_policy(p, None).unwrap().primary_userid().unwrap()
1863                .binding_signature().features().unwrap().supports_seipdv1());
1864    }
1865
1866    #[test]
1867    fn not_always_certify() {
1868        let p = &P::new();
1869        let (cert1, _) = CertBuilder::new()
1870            .set_cipher_suite(CipherSuite::Cv25519)
1871            .set_primary_key_flags(KeyFlags::empty())
1872            .add_transport_encryption_subkey()
1873            .generate().unwrap();
1874        assert!(! cert1.primary_key().with_policy(p, None).unwrap().for_certification());
1875        assert_eq!(cert1.keys().subkeys().count(), 1);
1876    }
1877
1878    #[test]
1879    fn gen_wired_subkeys() {
1880        let (cert1, _) = CertBuilder::new()
1881            .set_cipher_suite(CipherSuite::Cv25519)
1882            .set_primary_key_flags(KeyFlags::empty())
1883            .add_subkey(KeyFlags::empty().set_certification(), None, None)
1884            .generate().unwrap();
1885        let sig_pkts = cert1.subkeys().next().unwrap().bundle()
1886            .self_signatures().next().unwrap().hashed_area();
1887
1888        match sig_pkts.subpacket(SubpacketTag::KeyFlags).unwrap().value() {
1889            SubpacketValue::KeyFlags(ref ks) => assert!(ks.for_certification()),
1890            v => panic!("Unexpected subpacket: {:?}", v),
1891        }
1892
1893        assert_eq!(cert1.subkeys().count(), 1);
1894    }
1895
1896    #[test]
1897    fn generate_revocation_certificate() {
1898        let p = &P::new();
1899        use crate::types::RevocationStatus;
1900        let (cert, revocation) = CertBuilder::new()
1901            .set_cipher_suite(CipherSuite::Cv25519)
1902            .generate().unwrap();
1903        assert_eq!(cert.revocation_status(p, None),
1904                   RevocationStatus::NotAsFarAsWeKnow);
1905
1906        let cert = cert.insert_packets(revocation.clone()).unwrap().0;
1907        assert_eq!(cert.revocation_status(p, None),
1908                   RevocationStatus::Revoked(vec![ &revocation ]));
1909    }
1910
1911    #[test]
1912    fn builder_roundtrip() {
1913        use std::convert::TryFrom;
1914
1915        let (cert,_) = CertBuilder::new()
1916            .set_cipher_suite(CipherSuite::Cv25519)
1917            .add_signing_subkey()
1918            .generate().unwrap();
1919        let pile = cert.clone().into_packet_pile().into_children().collect::<Vec<_>>();
1920        let exp = Cert::try_from(pile).unwrap();
1921
1922        assert_eq!(cert, exp);
1923    }
1924
1925    #[test]
1926    fn encrypted_secrets() {
1927        let (cert,_) = CertBuilder::new()
1928            .set_cipher_suite(CipherSuite::Cv25519)
1929            .set_password(Some(String::from("streng geheim").into()))
1930            .generate().unwrap();
1931        assert!(cert.primary_key().key().optional_secret().unwrap().is_encrypted());
1932    }
1933
1934    #[test]
1935    fn all_ciphersuites() {
1936        for cs in CipherSuite::variants()
1937            .into_iter().filter(|cs| cs.is_supported().is_ok())
1938        {
1939            assert!(CertBuilder::new()
1940                .set_cipher_suite(cs)
1941                .generate().is_ok());
1942        }
1943    }
1944
1945    #[test]
1946    fn validity_periods() {
1947        let p = &P::new();
1948
1949        let now = crate::now();
1950        let s = std::time::Duration::new(1, 0);
1951
1952        let (cert,_) = CertBuilder::new()
1953            .set_creation_time(now)
1954            .set_validity_period(600 * s)
1955            .add_subkey(KeyFlags::empty().set_signing(),
1956                        300 * s, None)
1957            .add_subkey(KeyFlags::empty().set_authentication(),
1958                        None, None)
1959            .generate().unwrap();
1960
1961        let key = cert.primary_key().key();
1962        let sig = &cert.primary_key().bundle().self_signatures().next().unwrap();
1963        assert!(sig.key_alive(key, now).is_ok());
1964        assert!(sig.key_alive(key, now + 590 * s).is_ok());
1965        assert!(! sig.key_alive(key, now + 610 * s).is_ok());
1966
1967        let ka = cert.keys().with_policy(p, now).alive().revoked(false)
1968            .for_signing().next().unwrap();
1969        assert!(ka.alive().is_ok());
1970        assert!(ka.clone().with_policy(p, now + 290 * s).unwrap().alive().is_ok());
1971        assert!(! ka.clone().with_policy(p, now + 310 * s).unwrap().alive().is_ok());
1972
1973        let ka = cert.keys().with_policy(p, now).alive().revoked(false)
1974            .for_authentication().next().unwrap();
1975        assert!(ka.alive().is_ok());
1976        assert!(ka.clone().with_policy(p, now + 590 * s).unwrap().alive().is_ok());
1977        assert!(! ka.clone().with_policy(p, now + 610 * s).unwrap().alive().is_ok());
1978    }
1979
1980    #[test]
1981    fn creation_time() {
1982        let p = &P::new();
1983
1984        use std::time::UNIX_EPOCH;
1985        let (cert, rev) = CertBuilder::new()
1986            .set_creation_time(UNIX_EPOCH)
1987            .set_cipher_suite(CipherSuite::Cv25519)
1988            .add_userid("foo")
1989            .add_signing_subkey()
1990            .generate().unwrap();
1991
1992        assert_eq!(cert.primary_key().key().creation_time(), UNIX_EPOCH);
1993        assert_eq!(cert.primary_key().with_policy(p, None).unwrap()
1994                   .binding_signature()
1995                   .signature_creation_time().unwrap(), UNIX_EPOCH);
1996        assert_eq!(cert.primary_key().with_policy(p, None).unwrap()
1997                   .direct_key_signature().unwrap()
1998                   .signature_creation_time().unwrap(), UNIX_EPOCH);
1999        assert_eq!(rev.signature_creation_time().unwrap(), UNIX_EPOCH);
2000
2001        // (Sub)Keys.
2002        assert_eq!(cert.keys().with_policy(p, None).count(), 2);
2003        for ka in cert.keys().with_policy(p, None) {
2004            assert_eq!(ka.key().creation_time(), UNIX_EPOCH);
2005            assert_eq!(ka.binding_signature()
2006                       .signature_creation_time().unwrap(), UNIX_EPOCH);
2007        }
2008
2009        // UserIDs.
2010        assert_eq!(cert.userids().count(), 1);
2011        for ui in cert.userids().with_policy(p, None) {
2012            assert_eq!(ui.binding_signature()
2013                       .signature_creation_time().unwrap(), UNIX_EPOCH);
2014        }
2015    }
2016
2017    #[test]
2018    fn designated_revokers() -> Result<()> {
2019        use std::collections::HashSet;
2020
2021        let p = &P::new();
2022
2023        let fpr1 = "C03F A641 1B03 AE12 5764  6118 7223 B566 78E0 2528";
2024        let fpr2 = "50E6 D924 308D BF22 3CFB  510A C2B8 1905 6C65 2598";
2025        let revokers = vec![
2026            RevocationKey::new(PublicKeyAlgorithm::RSAEncryptSign,
2027                               Fingerprint::from_str(fpr1)?,
2028                               false),
2029            RevocationKey::new(PublicKeyAlgorithm::ECDSA,
2030                               Fingerprint::from_str(fpr2)?,
2031                               false)
2032        ];
2033
2034        let (cert,_)
2035            = CertBuilder::general_purpose(Some("alice@example.org"))
2036            .set_revocation_keys(revokers.clone())
2037            .generate()?;
2038        let cert = cert.with_policy(p, None)?;
2039
2040        assert_eq!(cert.revocation_keys().collect::<HashSet<_>>(),
2041                   revokers.iter().collect::<HashSet<_>>());
2042
2043        // Do it again, with a key that has no User IDs.
2044        let (cert,_) = CertBuilder::new()
2045            .set_revocation_keys(revokers.clone())
2046            .generate()?;
2047        let cert = cert.with_policy(p, None)?;
2048        assert!(cert.primary_userid().is_err());
2049
2050        assert_eq!(cert.revocation_keys().collect::<HashSet<_>>(),
2051                   revokers.iter().collect::<HashSet<_>>());
2052
2053        // The designated revokers on all signatures should be
2054        // considered.
2055        let now = crate::types::Timestamp::now();
2056        let then = now.checked_add(crate::types::Duration::days(1)?).unwrap();
2057        let (cert,_) = CertBuilder::new()
2058            .set_revocation_keys(revokers.clone())
2059            .set_creation_time(now)
2060            .generate()?;
2061
2062        // Add a newer direct key signature.
2063        use crate::crypto::hash::Hash;
2064        let mut primary_signer =
2065            cert.primary_key().key().clone().parts_into_secret()?
2066            .into_keypair()?;
2067        let mut hash = HashAlgorithm::SHA512.context()?
2068            .for_signature(primary_signer.public().version());
2069        cert.primary_key().key().hash(&mut hash)?;
2070        let sig = signature::SignatureBuilder::new(SignatureType::DirectKey)
2071            .set_signature_creation_time(then)?
2072            .sign_hash(&mut primary_signer, hash)?;
2073        let cert = cert.insert_packets(sig)?.0;
2074
2075        assert!(cert.with_policy(p, then)?.primary_userid().is_err());
2076        assert_eq!(cert.revocation_keys(p).collect::<HashSet<_>>(),
2077                   revokers.iter().collect::<HashSet<_>>());
2078        Ok(())
2079    }
2080
2081    /// Checks that the builder emits exactly one user id or attribute
2082    /// marked as primary.
2083    #[test]
2084    fn primary_user_things() -> Result<()> {
2085        fn count_primary_user_things(c: Cert) -> usize {
2086            c.into_packets().map(|p| match p {
2087                Packet::Signature(s) if s.primary_userid().unwrap_or(false)
2088                    => 1,
2089                _ => 0,
2090            }).sum()
2091        }
2092
2093        use crate::packet::{prelude::*, user_attribute::Subpacket};
2094        let ua_foo =
2095            UserAttribute::new(&[Subpacket::Unknown(7, vec![7; 7].into())])?;
2096        let ua_bar =
2097            UserAttribute::new(&[Subpacket::Unknown(11, vec![11; 11].into())])?;
2098
2099        let p = &P::new();
2100        let positive = SignatureType::PositiveCertification;
2101
2102        let (c, _) = CertBuilder::new().generate()?;
2103        assert_eq!(count_primary_user_things(c), 0);
2104
2105        let (c, _) = CertBuilder::new()
2106            .add_userid("foo")
2107            .generate()?;
2108        assert_eq!(count_primary_user_things(c), 1);
2109
2110        let (c, _) = CertBuilder::new()
2111            .add_userid("foo")
2112            .add_userid("bar")
2113            .generate()?;
2114        assert_eq!(count_primary_user_things(c), 1);
2115
2116        let (c, _) = CertBuilder::new()
2117            .add_user_attribute(ua_foo.clone())
2118            .generate()?;
2119        assert_eq!(count_primary_user_things(c), 1);
2120
2121        let (c, _) = CertBuilder::new()
2122            .add_user_attribute(ua_foo.clone())
2123            .add_user_attribute(ua_bar.clone())
2124            .generate()?;
2125        assert_eq!(count_primary_user_things(c), 1);
2126
2127        let (c, _) = CertBuilder::new()
2128            .add_userid("foo")
2129            .add_user_attribute(ua_foo.clone())
2130            .generate()?;
2131        let vc = c.with_policy(p, None)?;
2132        assert_eq!(vc.primary_userid()?.binding_signature().primary_userid(),
2133                   Some(true));
2134        assert_eq!(vc.primary_user_attribute()?.binding_signature().primary_userid(),
2135                   None);
2136        assert_eq!(count_primary_user_things(c), 1);
2137
2138        let (c, _) = CertBuilder::new()
2139            .add_user_attribute(ua_foo.clone())
2140            .add_userid("foo")
2141            .generate()?;
2142        let vc = c.with_policy(p, None)?;
2143        assert_eq!(vc.primary_userid()?.binding_signature().primary_userid(),
2144                   Some(true));
2145        assert_eq!(vc.primary_user_attribute()?.binding_signature().primary_userid(),
2146                   None);
2147        assert_eq!(count_primary_user_things(c), 1);
2148
2149        let (c, _) = CertBuilder::new()
2150            .add_userid("foo")
2151            .add_userid_with(
2152                "buz",
2153                SignatureBuilder::new(positive).set_primary_userid(false)?)?
2154            .add_userid_with(
2155                "bar",
2156                SignatureBuilder::new(positive).set_primary_userid(true)?)?
2157            .add_userid_with(
2158                "baz",
2159                SignatureBuilder::new(positive).set_primary_userid(true)?)?
2160            .generate()?;
2161        let vc = c.with_policy(p, None)?;
2162        assert_eq!(vc.primary_userid()?.userid().value(), b"bar");
2163        assert_eq!(count_primary_user_things(c), 1);
2164
2165        Ok(())
2166    }
2167
2168    #[test]
2169    fn non_exportable_cert() -> Result<()> {
2170        // Make sure that when we export a non-exportable cert,
2171        // nothing is exported.
2172
2173        let (cert, _) =
2174            CertBuilder::general_purpose(Some("alice@example.org"))
2175            .set_exportable(false)
2176            .generate()?;
2177
2178        let (bob, _) =
2179            CertBuilder::general_purpose(Some("bob@example.org"))
2180            .generate()?;
2181
2182        // Have Bob certify Alice's primary User ID with an exportable
2183        // signature.  This shouldn't make Alice's certificate
2184        // exportable.
2185        let mut keypair = bob.primary_key().key().clone()
2186            .parts_into_secret()?.into_keypair()?;
2187        let certification = cert.userids().nth(0).unwrap()
2188            .userid()
2189            .certify(&mut keypair, &cert,
2190                     SignatureType::PositiveCertification,
2191                     None, None)?;
2192        let cert = cert.insert_packets(certification)?.0;
2193
2194        macro_rules! check {
2195            ($cert: expr, $export: ident, $expected: expr) => {
2196                let mut exported = Vec::new();
2197                $cert.$export(&mut exported)?;
2198
2199                let certs = CertParser::from_bytes(&exported)?
2200                    .collect::<Result<Vec<Cert>>>()?;
2201
2202                assert_eq!(certs.len(), $expected);
2203
2204                if $expected == 0 {
2205                    assert_eq!(exported.len(), 0,
2206                               "{}", String::from_utf8_lossy(&exported));
2207                } else {
2208                    assert!(exported.len() > 0);
2209                }
2210            }
2211        }
2212
2213        // Binary cert:
2214        check!(cert, export, 0);
2215        check!(cert, serialize, 1);
2216
2217        // Binary TSK:
2218        check!(cert.as_tsk(), export, 0);
2219        check!(cert.as_tsk(), serialize, 1);
2220
2221        // Armored cert:
2222        check!(cert.armored(), export, 0);
2223        check!(cert.armored(), serialize, 1);
2224
2225        // Armored TSK:
2226        check!(cert.as_tsk().armored(), export, 0);
2227        check!(cert.as_tsk().armored(), serialize, 1);
2228
2229        // Have Alice add an exportable self signature.  Now her
2230        // certificate should be exportable.
2231        let mut keypair = cert.primary_key().key().clone()
2232            .parts_into_secret()?.into_keypair()?;
2233        let certification = cert.userids().nth(0).unwrap()
2234            .userid()
2235            .certify(&mut keypair, &cert,
2236                     SignatureType::PositiveCertification,
2237                     None, None)?;
2238        let cert = cert.insert_packets(certification)?.0;
2239
2240        macro_rules! check {
2241            ($cert: expr, $export: ident, $expected: expr) => {
2242                let mut exported = Vec::new();
2243                $cert.$export(&mut exported)?;
2244
2245                let certs = CertParser::from_bytes(&exported)?
2246                    .collect::<Result<Vec<Cert>>>()?;
2247
2248                assert_eq!(certs.len(), $expected);
2249
2250                if $expected == 0 {
2251                    assert_eq!(exported.len(), 0,
2252                               "{}", String::from_utf8_lossy(&exported));
2253                } else {
2254                    assert!(exported.len() > 0);
2255                }
2256            }
2257        }
2258
2259        // Binary cert:
2260        check!(cert, export, 1);
2261        check!(cert, serialize, 1);
2262
2263        // Binary TSK:
2264        check!(cert.as_tsk(), export, 1);
2265        check!(cert.as_tsk(), serialize, 1);
2266
2267        // Armored cert:
2268        check!(cert.armored(), export, 1);
2269        check!(cert.armored(), serialize, 1);
2270
2271        // Armored TSK:
2272        check!(cert.as_tsk().armored(), export, 1);
2273        check!(cert.as_tsk().armored(), serialize, 1);
2274
2275        Ok(())
2276    }
2277}