diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-09-30 13:37:28 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-10-02 15:09:10 +0200 |
commit | 23cb4b184b8c710d5c54bd45dbad206d59ae36b3 (patch) | |
tree | af1ed73908e82f76faf4817e1383d97b45876622 /openpgp/src/packet/signature | |
parent | b81204994ebd395b0229c0e7eaaa47b7a013ece9 (diff) |
openpgp: Rename file.
Diffstat (limited to 'openpgp/src/packet/signature')
-rw-r--r-- | openpgp/src/packet/signature/mod.rs | 3054 |
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 |