summaryrefslogtreecommitdiffstats
path: root/openpgp/src/packet/signature
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-09-30 13:37:28 +0200
committerJustus Winter <justus@sequoia-pgp.org>2020-10-02 15:09:10 +0200
commit23cb4b184b8c710d5c54bd45dbad206d59ae36b3 (patch)
treeaf1ed73908e82f76faf4817e1383d97b45876622 /openpgp/src/packet/signature
parentb81204994ebd395b0229c0e7eaaa47b7a013ece9 (diff)
openpgp: Rename file.
Diffstat (limited to 'openpgp/src/packet/signature')
-rw-r--r--openpgp/src/packet/signature/mod.rs3054
1 files changed, 0 insertions, 3054 deletions
diff --git a/openpgp/src/packet/signature/mod.rs b/openpgp/src/packet/signature/mod.rs
deleted file mode 100644
index 626e85ee..00000000
--- a/openpgp/src/packet/signature/mod.rs
+++ /dev/null
@@ -1,3054 +0,0 @@
-//! Signature-related functionality.
-//!
-//! Signatures are one of the central data structures in OpenPGP.
-//! They are used to protect the integrity of both structured
-//! documents (e.g., timestamps) and unstructured documents (arbitrary
-//! byte sequences) as well as cryptographic data structures.
-//!
-//! The use of signatures to protect cryptographic data structures is
-//! central to making it easy to change an OpenPGP certificate.
-//! Consider how a certificate is initially authenticated. A user,
-//! say Alice, securely communicates her certificate's fingerprint to
-//! another user, say Bob. Alice might do this by personally handing
-//! Bob a business card with her fingerprint on it. When Bob is in
-//! front of his computer, he may then record that Alice uses the
-//! specified key. Technically, the fingerprint that he used only
-//! identifies the primary key: a fingerprint is the hash of the
-//! primary key; it does not say anything about any of the rest of the
-//! certificate---the subkeys, the User IDs, and the User Attributes.
-//! But, because these components are signed by the primary key, we
-//! know that the controller of the key intended that they be
-//! associated with the certificate. This mechanism makes it not only
-//! possible to add and revoke components, but also to change
-//! meta-data, such as a key's expiration time. If the fingerprint
-//! were instead computed over the whole OpenPGP certificate, then
-//! changing the certificate would result in a new fingerprint. In
-//! that case, the fingerprint could not be used as a long-term,
-//! unique, and stable identifier.
-//!
-//! Signatures are described in [Section 5.2 of RFC 4880].
-//!
-//! # Data Types
-//!
-//! The main signature-related data type is the [`Signature`] enum.
-//! This enum abstracts away the differences between the signature
-//! formats (the deprecated [version 3], the current [version 4], and
-//! the proposed [version 5] formats). Nevertheless some
-//! functionality remains format specific. For instance, version 4
-//! signatures introduced support for storing arbitrary key-value
-//! pairs (so-called [notations]).
-//!
-//! This version of Sequoia only supports version 4 signatures
-//! ([`Signature4`]). However, future versions may include limited
-//! support for version 3 signatures to allow working with archived
-//! messages, and we intend to add support for version 5 signatures
-//! once the new version of the specification has been finalized.
-//!
-//! When signing a document, a `Signature` is typically created
-//! indirectly by the [streaming `Signer`]. Similarly, a `Signature`
-//! packet is created as a side effect of parsing a signed message
-//! using the [`PacketParser`].
-//!
-//! The [`SigntaureBuilder`] can be used to create a binding
-//! signature, a certification, etc. The motivation for having a
-//! separate data structure for creating signatures is that it
-//! decreases the chance that a half-constructed signature is
-//! accidentally exported. When modifying an existing signature, you
-//! can use, for instance, `SignatureBuilder::from` to convert a
-//! `Signtaure` into a `SigntaureBuilder`:
-//!
-//! ```
-//! use sequoia_openpgp as openpgp;
-//! use openpgp::policy::StandardPolicy;
-//! # use openpgp::cert::prelude::*;
-//! # use openpgp::packet::prelude::*;
-//!
-//! # fn main() -> openpgp::Result<()> {
-//! let p = &StandardPolicy::new();
-//!
-//! # // Generate a new certificate. It has secret key material.
-//! # let (cert, _) = CertBuilder::new()
-//! # .generate()?;
-//! #
-//! // Create a new direct key signature using the current one as a template.
-//! let pk = cert.with_policy(p, None)?.primary_key();
-//! let sig = pk.direct_key_signature()?;
-//! let builder: SignatureBuilder = sig.clone().into();
-//! # Ok(())
-//! # }
-//! ```
-//!
-//! For version 4 signatures, attributes are set using so-called
-//! subpackets. Subpackets can be stored in two places: either in the
-//! so-called hashed area or in the so-called unhashed area. Whereas
-//! the hashed area's integrity is protected by the signature, the
-//! unhashed area is not. Because an attacker can modify the unhashed
-//! area without detection, the unhashed area should only be used for
-//! storing self-authenticating data, e.g., the issuer, or a back
-//! signature. It is also sometimes used for [hints].
-//! [`Signature::normalize`] removes unexpected subpackets from the
-//! unhashed area. However, due to a lack of context, it does not
-//! validate the remaining subpackets.
-//!
-//! In Sequoia, each subpacket area is represented by a
-//! [`SubpacketArea`] data structure. The two subpacket areas are
-//! unified by the [`SubpacketAreas`] data structure, which implements
-//! a reasonable policy for looking up subpackets. In particular, it
-//! prefers subpackets from the hashed subpacket area, and only
-//! consults the unhashed subpacket area for certain packets. See
-//! [its documentation] for details.
-//!
-//! [Section 5.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.2
-//! [`Signature`]: ../enum.Signature.html
-//! [version 3]: https://tools.ietf.org/html/rfc1991#section-5.2.2
-//! [version 4]: https://tools.ietf.org/html/rfc4880#section-5.2.3
-//! [version 5]: https://www.ietf.org/id/draft-ietf-openpgp-rfc4880bis-09.html#name-version-4-and-5-signature-p
-//! [notations]: https://tools.ietf.org/html/rfc4880#section-5.2.3.16
-//! [`Signature4`]: struct.Signature4.html
-//! [streaming `Signer`]: ../../serialize/stream/struct.Signer.html
-//! [`PacketParser`]: ../../parse/index.html
-//! [`SigntaureBuilder`]: struct.SignatureBuilder.html
-//! [hints]: https://tools.ietf.org/html/rfc4880#section-5.13
-//! [`Signature::normalize`]: ../enum.Signature.html#method.normalize
-//! [`SubpacketArea`]: subpacket/struct.SubpacketArea.html
-//! [`SubpacketAreas`]: subpacket/struct.SubpacketAreas.html
-//! [its documentation]: subpacket/struct.SubpacketAreas.html
-
-use std::cmp::Ordering;
-use std::fmt;
-use std::ops::{Deref, DerefMut};
-use std::time::SystemTime;
-
-#[cfg(test)]
-use quickcheck::{Arbitrary, Gen};
-
-use crate::Error;
-use crate::Result;
-use crate::crypto::{
- mpi,
- hash::{self, Hash},
- Signer,
-};
-use crate::HashAlgorithm;
-use crate::PublicKeyAlgorithm;
-use crate::SignatureType;
-use crate::packet::Signature;
-use crate::packet::{
- key,
- Key,
-};
-use crate::packet::UserID;
-use crate::packet::UserAttribute;
-use crate::Packet;
-use crate::packet;
-use crate::packet::signature::subpacket::{
- SubpacketArea,
- SubpacketAreas,
- SubpacketTag,
-};
-
-#[cfg(test)]
-/// Like quickcheck::Arbitrary, but bounded.
-trait ArbitraryBounded {
- /// Generates an arbitrary value, but only recurses if `depth >
- /// 0`.
- fn arbitrary_bounded<G: Gen>(g: &mut G, depth: usize) -> Self;
-}
-
-#[cfg(test)]
-/// Default depth when implementing Arbitrary using ArbitraryBounded.
-const DEFAULT_ARBITRARY_DEPTH: usize = 2;
-
-#[cfg(test)]
-macro_rules! impl_arbitrary_with_bound {
- ($typ:path) => {
- impl Arbitrary for $typ {
- fn arbitrary<G: Gen>(g: &mut G) -> Self {
- Self::arbitrary_bounded(
- g,
- crate::packet::signature::DEFAULT_ARBITRARY_DEPTH)
- }
- }
- }
-}
-
-pub mod subpacket;
-
-/// How many seconds to backdate signatures.
-///
-/// When creating certificates (more specifically, binding
-/// signatures), and when updating binding signatures (creating
-/// signatures from templates), we backdate the signatures by this
-/// amount if no creation time is explicitly given. Backdating the
-/// certificate by a minute has the advantage that the certificate can
-/// immediately be customized:
-///
-/// In order to reliably override a binding signature, the
-/// overriding binding signature must be newer than the existing
-/// signature. If, however, the existing signature is created
-/// `now`, any newer signature must have a future creation time,
-/// and is considered invalid by Sequoia. To avoid this, we
-/// backdate certificate creation times (and hence binding
-/// signature creation times), so that there is "space" between
-/// the creation time and now for signature updates.
-pub(crate) const SIG_BACKDATE_BY: u64 = 60;
-
-/// The data stored in a `Signature` packet.
-///
-/// This data structure contains exactly those fields that appear in a
-/// [`Signature` packet]. It is used by both the [`Signature4`] and
-/// the [`SignatureBuilder`] data structures, which include other
-/// auxiliary information. This data structure is public so that
-/// `Signature4` and `SignatureBuilder` can deref to it.
-///
-/// A `SignatureField` derefs to a [`SubpacketAreas`].
-///
-/// [`Signature`]: https://tools.ietf.org/html/rfc4880#section-5.2
-/// [`Signature4`]: struct.Signature4.html
-/// [`SignatureBuilder`]: struct.SignatureBuilder.html
-/// [`SubpacketAreas`]: subpacket/struct.SubpacketAreas.html
-#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
-pub struct SignatureFields {
- /// Version of the signature packet. Must be 4.
- version: u8,
- /// Type of signature.
- typ: SignatureType,
- /// Public-key algorithm used for this signature.
- pk_algo: PublicKeyAlgorithm,
- /// Hash algorithm used to compute the signature.
- hash_algo: HashAlgorithm,
- /// Subpackets.
- subpackets: SubpacketAreas,
-}
-
-#[cfg(test)]
-impl ArbitraryBounded for SignatureFields {
- fn arbitrary_bounded<G: Gen>(g: &mut G, depth: usize) -> Self {
- SignatureFields {
- // XXX: Make this more interesting once we dig other
- // versions.
- version: 4,
- typ: Arbitrary::arbitrary(g),
- pk_algo: PublicKeyAlgorithm::arbitrary_for_signing(g),
- hash_algo: Arbitrary::arbitrary(g),
- subpackets: ArbitraryBounded::arbitrary_bounded(g, depth),
- }
- }
-}
-
-#[cfg(test)]
-impl_arbitrary_with_bound!(SignatureFields);
-
-impl Deref for SignatureFields {
- type Target = SubpacketAreas;
-
- fn deref(&self) -> &Self::Target {
- &self.subpackets
- }
-}
-
-impl DerefMut for SignatureFields {
- fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.subpackets
- }
-}
-
-impl SignatureFields {
- /// Gets the version.
- pub fn version(&self) -> u8 {
- self.version
- }
-
- /// Gets the signature type.
- ///
- /// This function is called `typ` and not `type`, because `type`
- /// is a reserved word.
- pub fn typ(&self) -> SignatureType {
- self.typ
- }
-
- /// Gets the public key algorithm.
- ///
- /// This is `pub(crate)`, because it shouldn't be exported by
- /// `SignatureBuilder` where it is only set at the end.
- pub(crate) fn pk_algo(&self) -> PublicKeyAlgorithm {
- self.pk_algo
- }
-
- /// Gets the hash algorithm.
- pub fn hash_algo(&self) -> HashAlgorithm {
- self.hash_algo
- }
-}
-
-/// A Signature builder.
-///
-/// The `SignatureBuilder` is used to create [`Signature`]s. Although
-/// it can be used to generate a signature over a document (using
-/// [`SignatureBuilder::sign_message`]), it is usually better to use
-/// the [streaming `Signer`] for that.
-///
-/// [`Signature`]: ../enum.Signature.html
-/// [streaming `Signer`]: ../../serialize/stream/struct.Signer.html
-/// [`SignatureBuilder::sign_message`]: #method.sign_message
-///
-/// Oftentimes, you won't want to create a new signature from scratch,
-/// but modify a copy of an existing signature. This is
-/// straightforward to do since `SignatureBuilder` implements [`From`]
-/// for Signature.
-///
-/// [`From`]: https://doc.rust-lang.org/stable/std/convert/trait.From.html
-///
-/// According to [Section 5.2.3.4 of RFC 4880], `Signatures` must
-/// include a [`Signature Creation Time`] subpacket. Since this
-/// should usually be set to the current time, and is easy to forget
-/// to update, we remove any `Signature Creation Time` subpackets
-/// from both the hashed subpacket area and the unhashed subpacket
-/// area when converting a `Signature` to a `SignatureBuilder`, and
-/// when the `SignatureBuilder` is finalized, we automatically insert
-/// a `Signature Creation Time` subpacket into the hashed subpacket
-/// area unless the `Signature Creation Time` subpacket has been set
-/// using the [`set_signature_creation_time`] method or preserved
-/// using the [`preserve_signature_creation_time`] method or
-/// suppressed using the [`suppress_signature_creation_time`] method.
-///
-/// If the `SignatureBuilder` has been created from scratch, the
-/// current time is used as signature creation time. If it has been
-/// created from a template, we make sure that the generated signature
-/// is newer. If that is not possible (i.e. the generated signature
-/// would have a future creation time), the signing operation fails.
-/// This ensures that binding signatures can be updated by deriving a
-/// `SignatureBuilder` from the existing binding. To disable this,
-/// explicitly set a signature creation time, or preserve the original
-/// one, or suppress the insertion of a timestamp.
-///
-/// [Section 5.2.3.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.2.3.4
-/// [`Signature Creation Time`]: https://tools.ietf.org/html/rfc4880#section-5.2.3.4
-/// [`set_signature_creation_time`]: #method.set_signature_creation_time
-/// [`preserve_signature_creation_time`]: #method.preserve_signature_creation_time
-/// [`suppress_signature_creation_time`]: #method.suppress_signature_creation_time
-///
-/// Similarly, most OpenPGP implementations cannot verify a signature
-/// if neither the [`Issuer`] subpacket nor the [`Issuer Fingerprint`]
-/// subpacket has been correctly set. To avoid subtle bugs due to the
-/// use of a stale `Issuer` subpacket or a stale `Issuer Fingerprint`
-/// subpacket, we remove any `Issuer` subpackets, and `Issuer
-/// Fingerprint` subpackets from both the hashed and unhashed areas
-/// when converting a `Signature` to a `SigantureBuilder`. Since the
-/// [`Signer`] passed to the finalization routine contains the
-/// required information, we also automatically add appropriate
-/// `Issuer` and `Issuer Fingerprint` subpackets to the unhashed
-/// subpacket area when the `SignatureBuilder` is finalized unless an
-/// `Issuer` subpacket or an `IssuerFingerprint` subpacket has been
-/// added to either of the subpacket areas (which can be done using
-/// the [`set_issuer`] method and the [`set_issuer_fingerprint`]
-/// method, respectively).
-///
-/// [`Issuer`]: https://tools.ietf.org/html/rfc4880#section-5.2.3.5
-/// [`Issuer Fingerprint`]: https://www.ietf.org/id/draft-ietf-openpgp-rfc4880bis-09.html#section-5.2.3.28
-/// [`Signer`]: ../../crypto/trait.Signer.html
-/// [`set_issuer`]: #method.set_issuer
-/// [`set_issuer_fingerprint`]: #method.set_issuer_fingerprint
-///
-/// To finalize the builder, call [`sign_hash`], [`sign_message`],
-/// [`sign_direct_key`], [`sign_subkey_binding`],
-/// [`sign_primary_key_binding`], [`sign_userid_binding`],
-/// [`sign_user_attribute_binding`], [`sign_standalone`], or
-/// [`sign_timestamp`], as appropriate. These functions turn the
-/// `SignatureBuilder` into a valid `Signature`.
-///
-/// [`sign_hash`]: #method.sign_hash
-/// [`sign_message`]: #method.sign_message
-/// [`sign_direct_key`]: #method.sign_direct_key
-/// [`sign_subkey_binding`]: #method.sign_subkey_binding
-/// [`sign_primary_key_binding`]: #method.sign_primary_key_binding
-/// [`sign_userid_binding`]: #method.sign_userid_binding
-/// [`sign_user_attribute_binding`]: #method.sign_user_attribute_binding
-/// [`sign_standalone`]: #method.sign_standalone
-/// [`sign_timestamp`]: #method.sign_timestamp
-///
-/// This structure `Deref`s to its containing [`SignatureFields`]
-/// structure, which in turn `Deref`s to its subpacket areas
-/// (a [`SubpacketAreas`]).
-///
-/// [`SignatureFields`]: struct.SignatureFields.html
-/// [`SubpacketAreas`]: subpacket/struct.SubpacketAreas.html
-///
-/// # Examples
-///
-/// Update a certificate's feature set by updating the `Features`
-/// subpacket on any direct key signature, and any User ID binding
-/// signatures. See the [`Preferences`] trait for how preferences
-/// like these are looked up.
-///
-/// [`Preferences`]: ../../cert/trait.Preferences.html
-///
-/// ```
-/// use sequoia_openpgp as openpgp;
-/// use openpgp::cert::prelude::*;
-/// use openpgp::packet::prelude::*;
-/// use openpgp::packet::signature::subpacket::{Subpacket, SubpacketValue};
-/// use openpgp::policy::StandardPolicy;
-/// use openpgp::types::Features;
-///
-/// # fn main() -> openpgp::Result<()> {
-/// let p = &StandardPolicy::new();
-///
-/// let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
-///
-/// // Derive a signer (the primary key is always certification capable).
-/// let pk = cert.primary_key().key();
-/// let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;
-///
-/// let mut sigs = Vec::new();
-///
-/// let vc = cert.with_policy(p, None)?;
-///
-/// if let Ok(sig) = vc.direct_key_signature() {
-/// sigs.push(SignatureBuilder::from(sig.clone())
-/// .modify_hashed_area(|mut a| {
-/// a.replace(Subpacket::new(
-/// SubpacketValue::Features(Features::sequoia().set(10)),
-/// false)?)?;
-/// Ok(a)
-/// })?
-/// // Update the direct key signature.
-/// .sign_direct_key(&mut signer, pk)?);
-/// }
-///
-/// for ua in vc.userids() {
-/// sigs.push(SignatureBuilder::from(ua.binding_signature().clone())
-/// .modify_hashed_area(|mut a| {
-/// a.replace(Subpacket::new(
-/// SubpacketValue::Features(Features::sequoia().set(10)),
-/// false)?)?;
-/// Ok(a)
-/// })?
-/// // Update the binding signature.
-/// .sign_userid_binding(&mut signer, pk, ua.userid())?);
-/// }
-///
-/// // Merge in the new signatures.
-/// let cert = cert.merge_packets(sigs.into_iter().map(Packet::from))?;
-/// # assert_eq!(cert.bad_signatures().len(), 0);
-/// # Ok(())
-/// # }
-/// ```
-// IMPORTANT: If you add fields to this struct, you need to explicitly
-// IMPORTANT: implement PartialEq, Eq, and Hash.
-#[derive(Clone, Hash, PartialEq, Eq)]
-pub struct SignatureBuilder {
- overrode_creation_time: bool,
- original_creation_time: Option<SystemTime>,
- fields: SignatureFields,
-}
-
-impl Deref for SignatureBuilder {
- type Target = SignatureFields;
-
- fn deref(&self) -> &Self::Target {
- &self.fields
- }
-}
-
-impl DerefMut for SignatureBuilder {
- fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.fields
- }
-}
-
-impl SignatureBuilder {
- /// Returns a new `SignatureBuilder` object.
- pub fn new(typ: SignatureType) -> Self {
- SignatureBuilder {
- overrode_creation_time: false,
- original_creation_time: None,
- fields: SignatureFields {
- version: 4,
- typ,
- pk_algo: PublicKeyAlgorithm::Unknown(0),
- hash_algo: HashAlgorithm::default(),
- subpackets: SubpacketAreas::default(),
- }
- }
- }
-
- /// Sets the signature type.
- pub fn set_type(mut self, t: SignatureType) -> Self {
- self.typ = t;
- self
- }
-
- /// Sets the hash algorithm.
- pub fn set_hash_algo(mut self, h: HashAlgorithm) -> Self {
- self.hash_algo = h;
- self
- }
-
- /// Generates a standalone signature.
- ///
- /// A [Standalone Signature] ([`SignatureType::Standalone`]) is a
- /// self-contained signature, which is only over the signature
- /// packet.
- ///
- /// [Standalone Signature]: https://tools.ietf.org/html/rfc4880#section-5.2.1
- /// [`SignatureType::Standalone`]: ../../types/enum.SignatureType.html#variant.Standalone
- ///
- /// This function checks that the [signature type] (passed to
- /// [`SignatureBuilder::new`], set via
- /// [`SignatureBuilder::set_type`], or copied when using
- /// `SignatureBuilder::From`) is [`SignatureType::Standalone`] or
- /// [`SignatureType::Unknown`].
- ///
- /// [signature type]: ../../types/enum.SignatureType.html
- /// [`SignatureBuilder::new`]: #method.new
- /// [`SignatureBuilder::set_type`]: #method.set_type
- /// [`SignatureType::Timestamp`]: ../../types/enum.SignatureType.html#variant.Timestamp
- /// [`SignatureType::Unknown`]: ../../types/enum.SignatureType.html#variant.Unknown
- ///
- /// The [`Signature`]'s public-key algorithm field is set to the
- /// algorithm used by `signer`.
- ///
- /// [`Signature`]: ../enum.Signature.html
- ///
- /// If neither an [`Issuer`] subpacket (set using
- /// [`SignatureBuilder::set_issuer`], for instance) nor an
- /// [`Issuer Fingerprint`] subpacket (set using
- /// [`SignatureBuilder::set_issuer_fingerprint`], for instance) is
- /// set, they are both added to the new `Signature`'s unhashed
- /// subpacket area and set to the `signer`'s `KeyID` and
- /// `Fingerprint`, respectively.
- ///
- /// [`Issuer`]: https://tools.ietf.org/html/rfc4880#section-5.2.3.5
- /// [`SignatureBuilder::set_issuer`]: #method.set_issuer
- /// [`Issuer Fingerprint`]: https://www.ietf.org/id/draft-ietf-openpgp-rfc4880bis-09.html#section-5.2.3.28
- /// [`SignatureBuilder::set_issuer_fingerprint`]: #method.set_issuer_fingerprint
- ///
- /// Likewise, a [`Signature Creation Time`] subpacket set to the
- /// current time is added to the hashed area if the `Signature
- /// Creation Time` subpacket hasn't been set using, for instance,
- /// the [`set_signature_creation_time`] method or the
- /// [`preserve_signature_creation_time`] method.
- ///
- /// [`Signature Creation Time`]: https://tools.ietf.org/html/rfc4880#section-5.2.3.4
- /// [`set_signature_creation_time`]: #method.set_signature_creation_time
- /// [`preserve_signature_creation_time`]: #method.preserve_signature_creation_time
- ///
- /// # Examples
- ///
- /// ```
- /// use sequoia_openpgp as openpgp;
- /// use openpgp::cert::prelude::*;
- /// use openpgp::packet::prelude::*;
- /// use openpgp::policy::StandardPolicy;
- /// use openpgp::types::SignatureType;
- ///
- /// # fn main() -> openpgp::Result<()> {
- /// let p = &StandardPolicy::new();
- ///
- /// let (cert, _) = CertBuilder::new().add_signing_subkey().generate()?;
- ///
- /// // Get a usable (alive, non-revoked) signing key.
- /// let key : &Key<_, _> = cert
- /// .keys().with_policy(p, None)
- /// .for_signing().alive().revoked(false).nth(0).unwrap().key();
- /// // Derive a signer.
- /// let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
- ///
- /// let sig = SignatureBuilder::new(SignatureType::Standalone)
- /// .sign_standalone(&mut signer)?;
- ///
- /// // Verify it.
- /// sig.verify_standalone(signer.public())?;
- /// # Ok(())
- /// # }
- /// ```
- pub fn sign_standalone(mut self, signer: &mut dyn Signer)
- -> Result<Signature>
- {
- match self.typ {
- SignatureType::Standalone => (),
- SignatureType::Unknown(_) => (),
- _ => return Err(Error::UnsupportedSignatureType(self.typ).into()),
- }
-
- self = self.pre_sign(signer)?;
-
- let digest = Signature::hash_standalone(&self)?;
-
- self.sign(signer, digest)
- }
-
- /// Generates a Timestamp Signature.
- ///
- /// Like a [Standalone Signature] (created using
- /// [`SignatureBuilder::sign_standalone`]), a [Timestamp
- /// Signature] is a self-contained signature, but its emphasis in
- /// on the contained timestamp, specifically, the timestamp stored
- /// in the [`Signature Creation Time`] subpacket. This type of
- /// signature is primarily used by [timestamping services]. To
- /// timestamp a signature, you can include either a [Signature
- /// Target subpacket] (set using
- /// [`SignatureBuilder::set_signature_target`]), or an [Embedded
- /// Signature] (set using
- /// [`SignatureBuilder::set_embedded_signature`]) in the hashed
- /// area.
- ///
- ///
- /// [Standalone Signature]: https://tools.ietf.org/html/rfc4880#section-5.2.1
- /// [`SignatureBuilder::sign_standalone`]: #method.sign_standalone
- /// [Timestamp Signature]: https://tools.ietf.org/html/rfc4880#section-5.2.1
- /// [`Signature Creation Time`]: https://tools.ietf.org/html/rfc4880#section-5.2.3.4
- /// [timestamping services]: https://en.wikipedia.org/wiki/Trusted_timestamping
- /// [Signature Target subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.25
- /// [`SignatureBuilder::set_signature_target`]: #method.set_signature_target
- /// [Embedded Signature]: https://tools.ietf.org/html/rfc4880#section-5.2.3.26
- /// [`SignatureBuilder::set_embedded_signature`]: #method.set_embedded_signature
- ///
- /// This function checks that the [signature type] (passed to
- /// [`SignatureBuilder::new`], set via
- /// [`SignatureBuilder::set_type`], or copied when using
- /// `SignatureBuilder::From`) is [`SignatureType::Timestamp`] or
- /// [`SignatureType::Unknown`].
- ///
- /// [signature type]: ../../types/enum.SignatureType.html
- /// [`SignatureBuilder::new`]: #method.new
- /// [`SignatureBuilder::set_type`]: #method.set_type
- /// [`SignatureType::Timestamp`]: ../../types/enum.SignatureType.html#variant.Timestamp
- /// [`SignatureType::Unknown`]: ../../types/enum.SignatureType.html#variant.Unknown
- ///
- /// The [`Signature`]'s public-key algorithm field is set to the
- /// algorithm used by `signer`.
- ///
- /// [`Signature`]: ../enum.Signature.html
- ///
- /// If neither an [`Issuer`] subpacket (set using
- /// [`SignatureBuilder::set_issuer`], for instance) nor an
- /// [`Issuer Fingerprint`] subpacket (set using
- /// [`SignatureBuilder::set_issuer_fingerprint`], for instance) is
- /// set, they are both added to the new `Signature`'s unhashed
- /// subpacket area and set to the `signer`'s `KeyID` and
- /// `Fingerprint`, respectively.
- ///
- /// [`Issuer`]: https://tools.ietf.org/html/rfc4880#section-5.2.3.5
- /// [`SignatureBuilder::set_issuer`]: #method.set_issuer
- /// [`Issuer Fingerprint`]: https://www.ietf.org/id/draft-ietf-openpgp-rfc4880bis-09.html#section-5.2.3.28
- /// [`SignatureBuilder::set_issuer_fingerprint`]: #method.set_issuer_fingerprint
- ///
- /// Likewise, a [`Signature Creation Time`] subpacket set to the
- /// current time is added to the hashed area if the `Signature
- /// Creation Time` subpacket hasn't been set using, for instance,
- /// the [`set_signature_creation_time`] method or the
- /// [`preserve_signature_creation_time`] method.
- ///
- /// [`Signature Creation Time`]: https://tools.ietf.org/html/rfc4880#section-5.2.3.4
- /// [`set_signature_creation_time`]: #method.set_signature_creation_time
- /// [`preserve_signature_creation_time`]: #method.preserve_signature_creation_time
- ///
- /// # Examples
- ///
- /// Create a timestamp signature:
- ///
- /// ```
- /// use sequoia_openpgp as openpgp;
- /// use openpgp::cert::prelude::*;
- /// use openpgp::packet::prelude::*;
- /// use openpgp::policy::StandardPolicy;
- /// use openpgp::types::SignatureType;
- ///
- /// # fn main() -> openpgp::Result<()> {
- /// let p = &StandardPolicy::new();
- ///
- /// let (cert, _) = CertBuilder::new().add_signing_subkey().generate()?;
- ///
- /// // Get a usable (alive, non-revoked) signing key.
- /// let key : &Key<_, _> = cert
- /// .keys().with_policy(p, None)
- /// .for_signing().alive().revoked(false).nth(0).unwrap().key();
- /// // Derive a signer.
- /// let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
- ///
- /// let sig = SignatureBuilder::new(SignatureType::Timestamp)
- /// .sign_timestamp(&mut signer)?;
- ///
- /// // Verify it.
- /// sig.verify_timestamp(signer.public())?;
- /// # Ok(())
- /// # }
- /// ```
- pub fn sign_timestamp(mut self, signer: &mut dyn Signer)
- -> Result<Signature>
- {
- match self.typ {
- SignatureType::Timestamp => (),
- SignatureType::Unknown(_) => (),
- _ => return Err(Error::UnsupportedSignatureType(self.typ).into()),
- }
-
- self = self.pre_sign(signer)?;
-
- let digest = Signature::hash_timestamp(&self)?;
-
- self.sign(signer, digest)
- }
-
- /// Generates a Direct Key Signature.
- ///
- /// A [Direct Key Signature] is a signature over the primary