sequoia_openpgp/packet/signature.rs
1//! Signature-related functionality.
2//!
3//! Signatures are one of the central data structures in OpenPGP.
4//! They are used to protect the integrity of both structured
5//! documents (e.g., timestamps) and unstructured documents (arbitrary
6//! byte sequences) as well as cryptographic data structures.
7//!
8//! The use of signatures to protect cryptographic data structures is
9//! central to making it easy to change an OpenPGP certificate.
10//! Consider how a certificate is initially authenticated. A user,
11//! say Alice, securely communicates her certificate's fingerprint to
12//! another user, say Bob. Alice might do this by personally handing
13//! Bob a business card with her fingerprint on it. When Bob is in
14//! front of his computer, he may then record that Alice uses the
15//! specified key. Technically, the fingerprint that he used only
16//! identifies the primary key: a fingerprint is the hash of the
17//! primary key; it does not say anything about any of the rest of the
18//! certificate---the subkeys, the User IDs, and the User Attributes.
19//! But, because these components are signed by the primary key, we
20//! know that the controller of the key intended that they be
21//! associated with the certificate. This mechanism makes it not only
22//! possible to add and revoke components, but also to change
23//! meta-data, such as a key's expiration time. If the fingerprint
24//! were instead computed over the whole OpenPGP certificate, then
25//! changing the certificate would result in a new fingerprint. In
26//! that case, the fingerprint could not be used as a long-term,
27//! unique, and stable identifier.
28//!
29//! Signatures are described in [Section 5.2 of RFC 9580].
30//!
31//! # Data Types
32//!
33//! The main signature-related data type is the [`Signature`] enum.
34//! This enum abstracts away the differences between the signature
35//! formats (the current [version 6], the deprecated [version 4], and
36//! the legacy [version 3] formats). Nevertheless some functionality
37//! remains format specific. For instance, [version 4] signatures
38//! introduced support for storing arbitrary key-value pairs
39//! (so-called [notations]).
40//!
41//! This version of Sequoia supports [version 6] and [version 4]
42//! signatures ([`Signature6`] and [`Signature4`]), and includes
43//! limited support for [version 3] signatures to allow working with
44//! archived messages.
45//!
46//! When signing a document, a `Signature` is typically created
47//! indirectly by the [streaming `Signer`]. Similarly, a `Signature`
48//! packet is created as a side effect of parsing a signed message
49//! using the [`PacketParser`].
50//!
51//! The [`SignatureBuilder`] can be used to create a binding
52//! signature, a certification, etc. The motivation for having a
53//! separate data structure for creating signatures is that it
54//! decreases the chance that a half-constructed signature is
55//! accidentally exported. When modifying an existing signature, you
56//! can use, for instance, `SignatureBuilder::from` to convert a
57//! `Signature` into a `SignatureBuilder`:
58//!
59//! ```
60//! use sequoia_openpgp as openpgp;
61//! use openpgp::policy::StandardPolicy;
62//! # use openpgp::cert::prelude::*;
63//! # use openpgp::packet::prelude::*;
64//!
65//! # fn main() -> openpgp::Result<()> {
66//! let p = &StandardPolicy::new();
67//!
68//! # // Generate a new certificate. It has secret key material.
69//! # let (cert, _) = CertBuilder::new()
70//! # .generate()?;
71//! #
72//! // Create a new direct key signature using the current one as a template.
73//! let pk = cert.with_policy(p, None)?.primary_key();
74//! let sig = pk.direct_key_signature()?;
75//! let builder: SignatureBuilder = sig.clone().into();
76//! # Ok(())
77//! # }
78//! ```
79//!
80//! For [version 6] and [version 4] signatures, attributes are set
81//! using so-called subpackets. Subpackets can be stored in two
82//! places: either in the so-called hashed area or in the so-called
83//! unhashed area. Whereas the hashed area's integrity is protected
84//! by the signature, the unhashed area is not. Because an attacker
85//! can modify the unhashed area without detection, the unhashed area
86//! should only be used for storing self-authenticating data, e.g.,
87//! the issuer, or a back signature. It is also sometimes used for
88//! [hints]. [`Signature::normalize`] removes unexpected subpackets
89//! from the unhashed area. However, due to a lack of context, it
90//! does not validate the remaining subpackets.
91//!
92//! In Sequoia, each subpacket area is represented by a
93//! [`SubpacketArea`] data structure. The two subpacket areas are
94//! unified by the [`SubpacketAreas`] data structure, which implements
95//! a reasonable policy for looking up subpackets. In particular, it
96//! prefers subpackets from the hashed subpacket area, and only
97//! consults the unhashed subpacket area for certain packets. See
98//! [its documentation] for details.
99//!
100//! [Section 5.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2
101//! [`Signature`]: super::Signature
102//! [version 3]: https://tools.ietf.org/html/rfc1991#section-5.2.2
103//! [version 4]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3
104//! [version 6]: https://www.rfc-editor.org/rfc/rfc9580.html#name-versions-4-and-6-signature-
105//! [notations]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
106//! [streaming `Signer`]: crate::serialize::stream::Signer
107//! [`PacketParser`]: crate::parse::PacketParser
108//! [hints]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.13
109//! [`Signature::normalize`]: super::Signature::normalize()
110//! [`SubpacketArea`]: subpacket::SubpacketArea
111//! [`SubpacketAreas`]: subpacket::SubpacketAreas
112//! [its documentation]: subpacket::SubpacketAreas
113
114use std::borrow::Cow;
115use std::cmp::Ordering;
116use std::convert::TryFrom;
117use std::fmt;
118use std::hash::Hasher;
119use std::ops::{Deref, DerefMut};
120use std::sync::OnceLock;
121use std::time::SystemTime;
122
123#[cfg(test)]
124use quickcheck::{Arbitrary, Gen};
125
126use crate::Error;
127use crate::Result;
128use crate::crypto::{
129 mpi,
130 hash::{self, Hash},
131 Signer,
132};
133use crate::KeyID;
134use crate::KeyHandle;
135use crate::HashAlgorithm;
136use crate::PublicKeyAlgorithm;
137use crate::SignatureType;
138use crate::packet::Signature;
139use crate::packet::{
140 key,
141 Key,
142};
143use crate::packet::UserID;
144use crate::packet::UserAttribute;
145use crate::Packet;
146use crate::packet;
147use crate::packet::signature::subpacket::{
148 Subpacket,
149 SubpacketArea,
150 SubpacketAreas,
151 SubpacketTag,
152 SubpacketValue,
153};
154use crate::types::Timestamp;
155
156#[cfg(test)]
157/// Like quickcheck::Arbitrary, but bounded.
158pub(crate) trait ArbitraryBounded {
159 /// Generates an arbitrary value, but only recurses if `depth >
160 /// 0`.
161 fn arbitrary_bounded(g: &mut Gen, depth: usize) -> Self;
162}
163
164#[cfg(test)]
165/// Default depth when implementing Arbitrary using ArbitraryBounded.
166const DEFAULT_ARBITRARY_DEPTH: usize = 2;
167
168#[cfg(test)]
169macro_rules! impl_arbitrary_with_bound {
170 ($typ:path) => {
171 impl Arbitrary for $typ {
172 fn arbitrary(g: &mut Gen) -> Self {
173 Self::arbitrary_bounded(
174 g,
175 crate::packet::signature::DEFAULT_ARBITRARY_DEPTH)
176 }
177 }
178 }
179}
180
181pub mod subpacket;
182pub mod cache;
183mod v6;
184pub use v6::Signature6;
185
186/// How many seconds to backdate signatures.
187///
188/// When creating certificates (more specifically, binding
189/// signatures), and when updating binding signatures (creating
190/// signatures from templates), we backdate the signatures by this
191/// amount if no creation time is explicitly given. Backdating the
192/// certificate by a minute has the advantage that the certificate can
193/// immediately be customized:
194///
195/// In order to reliably override a binding signature, the
196/// overriding binding signature must be newer than the existing
197/// signature. If, however, the existing signature is created
198/// `now`, any newer signature must have a future creation time,
199/// and is considered invalid by Sequoia. To avoid this, we
200/// backdate certificate creation times (and hence binding
201/// signature creation times), so that there is "space" between
202/// the creation time and now for signature updates.
203pub(crate) const SIG_BACKDATE_BY: u64 = 60;
204
205/// The data stored in a `Signature` packet.
206///
207/// This data structure contains exactly those fields that appear in a
208/// [`Signature` packet]. It is used by both the [`Signature4`] and
209/// the [`SignatureBuilder`] data structures, which include other
210/// auxiliary information. This data structure is public so that
211/// `Signature4` and `SignatureBuilder` can deref to it.
212///
213/// A `SignatureField` derefs to a [`SubpacketAreas`].
214///
215/// [`Signature`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2
216/// [`SubpacketAreas`]: subpacket::SubpacketAreas
217#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
218pub struct SignatureFields {
219 /// Version of the signature packet. Must be 4.
220 version: u8,
221 /// Type of signature.
222 typ: SignatureType,
223 /// Public-key algorithm used for this signature.
224 pk_algo: PublicKeyAlgorithm,
225 /// Hash algorithm used to compute the signature.
226 hash_algo: HashAlgorithm,
227 /// Subpackets.
228 subpackets: SubpacketAreas,
229}
230assert_send_and_sync!(SignatureFields);
231
232#[cfg(test)]
233impl ArbitraryBounded for SignatureFields {
234 fn arbitrary_bounded(g: &mut Gen, depth: usize) -> Self {
235 SignatureFields {
236 // XXX: Make this more interesting once we dig other
237 // versions.
238 version: 4,
239 typ: Arbitrary::arbitrary(g),
240 pk_algo: PublicKeyAlgorithm::arbitrary_for_signing(g),
241 hash_algo: Arbitrary::arbitrary(g),
242 subpackets: ArbitraryBounded::arbitrary_bounded(g, depth),
243 }
244 }
245}
246
247#[cfg(test)]
248impl_arbitrary_with_bound!(SignatureFields);
249
250impl Deref for SignatureFields {
251 type Target = SubpacketAreas;
252
253 fn deref(&self) -> &Self::Target {
254 &self.subpackets
255 }
256}
257
258impl DerefMut for SignatureFields {
259 fn deref_mut(&mut self) -> &mut Self::Target {
260 &mut self.subpackets
261 }
262}
263
264impl SignatureFields {
265 /// Gets the version.
266 pub fn version(&self) -> u8 {
267 self.version
268 }
269
270 /// Gets the signature type.
271 ///
272 /// This function is called `typ` and not `type`, because `type`
273 /// is a reserved word.
274 pub fn typ(&self) -> SignatureType {
275 self.typ
276 }
277
278 /// Gets the public key algorithm.
279 ///
280 /// This is `pub(crate)`, because it shouldn't be exported by
281 /// `SignatureBuilder` where it is only set at the end.
282 pub(crate) fn pk_algo(&self) -> PublicKeyAlgorithm {
283 self.pk_algo
284 }
285
286 /// Gets the hash algorithm.
287 pub fn hash_algo(&self) -> HashAlgorithm {
288 self.hash_algo
289 }
290}
291
292#[derive(Clone, Debug, Hash, PartialEq, Eq)]
293pub(crate) enum SBVersion {
294 V4 {},
295 V6 {
296 salt: Vec<u8>,
297 },
298}
299
300impl Default for SBVersion {
301 fn default() -> Self {
302 SBVersion::V4 {}
303 }
304}
305
306impl SBVersion {
307 fn to_u8(&self) -> u8 {
308 match self {
309 SBVersion::V4 { .. } => 4,
310 SBVersion::V6 { .. } => 6,
311 }
312 }
313
314 /// Returns the salt, if any.
315 pub(crate) fn salt(&self) -> Option<&[u8]> {
316 match self {
317 SBVersion::V4 { .. } => None,
318 SBVersion::V6 { salt, .. } => Some(&salt),
319 }
320 }
321}
322
323/// A Signature builder.
324///
325/// The `SignatureBuilder` is used to create [`Signature`]s. Although
326/// it can be used to generate a signature over a document (using
327/// [`SignatureBuilder::sign_message`]), it is usually better to use
328/// the [streaming `Signer`] for that.
329///
330/// [`Signature`]: super::Signature
331/// [streaming `Signer`]: crate::serialize::stream::Signer
332/// [`SignatureBuilder::sign_message`]: SignatureBuilder::sign_message()
333///
334/// Oftentimes, you won't want to create a new signature from scratch,
335/// but modify a copy of an existing signature. This is
336/// straightforward to do since `SignatureBuilder` implements [`From`]
337/// for Signature.
338///
339/// [`From`]: std::convert::From
340///
341/// When converting a `Signature` to a `SignatureBuilder`, the hash
342/// algorithm is reset to the default hash algorithm
343/// (`HashAlgorithm::Default()`). This ensures that a recommended
344/// hash algorithm is used even when an old signature is used as a
345/// template, which is often the case when updating self signatures,
346/// and binding signatures.
347///
348/// According to [Section 5.2.3.11 of RFC 9580], `Signatures` must
349/// include a [`Signature Creation Time`] subpacket. Since this
350/// should usually be set to the current time, and is easy to forget
351/// to update, we remove any `Signature Creation Time` subpackets
352/// from both the hashed subpacket area and the unhashed subpacket
353/// area when converting a `Signature` to a `SignatureBuilder`, and
354/// when the `SignatureBuilder` is finalized, we automatically insert
355/// a `Signature Creation Time` subpacket into the hashed subpacket
356/// area unless the `Signature Creation Time` subpacket has been set
357/// using the [`set_signature_creation_time`] method or preserved
358/// using the [`preserve_signature_creation_time`] method or
359/// suppressed using the [`suppress_signature_creation_time`] method.
360///
361/// If the `SignatureBuilder` has been created from scratch, the
362/// current time is used as signature creation time. If it has been
363/// created from a template, we make sure that the generated signature
364/// is newer. If that is not possible (i.e. the generated signature
365/// would have a future creation time), the signing operation fails.
366/// This ensures that binding signatures can be updated by deriving a
367/// `SignatureBuilder` from the existing binding. To disable this,
368/// explicitly set a signature creation time, or preserve the original
369/// one, or suppress the insertion of a timestamp.
370///
371/// [Section 5.2.3.11 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
372/// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
373/// [`set_signature_creation_time`]: SignatureBuilder::set_signature_creation_time()
374/// [`preserve_signature_creation_time`]: SignatureBuilder::preserve_signature_creation_time()
375/// [`suppress_signature_creation_time`]: SignatureBuilder::suppress_signature_creation_time()
376///
377/// Similarly, most OpenPGP implementations cannot verify a signature
378/// if neither the [`Issuer`] subpacket nor the [`Issuer Fingerprint`]
379/// subpacket has been correctly set. To avoid subtle bugs due to the
380/// use of a stale `Issuer` subpacket or a stale `Issuer Fingerprint`
381/// subpacket, we remove any `Issuer` subpackets, and `Issuer
382/// Fingerprint` subpackets from both the hashed and unhashed areas
383/// when converting a `Signature` to a `SigantureBuilder`. Since the
384/// [`Signer`] passed to the finalization routine contains the
385/// required information, we also automatically add appropriate
386/// `Issuer` and `Issuer Fingerprint` subpackets to the hashed
387/// subpacket area when the `SignatureBuilder` is finalized unless an
388/// `Issuer` subpacket or an `IssuerFingerprint` subpacket has been
389/// added to either of the subpacket areas (which can be done using
390/// the [`set_issuer`] method and the [`set_issuer_fingerprint`]
391/// method, respectively).
392///
393/// [`Issuer`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
394/// [`Issuer Fingerprint`]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
395/// [`Signer`]: super::super::crypto::Signer
396/// [`set_issuer`]: SignatureBuilder::set_issuer()
397/// [`set_issuer_fingerprint`]: SignatureBuilder::set_issuer_fingerprint()
398///
399/// To finalize the builder, call [`sign_hash`], [`sign_message`],
400/// [`sign_direct_key`], [`sign_subkey_binding`],
401/// [`sign_primary_key_binding`], [`sign_userid_binding`],
402/// [`sign_user_attribute_binding`], [`sign_standalone`], or
403/// [`sign_timestamp`], as appropriate. These functions turn the
404/// `SignatureBuilder` into a valid `Signature`.
405///
406/// [`sign_hash`]: SignatureBuilder::sign_hash()
407/// [`sign_message`]: SignatureBuilder::sign_message()
408/// [`sign_direct_key`]: SignatureBuilder::sign_direct_key()
409/// [`sign_subkey_binding`]: SignatureBuilder::sign_subkey_binding()
410/// [`sign_primary_key_binding`]: SignatureBuilder::sign_primary_key_binding()
411/// [`sign_userid_binding`]: SignatureBuilder::sign_userid_binding()
412/// [`sign_user_attribute_binding`]: SignatureBuilder::sign_user_attribute_binding()
413/// [`sign_standalone`]: SignatureBuilder::sign_standalone()
414/// [`sign_timestamp`]: SignatureBuilder::sign_timestamp()
415///
416/// This structure `Deref`s to its containing [`SignatureFields`]
417/// structure, which in turn `Deref`s to its subpacket areas
418/// (a [`SubpacketAreas`]).
419///
420/// [`SubpacketAreas`]: subpacket::SubpacketAreas
421///
422/// # Examples
423///
424/// Update a certificate's feature set by updating the `Features`
425/// subpacket on any direct key signature, and any User ID binding
426/// signatures. See the [`Preferences`] trait for how preferences
427/// like these are looked up.
428///
429/// [`Preferences`]: crate::cert::Preferences
430///
431/// ```
432/// use sequoia_openpgp as openpgp;
433/// use openpgp::cert::prelude::*;
434/// use openpgp::packet::prelude::*;
435/// use openpgp::packet::signature::subpacket::{Subpacket, SubpacketValue};
436/// use openpgp::policy::StandardPolicy;
437/// use openpgp::types::Features;
438///
439/// # fn main() -> openpgp::Result<()> {
440/// let p = &StandardPolicy::new();
441///
442/// let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
443///
444/// // Derive a signer (the primary key is always certification capable).
445/// let pk = cert.primary_key().key();
446/// let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;
447///
448/// let mut sigs = Vec::new();
449///
450/// let vc = cert.with_policy(p, None)?;
451///
452/// if let Ok(sig) = vc.direct_key_signature() {
453/// sigs.push(SignatureBuilder::from(sig.clone())
454/// .modify_hashed_area(|mut a| {
455/// a.replace(Subpacket::new(
456/// SubpacketValue::Features(Features::sequoia().set(10)),
457/// false)?)?;
458/// Ok(a)
459/// })?
460/// // Update the direct key signature.
461/// .sign_direct_key(&mut signer, None)?);
462/// }
463///
464/// for ua in vc.userids() {
465/// sigs.push(SignatureBuilder::from(ua.binding_signature().clone())
466/// .modify_hashed_area(|mut a| {
467/// a.replace(Subpacket::new(
468/// SubpacketValue::Features(Features::sequoia().set(10)),
469/// false)?)?;
470/// Ok(a)
471/// })?
472/// // Update the binding signature.
473/// .sign_userid_binding(&mut signer, pk, ua.userid())?);
474/// }
475///
476/// // Merge in the new signatures.
477/// let cert = cert.insert_packets(sigs.into_iter().map(Packet::from))?.0;
478/// # assert_eq!(cert.bad_signatures().count(), 0);
479/// # Ok(())
480/// # }
481/// ```
482// IMPORTANT: If you add fields to this struct, you need to explicitly
483// IMPORTANT: implement PartialEq, Eq, and Hash.
484#[derive(Clone, Hash, PartialEq, Eq)]
485pub struct SignatureBuilder {
486 reference_time: Option<SystemTime>,
487 overrode_creation_time: bool,
488 original_creation_time: Option<SystemTime>,
489 pub(crate) fields: SignatureFields,
490
491 /// The version of signature in the signature builder.
492 ///
493 /// Note: this is called sb_version instead of version, because
494 /// currently SignaturBuilder derefs to SignatureFields, which
495 /// also has a field called version, which lead to a lot of
496 /// confusion. Consider renaming it once the deref is gone.
497 pub(crate) sb_version: SBVersion,
498}
499assert_send_and_sync!(SignatureBuilder);
500
501impl Deref for SignatureBuilder {
502 type Target = SignatureFields;
503
504 fn deref(&self) -> &Self::Target {
505 &self.fields
506 }
507}
508
509impl DerefMut for SignatureBuilder {
510 fn deref_mut(&mut self) -> &mut Self::Target {
511 &mut self.fields
512 }
513}
514
515impl SignatureBuilder {
516 /// Returns a new `SignatureBuilder` object.
517 pub fn new(typ: SignatureType) -> Self {
518 SignatureBuilder {
519 reference_time: None,
520 overrode_creation_time: false,
521 original_creation_time: None,
522 fields: SignatureFields {
523 version: 4,
524 typ,
525 pk_algo: PublicKeyAlgorithm::Unknown(0),
526 hash_algo: HashAlgorithm::default(),
527 subpackets: SubpacketAreas::default(),
528 },
529 sb_version: SBVersion::default(),
530 }
531 }
532
533 /// Sets the signature type.
534 pub fn set_type(mut self, t: SignatureType) -> Self {
535 self.typ = t;
536 self
537 }
538
539 /// Sets the hash algorithm.
540 pub fn set_hash_algo(mut self, h: HashAlgorithm) -> Self {
541 self.hash_algo = h;
542 self
543 }
544
545 /// Generates a standalone signature.
546 ///
547 /// A [Standalone Signature] ([`SignatureType::Standalone`]) is a
548 /// self-contained signature, which is only over the signature
549 /// packet.
550 ///
551 /// [Standalone Signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
552 /// [`SignatureType::Standalone`]: crate::types::SignatureType::Standalone
553 ///
554 /// This function checks that the [signature type] (passed to
555 /// [`SignatureBuilder::new`], set via
556 /// [`SignatureBuilder::set_type`], or copied when using
557 /// `SignatureBuilder::From`) is [`SignatureType::Standalone`] or
558 /// [`SignatureType::Unknown`].
559 ///
560 /// [signature type]: crate::types::SignatureType
561 /// [`SignatureBuilder::new`]: SignatureBuilder::new()
562 /// [`SignatureBuilder::set_type`]: SignatureBuilder::set_type()
563 /// [`SignatureType::Timestamp`]: crate::types::SignatureType::Timestamp
564 /// [`SignatureType::Unknown`]: crate::types::SignatureType::Unknown
565 ///
566 /// The [`Signature`]'s public-key algorithm field is set to the
567 /// algorithm used by `signer`.
568 ///
569 /// [`Signature`]: super::Signature
570 ///
571 /// If neither an [`Issuer`] subpacket (set using
572 /// [`SignatureBuilder::set_issuer`], for instance) nor an
573 /// [`Issuer Fingerprint`] subpacket (set using
574 /// [`SignatureBuilder::set_issuer_fingerprint`], for instance) is
575 /// set, they are both added to the new `Signature`'s hashed
576 /// subpacket area and set to the `signer`'s `KeyID` and
577 /// `Fingerprint`, respectively.
578 ///
579 /// [`Issuer`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
580 /// [`SignatureBuilder::set_issuer`]: SignatureBuilder::set_issuer()
581 /// [`Issuer Fingerprint`]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
582 /// [`SignatureBuilder::set_issuer_fingerprint`]: SignatureBuilder::set_issuer_fingerprint()
583 ///
584 /// Likewise, a [`Signature Creation Time`] subpacket set to the
585 /// current time is added to the hashed area if the `Signature
586 /// Creation Time` subpacket hasn't been set using, for instance,
587 /// the [`set_signature_creation_time`] method or the
588 /// [`preserve_signature_creation_time`] method.
589 ///
590 /// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
591 /// [`set_signature_creation_time`]: SignatureBuilder::set_signature_creation_time()
592 /// [`preserve_signature_creation_time`]: SignatureBuilder::preserve_signature_creation_time()
593 ///
594 /// # Examples
595 ///
596 /// ```
597 /// use sequoia_openpgp as openpgp;
598 /// use openpgp::cert::prelude::*;
599 /// use openpgp::packet::prelude::*;
600 /// use openpgp::policy::StandardPolicy;
601 /// use openpgp::types::SignatureType;
602 ///
603 /// # fn main() -> openpgp::Result<()> {
604 /// let p = &StandardPolicy::new();
605 ///
606 /// let (cert, _) = CertBuilder::new().add_signing_subkey().generate()?;
607 ///
608 /// // Get a usable (alive, non-revoked) signing key.
609 /// let key : &Key<_, _> = cert
610 /// .keys().with_policy(p, None)
611 /// .for_signing().alive().revoked(false).nth(0).unwrap().key();
612 /// // Derive a signer.
613 /// let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
614 ///
615 /// let mut sig = SignatureBuilder::new(SignatureType::Standalone)
616 /// .sign_standalone(&mut signer)?;
617 ///
618 /// // Verify it.
619 /// sig.verify_standalone(signer.public())?;
620 /// # Ok(())
621 /// # }
622 /// ```
623 pub fn sign_standalone(mut self, signer: &mut dyn Signer)
624 -> Result<Signature>
625 {
626 self = self.pre_sign(signer)?;
627
628 let mut hash =
629 self.hash_algo().context()?.for_signature(self.version());
630 self.hash_standalone(&mut hash)?;
631 self.sign(signer, hash.into_digest()?)
632 }
633
634 /// Generates a Timestamp Signature.
635 ///
636 /// Like a [Standalone Signature] (created using
637 /// [`SignatureBuilder::sign_standalone`]), a [Timestamp
638 /// Signature] is a self-contained signature, but its emphasis in
639 /// on the contained timestamp, specifically, the timestamp stored
640 /// in the [`Signature Creation Time`] subpacket. This type of
641 /// signature is primarily used by [timestamping services]. To
642 /// timestamp a signature, you can include either a [Signature
643 /// Target subpacket] (set using
644 /// [`SignatureBuilder::set_signature_target`]), or an [Embedded
645 /// Signature] (set using
646 /// [`SignatureBuilder::set_embedded_signature`]) in the hashed
647 /// area.
648 ///
649 ///
650 /// [Standalone Signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
651 /// [`SignatureBuilder::sign_standalone`]: SignatureBuilder::sign_standalone()
652 /// [Timestamp Signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
653 /// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
654 /// [timestamping services]: https://en.wikipedia.org/wiki/Trusted_timestamping
655 /// [Signature Target subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.33
656 /// [`SignatureBuilder::set_signature_target`]: SignatureBuilder::set_signature_target()
657 /// [Embedded Signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.34
658 /// [`SignatureBuilder::set_embedded_signature`]: SignatureBuilder::set_embedded_signature()
659 ///
660 /// This function checks that the [signature type] (passed to
661 /// [`SignatureBuilder::new`], set via
662 /// [`SignatureBuilder::set_type`], or copied when using
663 /// `SignatureBuilder::From`) is [`SignatureType::Timestamp`] or
664 /// [`SignatureType::Unknown`].
665 ///
666 /// [signature type]: crate::types::SignatureType
667 /// [`SignatureBuilder::new`]: SignatureBuilder::new()
668 /// [`SignatureBuilder::set_type`]: SignatureBuilder::set_type()
669 /// [`SignatureType::Timestamp`]: crate::types::SignatureType::Timestamp
670 /// [`SignatureType::Unknown`]: crate::types::SignatureType::Unknown
671 ///
672 /// The [`Signature`]'s public-key algorithm field is set to the
673 /// algorithm used by `signer`.
674 ///
675 /// [`Signature`]: super::Signature
676 ///
677 /// If neither an [`Issuer`] subpacket (set using
678 /// [`SignatureBuilder::set_issuer`], for instance) nor an
679 /// [`Issuer Fingerprint`] subpacket (set using
680 /// [`SignatureBuilder::set_issuer_fingerprint`], for instance) is
681 /// set, they are both added to the new `Signature`'s hashed
682 /// subpacket area and set to the `signer`'s `KeyID` and
683 /// `Fingerprint`, respectively.
684 ///
685 /// [`Issuer`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
686 /// [`SignatureBuilder::set_issuer`]: SignatureBuilder::set_issuer()
687 /// [`Issuer Fingerprint`]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
688 /// [`SignatureBuilder::set_issuer_fingerprint`]: SignatureBuilder::set_issuer_fingerprint()
689 ///
690 /// Likewise, a [`Signature Creation Time`] subpacket set to the
691 /// current time is added to the hashed area if the `Signature
692 /// Creation Time` subpacket hasn't been set using, for instance,
693 /// the [`set_signature_creation_time`] method or the
694 /// [`preserve_signature_creation_time`] method.
695 ///
696 /// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
697 /// [`set_signature_creation_time`]: SignatureBuilder::set_signature_creation_time()
698 /// [`preserve_signature_creation_time`]: SignatureBuilder::preserve_signature_creation_time()
699 ///
700 /// # Examples
701 ///
702 /// Create a timestamp signature:
703 ///
704 /// ```
705 /// use sequoia_openpgp as openpgp;
706 /// use openpgp::cert::prelude::*;
707 /// use openpgp::packet::prelude::*;
708 /// use openpgp::policy::StandardPolicy;
709 /// use openpgp::types::SignatureType;
710 ///
711 /// # fn main() -> openpgp::Result<()> {
712 /// let p = &StandardPolicy::new();
713 ///
714 /// let (cert, _) = CertBuilder::new().add_signing_subkey().generate()?;
715 ///
716 /// // Get a usable (alive, non-revoked) signing key.
717 /// let key : &Key<_, _> = cert
718 /// .keys().with_policy(p, None)
719 /// .for_signing().alive().revoked(false).nth(0).unwrap().key();
720 /// // Derive a signer.
721 /// let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
722 ///
723 /// let mut sig = SignatureBuilder::new(SignatureType::Timestamp)
724 /// .sign_timestamp(&mut signer)?;
725 ///
726 /// // Verify it.
727 /// sig.verify_timestamp(signer.public())?;
728 /// # Ok(())
729 /// # }
730 /// ```
731 pub fn sign_timestamp(mut self, signer: &mut dyn Signer)
732 -> Result<Signature>
733 {
734 self = self.pre_sign(signer)?;
735
736 let mut hash =
737 self.hash_algo().context()?.for_signature(self.version());
738 self.hash_timestamp(&mut hash)?;
739 self.sign(signer, hash.into_digest()?)
740 }
741
742 /// Generates a Direct Key Signature.
743 ///
744 /// A [Direct Key Signature] is a signature over the primary key.
745 /// It is primarily used to hold fallback [preferences]. For
746 /// instance, when addressing the Certificate by a User ID, the
747 /// OpenPGP implementation is supposed to look for preferences
748 /// like the [Preferred Symmetric Algorithms] on the User ID, and
749 /// only if there is no such packet, look on the direct key
750 /// signature.
751 ///
752 /// This function is also used to create a [Key Revocation
753 /// Signature], which revokes the certificate.
754 ///
755 /// [preferences]: crate::cert::Preferences
756 /// [Direct Key Signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
757 /// [Preferred Symmetric Algorithms]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.14
758 /// [Key Revocation Signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
759 ///
760 /// This function checks that the [signature type] (passed to
761 /// [`SignatureBuilder::new`], set via
762 /// [`SignatureBuilder::set_type`], or copied when using
763 /// `SignatureBuilder::From`) is [`SignatureType::DirectKey`],
764 /// [`SignatureType::KeyRevocation`], or
765 /// [`SignatureType::Unknown`].
766 ///
767 /// [signature type]: crate::types::SignatureType
768 /// [`SignatureBuilder::new`]: SignatureBuilder::new()
769 /// [`SignatureBuilder::set_type`]: SignatureBuilder::set_type()
770 /// [`SignatureType::DirectKey`]: crate::types::SignatureType::DirectKey
771 /// [`SignatureType::KeyRevocation`]: crate::types::SignatureType::KeyRevocation
772 /// [`SignatureType::Unknown`]: crate::types::SignatureType::Unknown
773 ///
774 /// The [`Signature`]'s public-key algorithm field is set to the
775 /// algorithm used by `signer`.
776 ///
777 /// [`Signature`]: super::Signature
778 ///
779 /// If neither an [`Issuer`] subpacket (set using
780 /// [`SignatureBuilder::set_issuer`], for instance) nor an
781 /// [`Issuer Fingerprint`] subpacket (set using
782 /// [`SignatureBuilder::set_issuer_fingerprint`], for instance) is
783 /// set, they are both added to the new `Signature`'s hashed
784 /// subpacket area and set to the `signer`'s `KeyID` and
785 /// `Fingerprint`, respectively.
786 ///
787 /// [`Issuer`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
788 /// [`SignatureBuilder::set_issuer`]: SignatureBuilder::set_issuer()
789 /// [`Issuer Fingerprint`]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
790 /// [`SignatureBuilder::set_issuer_fingerprint`]: SignatureBuilder::set_issuer_fingerprint()
791 ///
792 /// Likewise, a [`Signature Creation Time`] subpacket set to the
793 /// current time is added to the hashed area if the `Signature
794 /// Creation Time` subpacket hasn't been set using, for instance,
795 /// the [`set_signature_creation_time`] method or the
796 /// [`preserve_signature_creation_time`] method.
797 ///
798 /// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
799 /// [`set_signature_creation_time`]: SignatureBuilder::set_signature_creation_time()
800 /// [`preserve_signature_creation_time`]: SignatureBuilder::preserve_signature_creation_time()
801 ///
802 /// If `pk` is set to `None` the signature will be computed over the public key
803 /// retrieved from the `signer` parameter, i.e. a self-signature will be created.
804 /// To create a third-party-signature provide an explicit public key as the
805 /// `pk` parameter.
806 ///
807 /// # Examples
808 ///
809 /// Set the default value for the [Preferred Symmetric Algorithms
810 /// subpacket]:
811 ///
812 /// [Preferred Symmetric Algorithms subpacket]: SignatureBuilder::set_preferred_symmetric_algorithms()
813 ///
814 /// ```
815 /// use sequoia_openpgp as openpgp;
816 /// use openpgp::cert::prelude::*;
817 /// use openpgp::packet::prelude::*;
818 /// use openpgp::policy::StandardPolicy;
819 /// use openpgp::types::SignatureType;
820 /// use openpgp::types::SymmetricAlgorithm;
821 ///
822 /// # fn main() -> openpgp::Result<()> {
823 /// let p = &StandardPolicy::new();
824 ///
825 /// let (cert, _) = CertBuilder::new().add_signing_subkey().generate()?;
826 ///
827 /// // Get a usable (alive, non-revoked) certification key.
828 /// let key : &Key<_, _> = cert
829 /// .keys().with_policy(p, None)
830 /// .for_certification().alive().revoked(false).nth(0).unwrap().key();
831 /// // Derive a signer.
832 /// let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
833 ///
834 /// // A direct key signature is always over the primary key.
835 /// let pk = cert.primary_key().key();
836 ///
837 /// // Modify the existing direct key signature.
838 /// let mut sig = SignatureBuilder::from(
839 /// cert.with_policy(p, None)?.direct_key_signature()?.clone())
840 /// .set_preferred_symmetric_algorithms(
841 /// vec![ SymmetricAlgorithm::AES256,
842 /// SymmetricAlgorithm::AES128,
843 /// ])?
844 /// .sign_direct_key(&mut signer, None)?;
845 ///
846 /// // Verify it.
847 /// sig.verify_direct_key(signer.public(), pk)?;
848 /// # Ok(())
849 /// # }
850 /// ```
851 pub fn sign_direct_key<'a, PK>(mut self, signer: &mut dyn Signer,
852 pk: PK)
853 -> Result<Signature>
854 where PK: Into<Option<&'a Key<key::PublicParts, key::PrimaryRole>>>
855 {
856 self = self.pre_sign(signer)?;
857
858 let mut hash =
859 self.hash_algo().context()?.for_signature(self.version());
860 let pk = pk.into().unwrap_or_else(|| signer.public().role_as_primary());
861 self.hash_direct_key(&mut hash, pk)?;
862
863 self.sign(signer, hash.into_digest()?)
864 }
865
866 /// Generates a User ID binding signature.
867 ///
868 /// A User ID binding signature (a self signature) or a [User ID
869 /// certification] (a third-party signature) is a signature over a
870 /// `User ID` and a `Primary Key` made by a certification-capable
871 /// key. It asserts that the signer is convinced that the `User
872 /// ID` should be associated with the `Certificate`, i.e., that
873 /// the binding is authentic.
874 ///
875 /// [User ID certification]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
876 ///
877 /// OpenPGP has four types of `User ID` certifications. They are
878 /// intended to express the degree of the signer's conviction,
879 /// i.e., how well the signer authenticated the binding. In
880 /// practice, the `Positive Certification` type is used for
881 /// self-signatures, and the `Generic Certification` is used for
882 /// third-party certifications; the other types are not normally
883 /// used.
884 ///
885 /// This function is also used to create [Certification
886 /// Revocations].
887 ///
888 /// [Certification Revocations]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
889 ///
890 /// This function checks that the [signature type] (passed to
891 /// [`SignatureBuilder::new`], set via
892 /// [`SignatureBuilder::set_type`], or copied when using
893 /// `SignatureBuilder::From`) is [`GenericCertification`],
894 /// [`PersonaCertification`], [`CasualCertification`],
895 /// [`PositiveCertification`], [`CertificationRevocation`], or
896 /// [`SignatureType::Unknown`].
897 ///
898 /// [signature type]: crate::types::SignatureType
899 /// [`SignatureBuilder::new`]: SignatureBuilder::new()
900 /// [`SignatureBuilder::set_type`]: SignatureBuilder::set_type()
901 /// [`GenericCertification`]: crate::types::SignatureType::GenericCertification
902 /// [`PersonaCertification`]: crate::types::SignatureType::PersonaCertification
903 /// [`CasualCertification`]: crate::types::SignatureType::CasualCertification
904 /// [`PositiveCertification`]: crate::types::SignatureType::PositiveCertification
905 /// [`CertificationRevocation`]: crate::types::SignatureType::CertificationRevocation
906 /// [`SignatureType::Unknown`]: crate::types::SignatureType::Unknown
907 ///
908 /// The [`Signature`]'s public-key algorithm field is set to the
909 /// algorithm used by `signer`.
910 ///
911 /// [`Signature`]: super::Signature
912 ///
913 /// If neither an [`Issuer`] subpacket (set using
914 /// [`SignatureBuilder::set_issuer`], for instance) nor an
915 /// [`Issuer Fingerprint`] subpacket (set using
916 /// [`SignatureBuilder::set_issuer_fingerprint`], for instance) is
917 /// set, they are both added to the new `Signature`'s hashed
918 /// subpacket area and set to the `signer`'s `KeyID` and
919 /// `Fingerprint`, respectively.
920 ///
921 /// [`Issuer`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
922 /// [`SignatureBuilder::set_issuer`]: SignatureBuilder::set_issuer()
923 /// [`Issuer Fingerprint`]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
924 /// [`SignatureBuilder::set_issuer_fingerprint`]: SignatureBuilder::set_issuer_fingerprint()
925 ///
926 /// Likewise, a [`Signature Creation Time`] subpacket set to the
927 /// current time is added to the hashed area if the `Signature
928 /// Creation Time` subpacket hasn't been set using, for instance,
929 /// the [`set_signature_creation_time`] method or the
930 /// [`preserve_signature_creation_time`] method.
931 ///
932 /// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
933 /// [`set_signature_creation_time`]: SignatureBuilder::set_signature_creation_time()
934 /// [`preserve_signature_creation_time`]: SignatureBuilder::preserve_signature_creation_time()
935 ///
936 /// If `pk` is set to `None` the signature will be computed over the public key
937 /// retrieved from the `signer` parameter, i.e. a self-signature will be created.
938 /// To create a third-party-signature provide an explicit public key as the
939 /// `pk` parameter.
940 ///
941 /// # Examples
942 ///
943 /// Set the [Preferred Symmetric Algorithms subpacket], which will
944 /// be used when addressing the certificate via the associated
945 /// User ID:
946 ///
947 /// [Preferred Symmetric Algorithms subpacket]: SignatureBuilder::set_preferred_symmetric_algorithms()
948 ///
949 /// ```
950 /// use sequoia_openpgp as openpgp;
951 /// use openpgp::cert::prelude::*;
952 /// use openpgp::packet::prelude::*;
953 /// use openpgp::policy::StandardPolicy;
954 /// use openpgp::types::SymmetricAlgorithm;
955 ///
956 /// # fn main() -> openpgp::Result<()> {
957 /// let p = &StandardPolicy::new();
958 ///
959 /// let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
960 ///
961 /// // Get a usable (alive, non-revoked) certification key.
962 /// let key : &Key<_, _> = cert
963 /// .keys().with_policy(p, None)
964 /// .for_certification().alive().revoked(false).nth(0).unwrap().key();
965 /// // Derive a signer.
966 /// let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
967 ///
968 /// // Update the User ID's binding signature.
969 /// let ua = cert.with_policy(p, None)?.userids().nth(0).unwrap();
970 /// let mut new_sig = SignatureBuilder::from(
971 /// ua.binding_signature().clone())
972 /// .set_preferred_symmetric_algorithms(
973 /// vec![ SymmetricAlgorithm::AES256,
974 /// SymmetricAlgorithm::AES128,
975 /// ])?
976 /// .sign_userid_binding(&mut signer, None, ua.userid())?;
977 ///
978 /// // Verify it.
979 /// let pk = cert.primary_key().key();
980 ///
981 /// new_sig.verify_userid_binding(signer.public(), pk, ua.userid())?;
982 /// # Ok(())
983 /// # }
984 /// ```
985 pub fn sign_userid_binding<'a, PK>(mut self, signer: &mut dyn Signer,
986 key: PK, userid: &UserID)
987 -> Result<Signature>
988 where PK: Into<Option<&'a Key<key::PublicParts, key::PrimaryRole>>>
989 {
990 self = self.pre_sign(signer)?;
991
992 let key = key.into().unwrap_or_else(|| signer.public().role_as_primary());
993
994 let mut hash =
995 self.hash_algo().context()?.for_signature(self.version());
996 self.hash_userid_binding(&mut hash, key, userid)?;
997 self.sign(signer, hash.into_digest()?)
998 }
999
1000 /// Generates a subkey binding signature.
1001 ///
1002 /// A [subkey binding signature] is a signature over the primary
1003 /// key and a subkey, which is made by the primary key. It is an
1004 /// assertion by the certificate that the subkey really belongs to
1005 /// the certificate. That is, it binds the subkey to the
1006 /// certificate.
1007 ///
1008 /// Note: this function does not create a back signature, which is
1009 /// needed by certification-capable, signing-capable, and
1010 /// authentication-capable subkeys. A back signature can be
1011 /// created using [`SignatureBuilder::sign_primary_key_binding`].
1012 ///
1013 /// This function is also used to create subkey revocations.
1014 ///
1015 /// [subkey binding signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
1016 /// [`SignatureBuilder::sign_primary_key_binding`]: SignatureBuilder::sign_primary_key_binding()
1017 ///
1018 /// This function checks that the [signature type] (passed to
1019 /// [`SignatureBuilder::new`], set via
1020 /// [`SignatureBuilder::set_type`], or copied when using
1021 /// `SignatureBuilder::From`) is
1022 /// [`SignatureType::SubkeyBinding`], [`SignatureType::SubkeyRevocation`], or
1023 /// [`SignatureType::Unknown`].
1024 ///
1025 /// [signature type]: crate::types::SignatureType
1026 /// [`SignatureBuilder::new`]: SignatureBuilder::new()
1027 /// [`SignatureBuilder::set_type`]: SignatureBuilder::set_type()
1028 /// [`SignatureType::SubkeyBinding`]: crate::types::SignatureType::SubkeyBinding
1029 /// [`SignatureType::SubkeyRevocation`]: crate::types::SignatureType::SubkeyRevocation
1030 /// [`SignatureType::Unknown`]: crate::types::SignatureType::Unknown
1031 ///
1032 /// The [`Signature`]'s public-key algorithm field is set to the
1033 /// algorithm used by `signer`.
1034 ///
1035 /// [`Signature`]: super::Signature
1036 ///
1037 /// If neither an [`Issuer`] subpacket (set using
1038 /// [`SignatureBuilder::set_issuer`], for instance) nor an
1039 /// [`Issuer Fingerprint`] subpacket (set using
1040 /// [`SignatureBuilder::set_issuer_fingerprint`], for instance) is
1041 /// set, they are both added to the new `Signature`'s hashed
1042 /// subpacket area and set to the `signer`'s `KeyID` and
1043 /// `Fingerprint`, respectively.
1044 ///
1045 /// [`Issuer`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
1046 /// [`SignatureBuilder::set_issuer`]: SignatureBuilder::set_issuer()
1047 /// [`Issuer Fingerprint`]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
1048 /// [`SignatureBuilder::set_issuer_fingerprint`]: SignatureBuilder::set_issuer_fingerprint()
1049 ///
1050 /// Likewise, a [`Signature Creation Time`] subpacket set to the
1051 /// current time is added to the hashed area if the `Signature
1052 /// Creation Time` subpacket hasn't been set using, for instance,
1053 /// the [`set_signature_creation_time`] method or the
1054 /// [`preserve_signature_creation_time`] method.
1055 ///
1056 /// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
1057 /// [`set_signature_creation_time`]: SignatureBuilder::set_signature_creation_time()
1058 /// [`preserve_signature_creation_time`]: SignatureBuilder::preserve_signature_creation_time()
1059 ///
1060 /// If `pk` is set to `None` the signature will be computed over the public key
1061 /// retrieved from the `signer` parameter.
1062 ///
1063 /// # Examples
1064 ///
1065 /// Add a new subkey intended for encrypting data in motion to an
1066 /// existing certificate:
1067 ///
1068 /// ```
1069 /// use sequoia_openpgp as openpgp;
1070 /// use openpgp::cert::prelude::*;
1071 /// use openpgp::packet::prelude::*;
1072 /// use openpgp::policy::StandardPolicy;
1073 /// use openpgp::types::{Curve, KeyFlags, SignatureType};
1074 ///
1075 /// # fn main() -> openpgp::Result<()> {
1076 /// let p = &StandardPolicy::new();
1077 ///
1078 /// let (cert, _) = CertBuilder::new().generate()?;
1079 /// # assert_eq!(cert.keys().count(), 1);
1080 ///
1081 /// let pk = cert.primary_key().key().clone().parts_into_secret()?;
1082 /// // Derive a signer.
1083 /// let mut pk_signer = pk.clone().into_keypair()?;
1084 ///
1085 /// // Generate an encryption subkey.
1086 /// let mut subkey: Key<_, _> =
1087 /// Key6::generate_ecc(false, Curve::Cv25519)?.into();
1088 /// // Derive a signer.
1089 /// let mut sk_signer = subkey.clone().into_keypair()?;
1090 ///
1091 /// let sig = SignatureBuilder::new(SignatureType::SubkeyBinding)
1092 /// .set_key_flags(KeyFlags::empty().set_transport_encryption())?
1093 /// .sign_subkey_binding(&mut pk_signer, None, &subkey)?;
1094 ///
1095 /// let cert = cert.insert_packets(vec![Packet::SecretSubkey(subkey),
1096 /// sig.into()])?.0;
1097 ///
1098 /// assert_eq!(cert.with_policy(p, None)?.keys().count(), 2);
1099 /// # Ok(())
1100 /// # }
1101 /// ```
1102 pub fn sign_subkey_binding<'a, PK, Q>(mut self, signer: &mut dyn Signer,
1103 primary: PK,
1104 subkey: &Key<Q, key::SubordinateRole>)
1105 -> Result<Signature>
1106 where Q: key::KeyParts,
1107 PK: Into<Option<&'a Key<key::PublicParts, key::PrimaryRole>>>,
1108 {
1109 self = self.pre_sign(signer)?;
1110
1111 let primary = primary.into().unwrap_or_else(|| signer.public().role_as_primary());
1112 let mut hash =
1113 self.hash_algo().context()?.for_signature(self.version());
1114 self.hash_subkey_binding(&mut hash, primary, subkey)?;
1115 self.sign(signer, hash.into_digest()?)
1116 }
1117
1118 /// Generates a primary key binding signature.
1119 ///
1120 /// A [primary key binding signature], also referred to as a back
1121 /// signature or backsig, is a signature over the primary key and
1122 /// a subkey, which is made by the subkey. This signature is a
1123 /// statement by the subkey that it belongs to the primary key.
1124 /// That is, it binds the certificate to the subkey. It is
1125 /// normally stored in the subkey binding signature (see
1126 /// [`SignatureBuilder::sign_subkey_binding`]) in the [`Embedded
1127 /// Signature`] subpacket (set using
1128 /// [`SignatureBuilder::set_embedded_signature`]).
1129 ///
1130 /// [primary key binding signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
1131 /// [`SignatureBuilder::sign_subkey_binding`]: SignatureBuilder::sign_subkey_binding()
1132 /// [`Embedded Signature`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.34
1133 /// [`SignatureBuilder::set_embedded_signature`]: SignatureBuilder::set_embedded_signature()
1134 ///
1135 /// All subkeys that make signatures of any sort (signature
1136 /// subkeys, certification subkeys, and authentication subkeys)
1137 /// must include this signature in their binding signature. This
1138 /// signature ensures that an attacker (Mallory) can't claim
1139 /// someone else's (Alice's) signing key by just creating a subkey
1140 /// binding signature. If that were the case, anyone who has
1141 /// Mallory's certificate could be tricked into thinking that
1142 /// Mallory made signatures that were actually made by Alice.
1143 /// This signature prevents this attack, because it proves that
1144 /// the person who controls the private key for the primary key
1145 /// also controls the private key for the subkey and therefore
1146 /// intended that the subkey be associated with the primary key.
1147 /// Thus, although Mallory controls his own primary key and can
1148 /// issue a subkey binding signature for Alice's signing key, he
1149 /// doesn't control her signing key, and therefore can't create a
1150 /// valid backsig.
1151 ///
1152 /// A primary key binding signature is not needed for
1153 /// encryption-capable subkeys. This is firstly because
1154 /// encryption-capable keys cannot make signatures. But also
1155 /// because an attacker doesn't gain anything by adopting an
1156 /// encryption-capable subkey: without the private key material,
1157 /// they still can't read the message's content.
1158 ///
1159 /// This function checks that the [signature type] (passed to
1160 /// [`SignatureBuilder::new`], set via
1161 /// [`SignatureBuilder::set_type`], or copied when using
1162 /// `SignatureBuilder::From`) is
1163 /// [`SignatureType::PrimaryKeyBinding`], or
1164 /// [`SignatureType::Unknown`].
1165 ///
1166 /// [signature type]: crate::types::SignatureType
1167 /// [`SignatureBuilder::new`]: SignatureBuilder::new()
1168 /// [`SignatureBuilder::set_type`]: SignatureBuilder::set_type()
1169 /// [`SignatureType::PrimaryKeyBinding`]: crate::types::SignatureType::PrimaryKeyBinding
1170 /// [`SignatureType::Unknown`]: crate::types::SignatureType::Unknown
1171 ///
1172 /// The [`Signature`]'s public-key algorithm field is set to the
1173 /// algorithm used by `signer`.
1174 ///
1175 /// [`Signature`]: super::Signature
1176 ///
1177 /// If neither an [`Issuer`] subpacket (set using
1178 /// [`SignatureBuilder::set_issuer`], for instance) nor an
1179 /// [`Issuer Fingerprint`] subpacket (set using
1180 /// [`SignatureBuilder::set_issuer_fingerprint`], for instance) is
1181 /// set, they are both added to the new `Signature`'s hashed
1182 /// subpacket area and set to the `signer`'s `KeyID` and
1183 /// `Fingerprint`, respectively.
1184 ///
1185 /// [`Issuer`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
1186 /// [`SignatureBuilder::set_issuer`]: SignatureBuilder::set_issuer()
1187 /// [`Issuer Fingerprint`]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
1188 /// [`SignatureBuilder::set_issuer_fingerprint`]: SignatureBuilder::set_issuer_fingerprint()
1189 ///
1190 /// Likewise, a [`Signature Creation Time`] subpacket set to the
1191 /// current time is added to the hashed area if the `Signature
1192 /// Creation Time` subpacket hasn't been set using, for instance,
1193 /// the [`set_signature_creation_time`] method or the
1194 /// [`preserve_signature_creation_time`] method.
1195 ///
1196 /// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
1197 /// [`set_signature_creation_time`]: SignatureBuilder::set_signature_creation_time()
1198 /// [`preserve_signature_creation_time`]: SignatureBuilder::preserve_signature_creation_time()
1199 ///
1200 /// # Examples
1201 ///
1202 /// Add a new signing-capable subkey to an existing certificate.
1203 /// Because we are adding a signing-capable subkey, the binding
1204 /// signature needs to include a backsig.
1205 ///
1206 /// ```
1207 /// use sequoia_openpgp as openpgp;
1208 /// use openpgp::cert::prelude::*;
1209 /// use openpgp::packet::prelude::*;
1210 /// use openpgp::policy::StandardPolicy;
1211 /// use openpgp::types::{Curve, KeyFlags, SignatureType};
1212 ///
1213 /// # fn main() -> openpgp::Result<()> {
1214 /// let p = &StandardPolicy::new();
1215 ///
1216 /// let (cert, _) = CertBuilder::new().generate()?;
1217 /// # assert_eq!(cert.keys().count(), 1);
1218 ///
1219 /// let pk = cert.primary_key().key().clone().parts_into_secret()?;
1220 /// // Derive a signer.
1221 /// let mut pk_signer = pk.clone().into_keypair()?;
1222 ///
1223 /// // Generate a signing subkey.
1224 /// let mut subkey: Key<_, _> =
1225 /// Key6::generate_ecc(true, Curve::Ed25519)?.into();
1226 /// // Derive a signer.
1227 /// let mut sk_signer = subkey.clone().into_keypair()?;
1228 ///
1229 /// let sig = SignatureBuilder::new(SignatureType::SubkeyBinding)
1230 /// .set_key_flags(KeyFlags::empty().set_signing())?
1231 /// // The backsig. This is essential for subkeys that create signatures!
1232 /// .set_embedded_signature(
1233 /// SignatureBuilder::new(SignatureType::PrimaryKeyBinding)
1234 /// .sign_primary_key_binding(&mut sk_signer, &pk, &subkey)?)?
1235 /// .sign_subkey_binding(&mut pk_signer, None, &subkey)?;
1236 ///
1237 /// let cert = cert.insert_packets(vec![Packet::SecretSubkey(subkey),
1238 /// sig.into()])?.0;
1239 ///
1240 /// assert_eq!(cert.with_policy(p, None)?.keys().count(), 2);
1241 /// # assert_eq!(cert.bad_signatures().count(), 0);
1242 /// # Ok(())
1243 /// # }
1244 /// ```
1245 pub fn sign_primary_key_binding<P, Q>(mut self,
1246 subkey_signer: &mut dyn Signer,
1247 primary: &Key<P, key::PrimaryRole>,
1248 subkey: &Key<Q, key::SubordinateRole>)
1249 -> Result<Signature>
1250 where P: key::KeyParts,
1251 Q: key::KeyParts,
1252 {
1253 self = self.pre_sign(subkey_signer)?;
1254
1255 let mut hash =
1256 self.hash_algo().context()?.for_signature(self.version());
1257 self.hash_primary_key_binding(&mut hash, primary, subkey)?;
1258 self.sign(subkey_signer, hash.into_digest()?)
1259 }
1260
1261
1262 /// Generates a User Attribute binding signature.
1263 ///
1264 /// A User Attribute binding signature or certification, a type of
1265 /// [User ID certification], is a signature over a User Attribute
1266 /// and a Primary Key. It asserts that the signer is convinced
1267 /// that the User Attribute should be associated with the
1268 /// Certificate, i.e., that the binding is authentic.
1269 ///
1270 /// [User ID certification]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
1271 ///
1272 /// OpenPGP has four types of User Attribute certifications. They
1273 /// are intended to express the degree of the signer's conviction.
1274 /// In practice, the `Positive Certification` type is used for
1275 /// self-signatures, and the `Generic Certification` is used for
1276 /// third-party certifications; the other types are not normally
1277 /// used.
1278 ///
1279 /// This function checks that the [signature type] (passed to
1280 /// [`SignatureBuilder::new`], set via
1281 /// [`SignatureBuilder::set_type`], or copied when using
1282 /// `SignatureBuilder::From`) is [`GenericCertification`],
1283 /// [`PersonaCertification`], [`CasualCertification`],
1284 /// [`PositiveCertification`], [`CertificationRevocation`], or
1285 /// [`SignatureType::Unknown`].
1286 ///
1287 /// [signature type]: crate::types::SignatureType
1288 /// [`SignatureBuilder::new`]: SignatureBuilder::new()
1289 /// [`SignatureBuilder::set_type`]: SignatureBuilder::set_type()
1290 /// [`GenericCertification`]: crate::types::SignatureType::GenericCertification
1291 /// [`PersonaCertification`]: crate::types::SignatureType::PersonaCertification
1292 /// [`CasualCertification`]: crate::types::SignatureType::CasualCertification
1293 /// [`PositiveCertification`]: crate::types::SignatureType::PositiveCertification
1294 /// [`CertificationRevocation`]: crate::types::SignatureType::CertificationRevocation
1295 /// [`SignatureType::Unknown`]: crate::types::SignatureType::Unknown
1296 ///
1297 /// The [`Signature`]'s public-key algorithm field is set to the
1298 /// algorithm used by `signer`.
1299 ///
1300 /// [`Signature`]: super::Signature
1301 ///
1302 /// If neither an [`Issuer`] subpacket (set using
1303 /// [`SignatureBuilder::set_issuer`], for instance) nor an
1304 /// [`Issuer Fingerprint`] subpacket (set using
1305 /// [`SignatureBuilder::set_issuer_fingerprint`], for instance) is
1306 /// set, they are both added to the new `Signature`'s hashed
1307 /// subpacket area and set to the `signer`'s `KeyID` and
1308 /// `Fingerprint`, respectively.
1309 ///
1310 /// [`Issuer`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
1311 /// [`SignatureBuilder::set_issuer`]: SignatureBuilder::set_issuer()
1312 /// [`Issuer Fingerprint`]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
1313 /// [`SignatureBuilder::set_issuer_fingerprint`]: SignatureBuilder::set_issuer_fingerprint()
1314 ///
1315 /// Likewise, a [`Signature Creation Time`] subpacket set to the
1316 /// current time is added to the hashed area if the `Signature
1317 /// Creation Time` subpacket hasn't been set using, for instance,
1318 /// the [`set_signature_creation_time`] method or the
1319 /// [`preserve_signature_creation_time`] method.
1320 ///
1321 /// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
1322 /// [`set_signature_creation_time`]: SignatureBuilder::set_signature_creation_time()
1323 /// [`preserve_signature_creation_time`]: SignatureBuilder::preserve_signature_creation_time()
1324 ///
1325 /// If `pk` is set to `None` the signature will be computed over the public key
1326 /// retrieved from the `signer` parameter, i.e. a self-signature will be created.
1327 /// To create a third-party-signature provide an explicit public key as the
1328 /// `pk` parameter.
1329 ///
1330 /// # Examples
1331 ///
1332 /// Add a new User Attribute to an existing certificate:
1333 ///
1334 /// ```
1335 /// use sequoia_openpgp as openpgp;
1336 /// use openpgp::cert::prelude::*;
1337 /// use openpgp::packet::prelude::*;
1338 /// use openpgp::policy::StandardPolicy;
1339 /// use openpgp::types::SignatureType;
1340 /// # use openpgp::packet::user_attribute::{Subpacket, Image};
1341 ///
1342 /// # fn main() -> openpgp::Result<()> {
1343 /// let p = &StandardPolicy::new();
1344 ///
1345 /// # // Add a bare user attribute.
1346 /// # let ua = UserAttribute::new(&[
1347 /// # Subpacket::Image(
1348 /// # Image::Private(100, vec![0, 1, 2].into_boxed_slice())),
1349 /// # ])?;
1350 /// #
1351 /// let (cert, _) = CertBuilder::new().generate()?;
1352 /// # assert_eq!(cert.user_attributes().count(), 0);
1353 ///
1354 /// // Add a user attribute.
1355 ///
1356 /// // Get a usable (alive, non-revoked) certification key.
1357 /// let key : &Key<_, _> = cert
1358 /// .keys().with_policy(p, None)
1359 /// .for_certification().alive().revoked(false).nth(0).unwrap().key();
1360 /// // Derive a signer.
1361 /// let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
1362 ///
1363 /// let pk = cert.primary_key().key();
1364 ///
1365 /// let mut sig =
1366 /// SignatureBuilder::new(SignatureType::PositiveCertification)
1367 /// .sign_user_attribute_binding(&mut signer, None, &ua)?;
1368 ///
1369 /// // Verify it.
1370 /// sig.verify_user_attribute_binding(signer.public(), pk, &ua)?;
1371 ///
1372 /// let cert = cert.insert_packets(vec![Packet::from(ua), sig.into()])?.0;
1373 /// assert_eq!(cert.with_policy(p, None)?.user_attributes().count(), 1);
1374 /// # Ok(())
1375 /// # }
1376 /// ```
1377 pub fn sign_user_attribute_binding<'a, PK>(mut self, signer: &mut dyn Signer,
1378 key: PK, ua: &UserAttribute)
1379 -> Result<Signature>
1380 where PK: Into<Option<&'a Key<key::PublicParts, key::PrimaryRole>>>
1381 {
1382 self = self.pre_sign(signer)?;
1383
1384 let key = key.into().unwrap_or_else(|| signer.public().role_as_primary());
1385
1386 let mut hash =
1387 self.hash_algo().context()?.for_signature(self.version());
1388 self.hash_user_attribute_binding(&mut hash, key, ua)?;
1389 self.sign(signer, hash.into_digest()?)
1390 }
1391
1392 /// Generates a signature.
1393 ///
1394 /// This is a low-level function. Normally, you'll want to use
1395 /// one of the higher-level functions, like
1396 /// [`SignatureBuilder::sign_userid_binding`]. But, this function
1397 /// is useful if you want to create a [`Signature`] for an
1398 /// unsupported signature type.
1399 ///
1400 /// [`SignatureBuilder::sign_userid_binding`]: SignatureBuilder::sign_userid_binding()
1401 /// [`Signature`]: super::Signature
1402 ///
1403 /// The `Signature`'s public-key algorithm field is set to the
1404 /// algorithm used by `signer`.
1405 ///
1406 /// If neither an [`Issuer`] subpacket (set using
1407 /// [`SignatureBuilder::set_issuer`], for instance) nor an
1408 /// [`Issuer Fingerprint`] subpacket (set using
1409 /// [`SignatureBuilder::set_issuer_fingerprint`], for instance) is
1410 /// set, they are both added to the new `Signature`'s hashed
1411 /// subpacket area and set to the `signer`'s `KeyID` and
1412 /// `Fingerprint`, respectively.
1413 ///
1414 /// [`Issuer`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
1415 /// [`SignatureBuilder::set_issuer`]: SignatureBuilder::set_issuer()
1416 /// [`Issuer Fingerprint`]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
1417 /// [`SignatureBuilder::set_issuer_fingerprint`]: SignatureBuilder::set_issuer_fingerprint()
1418 ///
1419 /// Likewise, a [`Signature Creation Time`] subpacket set to the
1420 /// current time is added to the hashed area if the `Signature
1421 /// Creation Time` subpacket hasn't been set using, for instance,
1422 /// the [`set_signature_creation_time`] method or the
1423 /// [`preserve_signature_creation_time`] method.
1424 ///
1425 /// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
1426 /// [`set_signature_creation_time`]: SignatureBuilder::set_signature_creation_time()
1427 /// [`preserve_signature_creation_time`]: SignatureBuilder::preserve_signature_creation_time()
1428 pub fn sign_hash(mut self, signer: &mut dyn Signer,
1429 mut hash: hash::Context)
1430 -> Result<Signature>
1431 {
1432 self.hash_algo = hash.algo();
1433
1434 self = self.pre_sign(signer)?;
1435
1436 self.hash(&mut hash)?;
1437 let mut digest = vec![0u8; hash.digest_size()];
1438 hash.digest(&mut digest)?;
1439
1440 self.sign(signer, digest)
1441 }
1442
1443 /// Signs a message.
1444 ///
1445 /// Normally, you'll want to use the [streaming `Signer`] to sign
1446 /// a message.
1447 ///
1448 /// [streaming `Signer`]: crate::serialize::stream::Signer
1449 ///
1450 /// OpenPGP supports two types of signatures over messages: binary
1451 /// and text. The text version normalizes line endings. But,
1452 /// since nearly all software today can deal with both Unix and
1453 /// DOS line endings, it is better to just use the binary version
1454 /// even when dealing with text. This avoids any possible
1455 /// ambiguity.
1456 ///
1457 /// This function checks that the [signature type] (passed to
1458 /// [`SignatureBuilder::new`], set via
1459 /// [`SignatureBuilder::set_type`], or copied when using
1460 /// `SignatureBuilder::From`) is [`Binary`], [`Text`], or
1461 /// [`SignatureType::Unknown`].
1462 ///
1463 /// [signature type]: crate::types::SignatureType
1464 /// [`SignatureBuilder::new`]: SignatureBuilder::new()
1465 /// [`SignatureBuilder::set_type`]: SignatureBuilder::set_type()
1466 /// [`Binary`]: crate::types::SignatureType::Binary
1467 /// [`Text`]: crate::types::SignatureType::Text
1468 /// [`SignatureType::Unknown`]: crate::types::SignatureType::Unknown
1469 ///
1470 /// The [`Signature`]'s public-key algorithm field is set to the
1471 /// algorithm used by `signer`.
1472 ///
1473 /// [`Signature`]: super::Signature
1474 ///
1475 /// If neither an [`Issuer`] subpacket (set using
1476 /// [`SignatureBuilder::set_issuer`], for instance) nor an
1477 /// [`Issuer Fingerprint`] subpacket (set using
1478 /// [`SignatureBuilder::set_issuer_fingerprint`], for instance) is
1479 /// set, they are both added to the new `Signature`'s hashed
1480 /// subpacket area and set to the `signer`'s `KeyID` and
1481 /// `Fingerprint`, respectively.
1482 ///
1483 /// [`Issuer`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
1484 /// [`SignatureBuilder::set_issuer`]: SignatureBuilder::set_issuer()
1485 /// [`Issuer Fingerprint`]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
1486 /// [`SignatureBuilder::set_issuer_fingerprint`]: SignatureBuilder::set_issuer_fingerprint()
1487 ///
1488 /// Likewise, a [`Signature Creation Time`] subpacket set to the
1489 /// current time is added to the hashed area if the `Signature
1490 /// Creation Time` subpacket hasn't been set using, for instance,
1491 /// the [`set_signature_creation_time`] method or the
1492 /// [`preserve_signature_creation_time`] method.
1493 ///
1494 /// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
1495 /// [`set_signature_creation_time`]: SignatureBuilder::set_signature_creation_time()
1496 /// [`preserve_signature_creation_time`]: SignatureBuilder::preserve_signature_creation_time()
1497 ///
1498 /// # Examples
1499 ///
1500 /// Signs a document. For large messages, you should use the
1501 /// [streaming `Signer`], which streams the message's content.
1502 ///
1503 /// [streaming `Signer`]: crate::serialize::stream::Signer
1504 ///
1505 /// ```
1506 /// use sequoia_openpgp as openpgp;
1507 /// use openpgp::cert::prelude::*;
1508 /// use openpgp::packet::prelude::*;
1509 /// use openpgp::policy::StandardPolicy;
1510 /// use openpgp::types::SignatureType;
1511 ///
1512 /// # fn main() -> openpgp::Result<()> {
1513 /// let p = &StandardPolicy::new();
1514 ///
1515 /// let (cert, _) = CertBuilder::new().add_signing_subkey().generate()?;
1516 ///
1517 /// // Get a usable (alive, non-revoked) signing key.
1518 /// let key : &Key<_, _> = cert
1519 /// .keys().with_policy(p, None)
1520 /// .for_signing().alive().revoked(false).nth(0).unwrap().key();
1521 /// // Derive a signer.
1522 /// let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
1523 ///
1524 /// // For large messages, you should use openpgp::serialize::stream::Signer,
1525 /// // which streams the message's content.
1526 /// let msg = b"Hello, world!";
1527 /// let mut sig = SignatureBuilder::new(SignatureType::Binary)
1528 /// .sign_message(&mut signer, msg)?;
1529 ///
1530 /// // Verify it.
1531 /// sig.verify_message(signer.public(), msg)?;
1532 /// # Ok(())
1533 /// # }
1534 /// ```
1535 pub fn sign_message<M>(mut self, signer: &mut dyn Signer, msg: M)
1536 -> Result<Signature>
1537 where M: AsRef<[u8]>
1538 {
1539 match self.typ {
1540 SignatureType::Binary => (),
1541 SignatureType::Text => (),
1542 SignatureType::Unknown(_) => (),
1543 _ => return Err(Error::UnsupportedSignatureType(self.typ).into()),
1544 }
1545
1546 self = self.pre_sign(signer)?;
1547
1548 // Hash the message
1549 let mut hash =
1550 self.hash_algo.context()?.for_signature(self.version());
1551 if let Some(salt) = self.sb_version.salt() {
1552 hash.update(salt);
1553 }
1554 hash.update(msg.as_ref());
1555
1556 self.hash(&mut hash)?;
1557 let mut digest = vec![0u8; hash.digest_size()];
1558 hash.digest(&mut digest)?;
1559
1560 self.sign(signer, digest)
1561 }
1562
1563 /// Sets the signature builder's default reference time.
1564 ///
1565 /// The reference time is used when no time is specified. The
1566 /// reference time is the current time by default and is evaluated
1567 /// on demand.
1568 ///
1569 /// # Examples
1570 ///
1571 /// ```
1572 /// use std::time::{Duration, SystemTime};
1573 /// use sequoia_openpgp as openpgp;
1574 /// use openpgp::types::SignatureType;
1575 /// use openpgp::packet::prelude::*;
1576 ///
1577 /// # fn main() -> openpgp::Result<()> {
1578 /// #
1579 /// // If we don't set a reference time, then the current time is used
1580 /// // when the signature is created.
1581 /// let sig = SignatureBuilder::new(SignatureType::PositiveCertification);
1582 /// let ct = sig.effective_signature_creation_time()?.expect("creation time");
1583 /// assert!(SystemTime::now().duration_since(ct).expect("ct is in the past")
1584 /// < Duration::new(1, 0));
1585 ///
1586 /// // If we set a reference time and don't set a creation time,
1587 /// // then that time is used for the creation time.
1588 /// let t = std::time::UNIX_EPOCH + Duration::new(1646660000, 0);
1589 /// let sig = sig.set_reference_time(t)?;
1590 /// assert_eq!(sig.effective_signature_creation_time()?, Some(t));
1591 /// # Ok(()) }
1592 /// ```
1593 pub fn set_reference_time<T>(mut self, reference_time: T) -> Result<Self>
1594 where
1595 T: Into<Option<SystemTime>>,
1596 {
1597 let reference_time = reference_time.into();
1598
1599 // Make sure the time is representable.
1600 if let Some(t) = reference_time.clone() {
1601 Timestamp::try_from(t)?;
1602 }
1603
1604 self.reference_time = reference_time;
1605 Ok(self)
1606 }
1607
1608 /// Returns the signature creation time that would be used if a
1609 /// signature were created now.
1610 ///
1611 /// # Examples
1612 ///
1613 /// ```
1614 /// use std::time::{Duration, SystemTime};
1615 /// use sequoia_openpgp as openpgp;
1616 /// use openpgp::types::SignatureType;
1617 /// use openpgp::packet::prelude::*;
1618 ///
1619 /// # fn main() -> openpgp::Result<()> {
1620 /// #
1621 /// // If we don't set a creation time, then the current time is used.
1622 /// let sig = SignatureBuilder::new(SignatureType::PositiveCertification);
1623 /// let ct = sig.effective_signature_creation_time()?.expect("creation time");
1624 /// assert!(SystemTime::now().duration_since(ct).expect("ct is in the past")
1625 /// < Duration::new(1, 0));
1626 ///
1627 /// // If we set a signature creation time, then we should get it back.
1628 /// let t = SystemTime::now() - Duration::new(24 * 60 * 60, 0);
1629 /// let sig = sig.set_signature_creation_time(t)?;
1630 /// assert!(t.duration_since(
1631 /// sig.effective_signature_creation_time()?.unwrap()).unwrap()
1632 /// < Duration::new(1, 0));
1633 /// # Ok(()) }
1634 /// ```
1635 pub fn effective_signature_creation_time(&self)
1636 -> Result<Option<SystemTime>>
1637 {
1638 use std::time;
1639
1640 let now = || -> Result<SystemTime> {
1641 let rt = self.reference_time.unwrap_or_else(crate::now);
1642 // Roundtrip via Timestamp to ensure that the time has the
1643 // right resolution and is representable.
1644 Ok(SystemTime::from(Timestamp::try_from(rt)?))
1645 };
1646
1647 if ! self.overrode_creation_time {
1648 // See if we want to backdate the signature.
1649 if let Some(orig) = self.original_creation_time {
1650 let now = now()?;
1651 let t =
1652 (orig + time::Duration::new(1, 0)).max(
1653 now - time::Duration::new(SIG_BACKDATE_BY, 0));
1654
1655 if t > now {
1656 return Err(Error::InvalidOperation(
1657 "Cannot create valid signature newer than SignatureBuilder template"
1658 .into()).into());
1659 }
1660
1661 Ok(Some(t))
1662 } else {
1663 Ok(Some(now()?))
1664 }
1665 } else {
1666 Ok(self.signature_creation_time())
1667 }
1668 }
1669
1670 /// Adjusts signature prior to signing.
1671 ///
1672 /// This function is called implicitly when a signature is created
1673 /// (e.g. using [`SignatureBuilder::sign_message`]). Usually,
1674 /// there is no need to call it explicitly.
1675 ///
1676 /// This function makes sure that generated signatures have a
1677 /// creation time, issuer information, and are not predictable by
1678 /// including a salt. Then, it sorts the subpackets. The
1679 /// function is idempotent modulo salt value.
1680 ///
1681 /// # Examples
1682 ///
1683 /// Occasionally, it is useful to determine the available space in
1684 /// a subpacket area. To take the effect of this function into
1685 /// account, call this function explicitly:
1686 ///
1687 /// ```
1688 /// # use sequoia_openpgp as openpgp;
1689 /// # fn main() -> openpgp::Result<()> {
1690 /// # use openpgp::packet::prelude::*;
1691 /// # use openpgp::types::Curve;
1692 /// # use openpgp::packet::signature::subpacket::SubpacketArea;
1693 /// # use openpgp::types::SignatureType;
1694 /// #
1695 /// # let key: Key<key::SecretParts, key::PrimaryRole>
1696 /// # = Key::from(Key6::generate_ecc(true, Curve::Ed25519)?);
1697 /// # let mut signer = key.into_keypair()?;
1698 /// let sig = SignatureBuilder::new(SignatureType::Binary)
1699 /// .pre_sign(&mut signer)?; // Important for size calculation.
1700 ///
1701 /// // Compute the available space in the hashed area. For this,
1702 /// // it is important that template.pre_sign has been called.
1703 /// use openpgp::serialize::MarshalInto;
1704 /// let available_space =
1705 /// SubpacketArea::MAX_SIZE - sig.hashed_area().serialized_len();
1706 ///
1707 /// // Let's check whether our prediction was right.
1708 /// let sig = sig.sign_message(&mut signer, b"Hello World :)")?;
1709 /// assert_eq!(
1710 /// available_space,
1711 /// SubpacketArea::MAX_SIZE - sig.hashed_area().serialized_len());
1712 /// # Ok(()) }
1713 /// ```
1714 pub fn pre_sign(mut self, signer: &dyn Signer) -> Result<Self> {
1715 let pk = signer.public();
1716 self.pk_algo = pk.pk_algo();
1717
1718 // Set the version. A Key6 will create a Signature6, a key4
1719 // will create a Signature4. If necessary, generate a salt.
1720 // If the salt has been explicitly set, it is not changed.
1721 self.sb_version = match (self.sb_version, pk.version()) {
1722 (SBVersion::V4 {}, 4) => SBVersion::V4 {},
1723 (SBVersion::V6 { .. }, 4) => SBVersion::V4 {},
1724 (SBVersion::V4 {}, 6) => {
1725 let mut salt = vec![0; self.fields.hash_algo().salt_size()?];
1726 crate::crypto::random(&mut salt)?;
1727 SBVersion::V6 { salt }
1728 },
1729 (SBVersion::V6 { salt }, 6) => SBVersion::V6 { salt },
1730 (_, n) => return Err(Error::InvalidOperation(
1731 format!("Unsupported key version {}", n)).into()),
1732 };
1733
1734 // Update the version in the field's struct.
1735 self.fields.version = self.sb_version.to_u8();
1736
1737 // Set the creation time.
1738 if ! self.overrode_creation_time {
1739 if let Some(t) = self.effective_signature_creation_time()? {
1740 self = self.set_signature_creation_time(t)?;
1741 }
1742 }
1743
1744 match &self.sb_version {
1745 SBVersion::V4 {} => {
1746 // Make sure we have an issuer packet.
1747 if self.issuers().next().is_none()
1748 && self.issuer_fingerprints().next().is_none()
1749 {
1750 self = self.set_issuer(signer.public().keyid())?
1751 .set_issuer_fingerprint(signer.public().fingerprint())?;
1752 }
1753
1754 // Add a salt to v4 signatures to make the signature
1755 // unpredictable.
1756 let mut salt = [0; 32];
1757 crate::crypto::random(&mut salt)?;
1758 self = self.set_notation("salt@notations.sequoia-pgp.org",
1759 salt, None, false)?;
1760 },
1761 SBVersion::V6 { .. } => {
1762 // Make sure we have an issuer fingerprint packet.
1763 if self.issuer_fingerprints().next().is_none() {
1764 self = self
1765 .set_issuer_fingerprint(signer.public().fingerprint())?;
1766 }
1767
1768 // In v6 signatures, we have a proper prefix salt.
1769 },
1770 }
1771
1772 self.sort();
1773
1774 Ok(self)
1775 }
1776
1777 /// Returns the prefix salt.
1778 ///
1779 /// In OpenPGP v6 signatures, a salt is prefixed to the data
1780 /// stream hashed in the signature. If a v6 signature is
1781 /// generated by using a v6 key, then a salt will be added
1782 /// automatically. If a salt has been set explicitly (see
1783 /// [`SignatureBuilder::set_prefix_salt`]), this function will
1784 /// return the salt.
1785 pub fn prefix_salt(&self) -> Option<&[u8]> {
1786 match &self.sb_version {
1787 SBVersion::V4 {} => None,
1788 SBVersion::V6 { salt } => Some(salt),
1789 }
1790 }
1791
1792 /// Explicitly sets the prefix salt.
1793 ///
1794 /// In OpenPGP v6 signatures, a salt is prefixed to the data
1795 /// stream hashed in the signature. If a v6 signature is
1796 /// generated by using a v6 key, then a salt will be added
1797 /// automatically. In general, you do not need to call this
1798 /// function.
1799 ///
1800 /// When streaming a signed message, it is useful to explicitly
1801 /// set the salt using this function.
1802 pub fn set_prefix_salt(mut self, new_salt: Vec<u8>) -> (Self, Option<Vec<u8>>) {
1803 let mut old = None;
1804
1805 self.sb_version = match std::mem::take(&mut self.sb_version) {
1806 SBVersion::V4 {} => SBVersion::V6 { salt: new_salt },
1807 SBVersion::V6 { salt } => {
1808 old = Some(salt);
1809 SBVersion::V6 { salt: new_salt }
1810 },
1811 };
1812
1813 (self, old)
1814 }
1815
1816 fn sign(self, signer: &mut dyn Signer, digest: Vec<u8>)
1817 -> Result<Signature>
1818 {
1819 // DSA is phased out in RFC9580.
1820 #[allow(deprecated)]
1821 if matches!(self.sb_version, SBVersion::V6 { .. })
1822 && self.fields.pk_algo() == PublicKeyAlgorithm::DSA
1823 {
1824 return Err(Error::BadSignature(
1825 "Version 6 signatures using DSA MUST NOT be created".into())
1826 .into());
1827 }
1828
1829 let mpis = signer.sign(self.hash_algo, &digest)?;
1830 let v4 = Signature4 {
1831 common: Default::default(),
1832 fields: self.fields,
1833 digest_prefix: [digest[0], digest[1]],
1834 mpis,
1835 computed_digest: digest.into(),
1836 level: 0,
1837 additional_issuers: OnceLock::new(),
1838 };
1839
1840 match self.sb_version {
1841 SBVersion::V4 {} => Ok(v4.into()),
1842 SBVersion::V6 { salt } =>
1843 Ok(Signature6::from_common(v4, salt)?.into())
1844 }
1845 }
1846}
1847
1848impl From<Signature> for SignatureBuilder {
1849 fn from(sig: Signature) -> Self {
1850 match sig {
1851 Signature::V3(sig) => sig.into(),
1852 Signature::V4(sig) => sig.into(),
1853 Signature::V6(sig) => sig.into(),
1854 }
1855 }
1856}
1857
1858impl From<Signature4> for SignatureBuilder {
1859 fn from(sig: Signature4) -> Self {
1860 let mut fields = sig.fields;
1861
1862 fields.hash_algo = HashAlgorithm::default();
1863
1864 let creation_time = fields.signature_creation_time();
1865
1866 fields.hashed_area_mut().remove_all(SubpacketTag::SignatureCreationTime);
1867 fields.hashed_area_mut().remove_all(SubpacketTag::Issuer);
1868 fields.hashed_area_mut().remove_all(SubpacketTag::IssuerFingerprint);
1869
1870 fields.unhashed_area_mut().remove_all(SubpacketTag::SignatureCreationTime);
1871 fields.unhashed_area_mut().remove_all(SubpacketTag::Issuer);
1872 fields.unhashed_area_mut().remove_all(SubpacketTag::IssuerFingerprint);
1873
1874 SignatureBuilder {
1875 reference_time: None,
1876 overrode_creation_time: false,
1877 original_creation_time: creation_time,
1878 fields,
1879 sb_version: Default::default(),
1880 }
1881 }
1882}
1883
1884impl From<Signature6> for SignatureBuilder {
1885 fn from(sig: Signature6) -> Self {
1886 SignatureBuilder::from(sig.common)
1887 }
1888}
1889
1890/// Holds a v4 Signature packet.
1891///
1892/// This holds a [version 4] Signature packet. Normally, you won't
1893/// directly work with this data structure, but with the [`Signature`]
1894/// enum, which is version agnostic. An exception is when you need to
1895/// do version-specific operations. But currently, there aren't any
1896/// version-specific methods.
1897///
1898/// [version 4]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2
1899/// [`Signature`]: super::Signature
1900#[derive(Clone)]
1901pub struct Signature4 {
1902 /// CTB packet header fields.
1903 pub(crate) common: packet::Common,
1904
1905 /// Fields as configured using the SignatureBuilder.
1906 pub(crate) fields: SignatureFields,
1907
1908 /// Upper 16 bits of the signed hash value.
1909 digest_prefix: [u8; 2],
1910 /// Signature MPIs.
1911 mpis: mpi::Signature,
1912
1913 /// The computed digest.
1914 ///
1915 /// When used in conjunction with a one-pass signature, this is the
1916 /// hash computed over the enclosed message.
1917 ///
1918 /// This is also set when a signature is successfully verified,
1919 /// and on signatures during certificate canonicalization.
1920 computed_digest: OnceLock<Vec<u8>>,
1921
1922 /// Signature level.
1923 ///
1924 /// A level of 0 indicates that the signature is directly over the
1925 /// data, a level of 1 means that the signature is a notarization
1926 /// over all level 0 signatures and the data, and so on.
1927 level: usize,
1928
1929 /// Additional issuer information.
1930 ///
1931 /// When we verify a signature successfully, we know the key that
1932 /// made the signature. Hence, we can compute the fingerprint,
1933 /// either a V4 one or a later one. If this information is
1934 /// missing from the signature, we can add it to the unhashed
1935 /// subpacket area at a convenient time. We don't add it when
1936 /// verifying, because that would mean that verifying a signature
1937 /// would change the serialized representation, and signature
1938 /// verification is usually expected to be idempotent.
1939 additional_issuers: OnceLock<Vec<KeyHandle>>,
1940}
1941assert_send_and_sync!(Signature4);
1942
1943impl fmt::Debug for Signature4 {
1944 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1945 f.debug_struct("Signature4")
1946 .field("version", &self.version())
1947 .field("typ", &self.typ())
1948 .field("pk_algo", &self.pk_algo())
1949 .field("hash_algo", &self.hash_algo())
1950 .field("hashed_area", self.hashed_area())
1951 .field("unhashed_area", self.unhashed_area())
1952 .field("additional_issuers", &self.additional_issuers())
1953 .field("digest_prefix",
1954 &crate::fmt::to_hex(&self.digest_prefix, false))
1955 .field(
1956 "computed_digest",
1957 &self
1958 .computed_digest
1959 .get()
1960 .map(|hash| crate::fmt::to_hex(&hash[..], false)),
1961 )
1962 .field("level", &self.level)
1963 .field("mpis", &self.mpis)
1964 .finish()
1965 }
1966}
1967
1968impl PartialEq for Signature4 {
1969 /// This method tests for self and other values to be equal, and
1970 /// is used by ==.
1971 ///
1972 /// This method compares the serialized version of the two
1973 /// packets. Thus, the computed values are ignored ([`level`],
1974 /// [`computed_digest`]).
1975 ///
1976 /// Note: because this function also compares the unhashed
1977 /// subpacket area, it is possible for a malicious party to take
1978 /// valid signatures, add subpackets to the unhashed area,
1979 /// yielding valid but distinct signatures. If you want to ignore
1980 /// the unhashed area, you should instead use the
1981 /// [`Signature::normalized_eq`] method.
1982 ///
1983 /// [`level`]: Signature4::level()
1984 /// [`computed_digest`]: Signature4::computed_digest()
1985 fn eq(&self, other: &Signature4) -> bool {
1986 self.cmp(other) == Ordering::Equal
1987 }
1988}
1989
1990impl Eq for Signature4 {}
1991
1992impl PartialOrd for Signature4 {
1993 fn partial_cmp(&self, other: &Signature4) -> Option<Ordering> {
1994 Some(self.cmp(other))
1995 }
1996}
1997
1998impl Ord for Signature4 {
1999 fn cmp(&self, other: &Signature4) -> Ordering {
2000 self.fields.cmp(&other.fields)
2001 .then_with(|| self.digest_prefix.cmp(&other.digest_prefix))
2002 .then_with(|| self.mpis.cmp(&other.mpis))
2003 }
2004}
2005
2006impl std::hash::Hash for Signature4 {
2007 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
2008 use std::hash::Hash as StdHash;
2009 StdHash::hash(&self.mpis, state);
2010 StdHash::hash(&self.fields, state);
2011 self.digest_prefix.hash(state);
2012 }
2013}
2014
2015impl Signature4 {
2016 /// Creates a new signature packet.
2017 ///
2018 /// If you want to sign something, consider using the [`SignatureBuilder`]
2019 /// interface.
2020 pub fn new(typ: SignatureType, pk_algo: PublicKeyAlgorithm,
2021 hash_algo: HashAlgorithm, hashed_area: SubpacketArea,
2022 unhashed_area: SubpacketArea,
2023 digest_prefix: [u8; 2],
2024 mpis: mpi::Signature) -> Self {
2025 Signature4 {
2026 common: Default::default(),
2027 fields: SignatureFields {
2028 version: 4,
2029 typ,
2030 pk_algo,
2031 hash_algo,
2032 subpackets: SubpacketAreas::new(hashed_area, unhashed_area),
2033 },
2034 digest_prefix,
2035 mpis,
2036 computed_digest: OnceLock::new(),
2037 level: 0,
2038 additional_issuers: OnceLock::new(),
2039 }
2040 }
2041
2042 /// Gets the public key algorithm.
2043 // SigantureFields::pk_algo is private, because we don't want it
2044 // available on SignatureBuilder, which also derefs to
2045 // &SignatureFields.
2046 pub fn pk_algo(&self) -> PublicKeyAlgorithm {
2047 self.fields.pk_algo()
2048 }
2049
2050 /// Gets the hash prefix.
2051 pub fn digest_prefix(&self) -> &[u8; 2] {
2052 &self.digest_prefix
2053 }
2054
2055 /// Sets the hash prefix.
2056 #[allow(dead_code)]
2057 pub(crate) fn set_digest_prefix(&mut self, prefix: [u8; 2]) -> [u8; 2] {
2058 ::std::mem::replace(&mut self.digest_prefix, prefix)
2059 }
2060
2061 /// Gets the signature packet's MPIs.
2062 pub fn mpis(&self) -> &mpi::Signature {
2063 &self.mpis
2064 }
2065
2066 /// Sets the signature packet's MPIs.
2067 #[allow(dead_code)]
2068 pub(crate) fn set_mpis(&mut self, mpis: mpi::Signature) -> mpi::Signature
2069 {
2070 ::std::mem::replace(&mut self.mpis, mpis)
2071 }
2072
2073 /// Gets the computed hash value.
2074 ///
2075 /// This is set by the [`PacketParser`] when parsing the message,
2076 /// during successful verification of signatures, and on
2077 /// signatures during certificate canonicalization.
2078 ///
2079 /// [`PacketParser`]: crate::parse::PacketParser
2080 pub fn computed_digest(&self) -> Option<&[u8]> {
2081 self.computed_digest.get().map(|d| &d[..])
2082 }
2083
2084 /// Sets the computed hash value, once.
2085 ///
2086 /// Calling this function a second time has no effect.
2087 pub(crate) fn set_computed_digest(&self, hash: Option<Vec<u8>>)
2088 {
2089 let _ = self.computed_digest.set(hash.unwrap_or_default());
2090 }
2091
2092 /// Gets the signature level.
2093 ///
2094 /// A level of 0 indicates that the signature is directly over the
2095 /// data, a level of 1 means that the signature is a notarization
2096 /// over all level 0 signatures and the data, and so on.
2097 pub fn level(&self) -> usize {
2098 self.level
2099 }
2100
2101 /// Sets the signature level.
2102 ///
2103 /// A level of 0 indicates that the signature is directly over the
2104 /// data, a level of 1 means that the signature is a notarization
2105 /// over all level 0 signatures and the data, and so on.
2106 pub(crate) fn set_level(&mut self, level: usize) -> usize {
2107 ::std::mem::replace(&mut self.level, level)
2108 }
2109
2110 /// Returns whether this signature should be exported.
2111 ///
2112 /// This checks whether the [`Exportable Certification`] subpacket
2113 /// is absent or present and 1, and that the signature does not
2114 /// include any sensitive [`Revocation Key`] (designated revokers)
2115 /// subpackets.
2116 ///
2117 /// [`Exportable Certification`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.19
2118 /// [`Revocation Key`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.23
2119 pub fn exportable(&self) -> Result<()> {
2120 if ! self.exportable_certification().unwrap_or(true) {
2121 return Err(Error::InvalidOperation(
2122 "Cannot export non-exportable certification".into()).into());
2123 }
2124
2125 if self.revocation_keys().any(|r| r.sensitive()) {
2126 return Err(Error::InvalidOperation(
2127 "Cannot export signature with sensitive designated revoker"
2128 .into()).into());
2129 }
2130
2131 Ok(())
2132 }
2133
2134 /// Returns the additional (i.e. newly discovered) issuers.
2135 fn additional_issuers(&self) -> &[KeyHandle] {
2136 self.additional_issuers.get().map(|v| v.as_slice()).unwrap_or(&[])
2137 }
2138}
2139
2140impl From<Signature3> for SignatureBuilder {
2141 fn from(sig: Signature3) -> Self {
2142 SignatureBuilder::from(sig.intern)
2143 }
2144}
2145
2146/// Holds a v3 Signature packet.
2147///
2148/// This holds a [version 3] Signature packet. Normally, you won't
2149/// directly work with this data structure, but with the [`Signature`]
2150/// enum, which is version agnostic. An exception is when you need to
2151/// do version-specific operations. But currently, there aren't any
2152/// version-specific methods.
2153///
2154/// [version 3]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2
2155/// [`Signature`]: super::Signature
2156///
2157/// Note: Per [Section 5.2 of RFC 9580], v3 signatures should not be
2158/// generated, but they should be accepted. As such, support for
2159/// version 3 signatures is limited to verifying them, but not
2160/// generating them.
2161///
2162/// [Section 5.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2
2163
2164#[derive(Clone)]
2165pub struct Signature3 {
2166 pub(crate) intern: Signature4,
2167}
2168assert_send_and_sync!(Signature3);
2169
2170impl TryFrom<Signature> for Signature3 {
2171 type Error = anyhow::Error;
2172
2173 fn try_from(sig: Signature) -> Result<Self> {
2174 match sig {
2175 Signature::V3(sig) => Ok(sig),
2176 sig => Err(
2177 Error::InvalidArgument(
2178 format!(
2179 "Got a v{}, require a v3 signature",
2180 sig.version()))
2181 .into()),
2182 }
2183 }
2184}
2185
2186// Yes, Signature3 derefs to Signature4. This is because Signature
2187// derefs to Signature4 so this is the only way to add support for v3
2188// sigs without breaking the semver.
2189impl Deref for Signature3 {
2190 type Target = Signature4;
2191
2192 fn deref(&self) -> &Self::Target {
2193 &self.intern
2194 }
2195}
2196
2197impl DerefMut for Signature3 {
2198 fn deref_mut(&mut self) -> &mut Self::Target {
2199 &mut self.intern
2200 }
2201}
2202
2203impl fmt::Debug for Signature3 {
2204 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2205 f.debug_struct("Signature3")
2206 .field("version", &self.version())
2207 .field("typ", &self.typ())
2208 .field("pk_algo", &self.pk_algo())
2209 .field("hash_algo", &self.hash_algo())
2210 .field("hashed_area", self.hashed_area())
2211 .field("unhashed_area", self.unhashed_area())
2212 .field("additional_issuers", &self.additional_issuers())
2213 .field("digest_prefix",
2214 &crate::fmt::to_hex(&self.digest_prefix, false))
2215 .field(
2216 "computed_digest",
2217 &self
2218 .computed_digest
2219 .get()
2220 .map(|hash| crate::fmt::to_hex(&hash[..], false)),
2221 )
2222 .field("level", &self.level)
2223 .field("mpis", &self.mpis)
2224 .finish()
2225 }
2226}
2227
2228impl PartialEq for Signature3 {
2229 /// This method tests for self and other values to be equal, and
2230 /// is used by ==.
2231 ///
2232 /// This method compares the serialized version of the two
2233 /// packets. Thus, the computed values are ignored ([`level`],
2234 /// [`computed_digest`]).
2235 ///
2236 /// [`level`]: Signature3::level()
2237 /// [`computed_digest`]: Signature3::computed_digest()
2238 fn eq(&self, other: &Signature3) -> bool {
2239 self.cmp(other) == Ordering::Equal
2240 }
2241}
2242
2243impl Eq for Signature3 {}
2244
2245impl PartialOrd for Signature3 {
2246 fn partial_cmp(&self, other: &Signature3) -> Option<Ordering> {
2247 Some(self.cmp(other))
2248 }
2249}
2250
2251impl Ord for Signature3 {
2252 fn cmp(&self, other: &Signature3) -> Ordering {
2253 self.intern.cmp(&other.intern)
2254 }
2255}
2256
2257impl std::hash::Hash for Signature3 {
2258 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
2259 use std::hash::Hash as StdHash;
2260 StdHash::hash(&self.intern, state);
2261 }
2262}
2263
2264impl Signature3 {
2265 /// Creates a new signature packet.
2266 ///
2267 /// If you want to sign something, consider using the [`SignatureBuilder`]
2268 /// interface.
2269 ///
2270 pub fn new(typ: SignatureType, creation_time: Timestamp,
2271 issuer: KeyID,
2272 pk_algo: PublicKeyAlgorithm,
2273 hash_algo: HashAlgorithm,
2274 digest_prefix: [u8; 2],
2275 mpis: mpi::Signature) -> Self {
2276 let hashed_area = SubpacketArea::new(vec![
2277 Subpacket::new(
2278 SubpacketValue::SignatureCreationTime(creation_time),
2279 true).expect("fits"),
2280 ]).expect("fits");
2281 let unhashed_area = SubpacketArea::new(vec![
2282 Subpacket::new(
2283 SubpacketValue::Issuer(issuer),
2284 false).expect("fits"),
2285 ]).expect("fits");
2286
2287 let mut sig = Signature4::new(typ,
2288 pk_algo, hash_algo,
2289 hashed_area, unhashed_area,
2290 digest_prefix, mpis);
2291 sig.version = 3;
2292
2293 Signature3 {
2294 intern: sig,
2295 }
2296 }
2297
2298 /// Gets the public key algorithm.
2299 // SigantureFields::pk_algo is private, because we don't want it
2300 // available on SignatureBuilder, which also derefs to
2301 // &SignatureFields.
2302 pub fn pk_algo(&self) -> PublicKeyAlgorithm {
2303 self.fields.pk_algo()
2304 }
2305
2306 /// Gets the hash prefix.
2307 pub fn digest_prefix(&self) -> &[u8; 2] {
2308 &self.digest_prefix
2309 }
2310
2311 /// Gets the signature packet's MPIs.
2312 pub fn mpis(&self) -> &mpi::Signature {
2313 &self.mpis
2314 }
2315
2316 /// Gets the computed hash value.
2317 ///
2318 /// This is set by the [`PacketParser`] when parsing the message.
2319 ///
2320 /// [`PacketParser`]: crate::parse::PacketParser
2321 pub fn computed_digest(&self) -> Option<&[u8]> {
2322 self.computed_digest.get().map(|d| &d[..])
2323 }
2324
2325 /// Gets the signature level.
2326 ///
2327 /// A level of 0 indicates that the signature is directly over the
2328 /// data, a level of 1 means that the signature is a notarization
2329 /// over all level 0 signatures and the data, and so on.
2330 pub fn level(&self) -> usize {
2331 self.level
2332 }
2333}
2334
2335impl crate::packet::Signature {
2336 /// Returns the value of any Issuer and Issuer Fingerprint subpackets.
2337 ///
2338 /// The [Issuer subpacket] and [Issuer Fingerprint subpacket] are
2339 /// used when processing a signature to identify which certificate
2340 /// created the signature. Since this information is
2341 /// self-authenticating (the act of validating the signature
2342 /// authenticates the subpacket), it is typically stored in the
2343 /// unhashed subpacket area.
2344 ///
2345 /// [Issuer subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
2346 /// [Issuer Fingerprint subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
2347 ///
2348 /// This function returns all instances of the Issuer subpacket
2349 /// and the Issuer Fingerprint subpacket in both the hashed
2350 /// subpacket area and the unhashed subpacket area.
2351 ///
2352 /// If you are only looking for the issuer subpackets use
2353 /// [`SubpacketAreas::issuers`], or if you are looking only for
2354 /// the issuer fingerprint subpackets use
2355 /// [`SubpacketAreas::issuer_fingerprints`].
2356 ///
2357 /// The issuers are sorted so that the `Fingerprints` come before
2358 /// `KeyID`s. The `Fingerprint`s and `KeyID`s are not further
2359 /// sorted, but are returned in the order that they are
2360 /// encountered.
2361 pub fn get_issuers(&self) -> Vec<crate::KeyHandle> {
2362 let mut issuers: Vec<_> =
2363 self.hashed_area().iter()
2364 .chain(self.unhashed_area().iter())
2365 .filter_map(|subpacket| {
2366 match subpacket.value() {
2367 SubpacketValue::Issuer(i) => Some(i.into()),
2368 SubpacketValue::IssuerFingerprint(i) => Some(i.into()),
2369 _ => None,
2370 }
2371 })
2372 .collect();
2373
2374 // Sort the issuers so that the fingerprints come first.
2375 issuers.sort_by(|a, b| {
2376 use crate::KeyHandle::*;
2377 use std::cmp::Ordering::*;
2378 match (a, b) {
2379 (Fingerprint(_), Fingerprint(_)) => Equal,
2380 (KeyID(_), Fingerprint(_)) => Greater,
2381 (Fingerprint(_), KeyID(_)) => Less,
2382 (KeyID(_), KeyID(_)) => Equal,
2383 }
2384 });
2385
2386 issuers
2387 }
2388
2389 /// Compares Signatures ignoring the unhashed subpacket area.
2390 ///
2391 /// This comparison function ignores the unhashed subpacket area
2392 /// when comparing two signatures. This prevents a malicious
2393 /// party from taking valid signatures, adding subpackets to the
2394 /// unhashed area, and deriving valid but distinct signatures,
2395 /// which could be used to perform a denial-of-service attack.
2396 /// For instance, an attacker could create a lot of signatures,
2397 /// which need to be validated. Ignoring the unhashed subpackets
2398 /// means that we can deduplicate signatures using this predicate.
2399 ///
2400 /// Unlike [`Signature::normalize`], this method ignores
2401 /// authenticated packets in the unhashed subpacket area.
2402 ///
2403 /// # Examples
2404 ///
2405 /// ```
2406 /// use sequoia_openpgp as openpgp;
2407 /// use openpgp::cert::prelude::*;
2408 /// use openpgp::packet::prelude::*;
2409 /// use openpgp::packet::signature::subpacket::{Subpacket, SubpacketValue};
2410 /// use openpgp::policy::StandardPolicy;
2411 /// use openpgp::types::SignatureType;
2412 /// use openpgp::types::Features;
2413 ///
2414 /// # fn main() -> openpgp::Result<()> {
2415 /// let p = &StandardPolicy::new();
2416 ///
2417 /// let (cert, _) = CertBuilder::new().generate()?;
2418 ///
2419 /// let orig = cert.with_policy(p, None)?.direct_key_signature()?;
2420 ///
2421 /// // Add an inconspicuous subpacket to the unhashed area.
2422 /// let sb = Subpacket::new(SubpacketValue::Features(Features::empty()), false)?;
2423 /// let mut modified = orig.clone();
2424 /// modified.unhashed_area_mut().add(sb);
2425 ///
2426 /// // We modified the signature, but the signature is still valid.
2427 /// modified.verify_direct_key(cert.primary_key().key(), cert.primary_key().key());
2428 ///
2429 /// // PartialEq considers the packets to not be equal...
2430 /// assert!(orig != &modified);
2431 /// // ... but normalized_eq does.
2432 /// assert!(orig.normalized_eq(&modified));
2433 /// # Ok(())
2434 /// # }
2435 /// ```
2436 pub fn normalized_eq(&self, other: &Signature) -> bool {
2437 self.normalized_cmp(other) == Ordering::Equal
2438 }
2439
2440 /// Compares Signatures ignoring the unhashed subpacket area.
2441 ///
2442 /// This is useful to deduplicate signatures by first sorting them
2443 /// using this function, and then deduplicating using the
2444 /// [`Signature::normalized_eq`] predicate.
2445 ///
2446 /// This comparison function ignores the unhashed subpacket area
2447 /// when comparing two signatures. This prevents a malicious
2448 /// party from taking valid signatures, adding subpackets to the
2449 /// unhashed area, and deriving valid but distinct signatures,
2450 /// which could be used to perform a denial-of-service attack.
2451 /// For instance, an attacker could create a lot of signatures,
2452 /// which need to be validated. Ignoring the unhashed subpackets
2453 /// means that we can deduplicate signatures using this predicate.
2454 ///
2455 /// Unlike [`Signature::normalize`], this method ignores
2456 /// authenticated packets in the unhashed subpacket area.
2457 ///
2458 /// # Examples
2459 ///
2460 /// ```
2461 /// use std::cmp::Ordering;
2462 /// use sequoia_openpgp as openpgp;
2463 /// use openpgp::cert::prelude::*;
2464 /// use openpgp::packet::prelude::*;
2465 /// use openpgp::packet::signature::subpacket::{Subpacket, SubpacketValue};
2466 /// use openpgp::policy::StandardPolicy;
2467 /// use openpgp::types::SignatureType;
2468 /// use openpgp::types::Features;
2469 ///
2470 /// # fn main() -> openpgp::Result<()> {
2471 /// let p = &StandardPolicy::new();
2472 ///
2473 /// let (cert, _) = CertBuilder::new().generate()?;
2474 ///
2475 /// let orig = cert.with_policy(p, None)?.direct_key_signature()?;
2476 ///
2477 /// // Add an inconspicuous subpacket to the unhashed area.
2478 /// let sb = Subpacket::new(SubpacketValue::Features(Features::empty()), false)?;
2479 /// let mut modified = orig.clone();
2480 /// modified.unhashed_area_mut().add(sb);
2481 ///
2482 /// // We modified the signature, but the signature is still valid.
2483 /// modified.verify_direct_key(cert.primary_key().key(), cert.primary_key().key());
2484 ///
2485 /// // PartialEq considers the packets to not be equal...
2486 /// assert!(orig != &modified);
2487 /// // ... but normalized_partial_cmp does.
2488 /// assert!(orig.normalized_cmp(&modified) == Ordering::Equal);
2489 /// # Ok(()) }
2490 /// ```
2491 pub fn normalized_cmp(&self, other: &Signature)
2492 -> Ordering {
2493 self.version().cmp(&other.version())
2494 .then_with(|| self.typ().cmp(&other.typ()))
2495 .then_with(|| self.pk_algo().cmp(&other.pk_algo()))
2496 .then_with(|| self.hash_algo().cmp(&other.hash_algo()))
2497 .then_with(|| self.hashed_area().cmp(other.hashed_area()))
2498 .then_with(|| self.digest_prefix().cmp(other.digest_prefix()))
2499 .then_with(|| self.mpis().cmp(other.mpis()))
2500 }
2501
2502 /// Hashes everything but the unhashed subpacket area into state.
2503 ///
2504 /// This is an alternate implementation of [`Hash`], which does
2505 /// not hash the unhashed subpacket area.
2506 ///
2507 /// [`Hash`]: std::hash::Hash
2508 ///
2509 /// Unlike [`Signature::normalize`], this method ignores
2510 /// authenticated packets in the unhashed subpacket area.
2511 pub fn normalized_hash<H>(&self, state: &mut H)
2512 where H: Hasher
2513 {
2514 use std::hash::Hash;
2515
2516 self.version.hash(state);
2517 self.typ.hash(state);
2518 self.pk_algo.hash(state);
2519 self.hash_algo.hash(state);
2520 self.hashed_area().hash(state);
2521 self.digest_prefix().hash(state);
2522 Hash::hash(&self.mpis(), state);
2523 }
2524
2525 /// Normalizes the signature.
2526 ///
2527 /// This function normalizes the *unhashed* signature subpackets.
2528 ///
2529 /// First, it removes all but the following self-authenticating
2530 /// subpackets:
2531 ///
2532 /// - `SubpacketValue::Issuer`
2533 /// - `SubpacketValue::IssuerFingerprint`
2534 /// - `SubpacketValue::EmbeddedSignature`
2535 ///
2536 /// Note: the retained subpackets are not checked for validity.
2537 ///
2538 /// Then, it adds any missing issuer information to the unhashed
2539 /// subpacket area that has been computed when verifying the
2540 /// signature.
2541 pub fn normalize(&self) -> Self {
2542 use subpacket::SubpacketTag::*;
2543 let mut sig = self.clone();
2544 {
2545 let area = sig.unhashed_area_mut();
2546 area.clear();
2547
2548 for spkt in self.unhashed_area().iter()
2549 .filter(|s| s.tag() == Issuer
2550 || s.tag() == IssuerFingerprint
2551 || s.tag() == EmbeddedSignature)
2552 {
2553 area.add(spkt.clone())
2554 .expect("it did fit into the old area");
2555 }
2556
2557 // Add missing issuer information. This is icing on the
2558 // cake, hence it is only a best-effort mechanism that
2559 // silently fails.
2560 let _ = sig.add_missing_issuers();
2561
2562 // Normalize the order of subpackets.
2563 sig.unhashed_area_mut().sort();
2564 }
2565 sig
2566 }
2567
2568 /// Adds missing issuer information.
2569 ///
2570 /// Calling this function adds any missing issuer information to
2571 /// the unhashed subpacket area.
2572 ///
2573 /// When a signature is verified, the identity of the signing key
2574 /// is computed and stored in the `Signature` struct. This
2575 /// information can be used to complement the issuer information
2576 /// stored in the signature. Note that we don't do this
2577 /// automatically when verifying signatures, because that would
2578 /// change the serialized representation of the signature as a
2579 /// side effect of verifying the signature.
2580 pub fn add_missing_issuers(&mut self) -> Result<()> {
2581 if self.additional_issuers().is_empty() {
2582 return Ok(());
2583 }
2584
2585 if self.version() == 3 {
2586 return Err(Error::InvalidOperation(
2587 "cannot add information to v3 signature".into()).into());
2588 }
2589
2590 let issuers = self.get_issuers();
2591 for id in self.additional_issuers.take().expect("not empty") {
2592 if ! issuers.contains(&id) {
2593 match id {
2594 KeyHandle::KeyID(id) =>
2595 self.unhashed_area_mut().add_internal(
2596 Subpacket::new(SubpacketValue::Issuer(id), false)?,
2597 true)?,
2598 KeyHandle::Fingerprint(fp) =>
2599 self.unhashed_area_mut().add_internal(
2600 Subpacket::new(SubpacketValue::IssuerFingerprint(fp), false)?,
2601 true)?,
2602 }
2603 }
2604 }
2605
2606 Ok(())
2607 }
2608
2609 /// Merges two signatures.
2610 ///
2611 /// Two signatures that are equal according to
2612 /// [`Signature::normalized_eq`] may differ in the contents of the
2613 /// unhashed subpacket areas. This function merges two signatures
2614 /// trying hard to incorporate all the information into one
2615 /// signature while avoiding denial-of-service attacks by merging
2616 /// in bad information.
2617 ///
2618 /// The merge strategy is as follows:
2619 ///
2620 /// - If the signatures differ according to
2621 /// [`Signature::normalized_eq`], the merge fails.
2622 ///
2623 /// - Do not consider any subpacket that does not belong into
2624 /// the unhashed subpacket area.
2625 ///
2626 /// - Consider all remaining subpackets, in the following order.
2627 /// If we run out of space, all remaining subpackets are
2628 /// ignored.
2629 ///
2630 /// - Authenticated subpackets from `self`
2631 /// - Authenticated subpackets from `other`
2632 /// - Unauthenticated subpackets from `self` commonly found in
2633 /// unhashed areas
2634 /// - Unauthenticated subpackets from `other` commonly found in
2635 /// unhashed areas
2636 /// - Remaining subpackets from `self`
2637 /// - Remaining subpackets from `other`
2638 ///
2639 /// See [`Subpacket::authenticated`] for how subpackets are
2640 /// authenticated. Subpackets commonly found in unhashed
2641 /// areas are issuer information and embedded signatures.
2642 pub fn merge(mut self, other: Signature) -> Result<Signature> {
2643 self.merge_internal(&other)?;
2644 Ok(self)
2645 }
2646
2647 /// Same as Signature::merge, but non-consuming for use with
2648 /// Vec::dedup_by.
2649 pub(crate) fn merge_internal(&mut self, other: &Signature) -> Result<()>
2650 {
2651 use crate::serialize::MarshalInto;
2652
2653 if ! self.normalized_eq(other) {
2654 return Err(Error::InvalidArgument(
2655 "Signatures are not equal modulo unhashed subpackets".into())
2656 .into());
2657 }
2658
2659 // Filters subpackets that plausibly could be in the unhashed
2660 // area.
2661 fn eligible(p: &Subpacket) -> bool {
2662 use SubpacketTag::*;
2663 #[allow(deprecated)]
2664 match p.tag() {
2665 SignatureCreationTime
2666 | SignatureExpirationTime
2667 | ExportableCertification
2668 | TrustSignature
2669 | RegularExpression
2670 | Revocable
2671 | KeyExpirationTime
2672 | PlaceholderForBackwardCompatibility
2673 | PreferredSymmetricAlgorithms
2674 | RevocationKey
2675 | PreferredHashAlgorithms
2676 | PreferredCompressionAlgorithms
2677 | KeyServerPreferences
2678 | PreferredKeyServer
2679 | PrimaryUserID
2680 | PolicyURI
2681 | KeyFlags
2682 | SignersUserID
2683 | ReasonForRevocation
2684 | Features
2685 | SignatureTarget
2686 | PreferredAEADAlgorithms
2687 | IntendedRecipient
2688 | ApprovedCertifications
2689 | PreferredAEADCiphersuites
2690 | Reserved(_)
2691 => false,
2692 Issuer
2693 | NotationData
2694 | EmbeddedSignature
2695 | IssuerFingerprint
2696 | Private(_)
2697 | Unknown(_)
2698 => true,
2699 }
2700 }
2701
2702 // Filters subpackets that usually are in the unhashed area.
2703 fn prefer(p: &Subpacket) -> bool {
2704 use SubpacketTag::*;
2705 matches!(p.tag(), Issuer | EmbeddedSignature | IssuerFingerprint)
2706 }
2707
2708 // Collect subpackets keeping track of the size.
2709 #[allow(clippy::mutable_key_type)]
2710 // In general, the keys of a HashSet should not have interior mutability.
2711 // This particular use should be safe: The hash set is only constructed
2712 // for the merge, we own all objects we put into the set, and we don't
2713 // modify them while they are in the set.
2714 let mut acc = std::collections::HashSet::new();
2715 let mut size = 0;
2716
2717 // Start with missing issuer information.
2718 for id in self.additional_issuers.take().unwrap_or_default().into_iter()
2719 .chain(other.additional_issuers().iter().cloned())
2720 {
2721 let p = match id {
2722 KeyHandle::KeyID(id) => Subpacket::new(
2723 SubpacketValue::Issuer(id), false)?,
2724 KeyHandle::Fingerprint(fp) => Subpacket::new(
2725 SubpacketValue::IssuerFingerprint(fp), false)?,
2726 };
2727
2728 let l = p.serialized_len();
2729 if size + l <= std::u16::MAX as usize && acc.insert(p) {
2730 size += l;
2731 }
2732 }
2733
2734 // Make multiple passes over the subpacket areas. Always
2735 // start with self, then other. Only consider eligible
2736 // packets. Consider authenticated ones first, then plausible
2737 // unauthenticated ones, then the rest.
2738 for p in
2739 self.unhashed_area().iter()
2740 .filter(|p| eligible(p) && p.authenticated())
2741 .chain(other.unhashed_area().iter()
2742 .filter(|p| eligible(p) && p.authenticated()))
2743 .chain(self.unhashed_area().iter()
2744 .filter(|p| eligible(p) && ! p.authenticated() && prefer(p)))
2745 .chain(other.unhashed_area().iter()
2746 .filter(|p| eligible(p) && ! p.authenticated() && prefer(p)))
2747 .chain(self.unhashed_area().iter()
2748 .filter(|p| eligible(p) && ! p.authenticated() && ! prefer(p)))
2749 .chain(other.unhashed_area().iter()
2750 .filter(|p| eligible(p) && ! p.authenticated() && ! prefer(p)))
2751 {
2752 let l = p.serialized_len();
2753 if size + l <= std::u16::MAX as usize && acc.insert(p.clone()) {
2754 size += l;
2755 }
2756 }
2757 assert!(size <= std::u16::MAX as usize);
2758 let mut a = SubpacketArea::new(acc.into_iter().collect())
2759 .expect("must fit");
2760 a.sort();
2761 *self.unhashed_area_mut() = a;
2762
2763 Ok(())
2764 }
2765}
2766
2767/// Verification-related functionality.
2768///
2769/// <a id="verification-functions"></a>
2770impl Signature {
2771 /// Verifies the signature using `key`.
2772 ///
2773 /// Verifies the signature using `key`, using the previously
2774 /// computed stored digest (see [`Signature4::computed_digest`]).
2775 /// If the computed digest has not been set prior to calling this
2776 /// function, it will fail.
2777 ///
2778 /// Because the context (i.e. what the signature covers) is hashed
2779 /// and stored in the computed digest, and not handed in as part
2780 /// of the signature verification, this interface must only be
2781 /// used if the context can be robustly inferred.
2782 ///
2783 /// For example, when verifying a third-party certification while
2784 /// iterating over user IDs in a certificate, this function can be
2785 /// used because the context is the current certificate and user
2786 /// ID, and this context has been hashed and the digest stored
2787 /// during certificate canonicalization. On the other hand, when
2788 /// verifying a dangling user ID revocation signature, the context
2789 /// has to be provided explicitly in a call to
2790 /// [`Signature::verify_userid_revocation`].
2791 ///
2792 /// Note: Due to limited context, this only verifies the
2793 /// cryptographic signature, and checks that the key predates the
2794 /// signature. Further constraints on the signature, like
2795 /// signature type, creation and expiration time, or signature
2796 /// revocations must be checked by the caller.
2797 ///
2798 /// Likewise, this function does not check whether `key` can make
2799 /// valid signatures; it is up to the caller to make sure the key
2800 /// is not revoked, not expired, has a valid self-signature, has a
2801 /// subkey binding signature (if appropriate), has the signing
2802 /// capability, etc.
2803 pub fn verify_signature<P, R>(&self, key: &Key<P, R>) -> Result<()>
2804 where P: key::KeyParts,
2805 R: key::KeyRole,
2806 {
2807 self.verify_digest_internal(
2808 key.parts_as_public().role_as_unspecified(), None)
2809 }
2810
2811 /// Verifies the signature against `hash`.
2812 ///
2813 /// The `hash` should only be computed over the payload, this
2814 /// function hashes in the signature itself before verifying it.
2815 ///
2816 /// Note: Due to limited context, this only verifies the
2817 /// cryptographic signature and checks that the key predates the
2818 /// signature. Further constraints on the signature, like
2819 /// creation and expiration time, or signature revocations must be
2820 /// checked by the caller.
2821 ///
2822 /// Likewise, this function does not check whether `key` can make
2823 /// valid signatures; it is up to the caller to make sure the key
2824 /// is not revoked, not expired, has a valid self-signature, has a
2825 /// subkey binding signature (if appropriate), has the signing
2826 /// capability, etc.
2827 pub fn verify_hash<P, R>(&self, key: &Key<P, R>,
2828 mut hash: hash::Context)
2829 -> Result<()>
2830 where P: key::KeyParts,
2831 R: key::KeyRole,
2832 {
2833 self.hash(&mut hash)?;
2834 self.verify_digest_internal(
2835 key.parts_as_public().role_as_unspecified(),
2836 Some(hash.into_digest()?.into()))
2837 }
2838
2839 /// Verifies the signature against `digest`.
2840 ///
2841 /// Note: Due to limited context, this only verifies the
2842 /// cryptographic signature and checks that the key predates the
2843 /// signature. Further constraints on the signature, like
2844 /// creation and expiration time, or signature revocations must be
2845 /// checked by the caller.
2846 ///
2847 /// Likewise, this function does not check whether `key` can make
2848 /// valid signatures; it is up to the caller to make sure the key
2849 /// is not revoked, not expired, has a valid self-signature, has a
2850 /// subkey binding signature (if appropriate), has the signing
2851 /// capability, etc.
2852 pub fn verify_digest<P, R, D>(&self, key: &Key<P, R>, digest: D)
2853 -> Result<()>
2854 where P: key::KeyParts,
2855 R: key::KeyRole,
2856 D: AsRef<[u8]>,
2857 {
2858 self.verify_digest_internal(
2859 key.parts_as_public().role_as_unspecified(),
2860 Some(digest.as_ref().into()))
2861 }
2862
2863 /// Verifies the signature against `computed_digest`, or
2864 /// `self.computed_digest` if the former is `None`.
2865 fn verify_digest_internal(&self,
2866 key: &Key<key::PublicParts, key::UnspecifiedRole>,
2867 computed_digest: Option<Cow<[u8]>>)
2868 -> Result<()>
2869 {
2870 // Only v6 keys may create v6 signatures.
2871 if (self.version() == 6) != (key.version() == 6) {
2872 return Err(Error::BadSignature(
2873 format!("Signature (v{}) and key (v{}) version mismatch",
2874 self.version(), key.version())).into());
2875 }
2876
2877 // Check salt size.
2878 if self.version() == 6 &&
2879 Some(self.hash_algo().salt_size()?) != self.salt().map(|s| s.len())
2880 {
2881 return Err(Error::BadSignature(
2882 format!("Salt of size {} bytes is wrong, expected {} bytes ",
2883 self.salt().map(|s| s.len()).unwrap_or(0),
2884 self.hash_algo().salt_size()?)).into());
2885 }
2886
2887 // DSA is phased out in RFC9580.
2888 #[allow(deprecated)]
2889 if self.version() == 6 && self.pk_algo() == PublicKeyAlgorithm::DSA {
2890 return Err(Error::BadSignature(
2891 "Version 6 signatures using DSA MUST be rejected".into())
2892 .into());
2893 }
2894
2895 if let Some(creation_time) = self.signature_creation_time() {
2896 if creation_time < key.creation_time() {
2897 return Err(Error::BadSignature(
2898 format!("Signature (created {:?}) predates key ({:?})",
2899 creation_time, key.creation_time())).into());
2900 }
2901 } else {
2902 return Err(Error::BadSignature(
2903 "Signature has no creation time subpacket".into()).into());
2904 }
2905
2906 // Either the digest has been given as argument, or it has
2907 // been stashed in the signature by the packet parser, or
2908 // error out.
2909 let digest = computed_digest.as_ref().map(AsRef::as_ref)
2910 .or(self.computed_digest())
2911 .ok_or_else(|| Error::BadSignature("Hash not computed.".into()))?;
2912
2913 let result = if let Ok(entry) = cache::Entry::new(
2914 self, digest, key.parts_as_public().role_as_unspecified())
2915 {
2916 if entry.present() {
2917 // The signature is good.
2918 Ok(())
2919 } else {
2920 // It's not in the cache.
2921
2922 let result = key.verify(
2923 self.mpis(), self.hash_algo(), digest);
2924
2925 // Insert the result in the cache.
2926 entry.insert(result.is_ok());
2927
2928 result
2929 }
2930 } else {
2931 key.verify(self.mpis(), self.hash_algo(), digest)
2932 };
2933
2934 if let Ok(expected_salt_len) = self.hash_algo().salt_size() {
2935 let salt_len = self.salt().map(|s| s.len()).unwrap_or(0);
2936 if self.version() == 6 && salt_len != expected_salt_len {
2937 return Err(Error::BadSignature(format!(
2938 "bad salt length, expected {} got {}",
2939 expected_salt_len, salt_len)).into());
2940 }
2941 }
2942
2943 if result.is_ok() {
2944 // Mark information in this signature as authenticated.
2945
2946 // The hashed subpackets are authenticated by the
2947 // signature.
2948 self.hashed_area().iter().for_each(|p| {
2949 p.set_authenticated(true);
2950 });
2951
2952 // The self-authenticating unhashed subpackets are
2953 // authenticated by the key's identity.
2954 self.unhashed_area().iter().for_each(|p| {
2955 let authenticated = match p.value() {
2956 SubpacketValue::Issuer(id) =>
2957 id == &key.keyid(),
2958 SubpacketValue::IssuerFingerprint(fp) =>
2959 fp == &key.fingerprint(),
2960 _ => false,
2961 };
2962 p.set_authenticated(authenticated);
2963 });
2964
2965 // Compute and record any issuer information not yet
2966 // contained in the signature.
2967 let issuers = self.get_issuers();
2968 let mut additional_issuers = Vec::with_capacity(0);
2969
2970 let id = KeyHandle::from(key.keyid());
2971 if self.version() <= 4 && ! issuers.contains(&id) {
2972 additional_issuers.push(id);
2973 }
2974
2975 if self.version() >= 4 {
2976 let fp = KeyHandle::from(key.fingerprint());
2977 if ! issuers.contains(&fp) {
2978 additional_issuers.push(fp);
2979 }
2980 }
2981
2982 // Replace it. If it was already set, we simply ignore
2983 // the error.
2984 let _ = self.additional_issuers.set(additional_issuers);
2985
2986 // Finally, remember the digest.
2987 if let Some(digest) = computed_digest {
2988 self.set_computed_digest(Some(digest.into_owned()));
2989 }
2990 }
2991 result
2992 }
2993
2994 /// Verifies the signature over text or binary documents using
2995 /// `key`.
2996 ///
2997 /// Note: Due to limited context, this only verifies the
2998 /// cryptographic signature, checks the signature's type, and
2999 /// checks that the key predates the signature. Further
3000 /// constraints on the signature, like creation and expiration
3001 /// time, or signature revocations must be checked by the caller.
3002 ///
3003 /// Likewise, this function does not check whether `key` can make
3004 /// valid signatures; it is up to the caller to make sure the key
3005 /// is not revoked, not expired, has a valid self-signature, has a
3006 /// subkey binding signature (if appropriate), has the signing
3007 /// capability, etc.
3008 pub fn verify_document<P, R>(&self, key: &Key<P, R>) -> Result<()>
3009 where P: key::KeyParts,
3010 R: key::KeyRole,
3011 {
3012 if !(self.typ() == SignatureType::Binary
3013 || self.typ() == SignatureType::Text) {
3014 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3015 }
3016
3017 self.verify_digest_internal(
3018 key.parts_as_public().role_as_unspecified(), None)
3019 }
3020
3021 /// Verifies the standalone signature using `key`.
3022 ///
3023 /// Note: Due to limited context, this only verifies the
3024 /// cryptographic signature, checks the signature's type, and
3025 /// checks that the key predates the signature. Further
3026 /// constraints on the signature, like creation and expiration
3027 /// time, or signature revocations must be checked by the caller.
3028 ///
3029 /// Likewise, this function does not check whether `key` can make
3030 /// valid signatures; it is up to the caller to make sure the key
3031 /// is not revoked, not expired, has a valid self-signature, has a
3032 /// subkey binding signature (if appropriate), has the signing
3033 /// capability, etc.
3034 pub fn verify_standalone<P, R>(&self, key: &Key<P, R>) -> Result<()>
3035 where P: key::KeyParts,
3036 R: key::KeyRole,
3037 {
3038 if self.typ() != SignatureType::Standalone {
3039 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3040 }
3041
3042 // Standalone signatures are like binary-signatures over the
3043 // zero-sized string.
3044 let mut hash =
3045 self.hash_algo().context()?.for_signature(self.version());
3046 self.hash_standalone(&mut hash)?;
3047 self.verify_digest_internal(key.parts_as_public().role_as_unspecified(),
3048 Some(hash.into_digest()?.into()))
3049 }
3050
3051 /// Verifies the timestamp signature using `key`.
3052 ///
3053 /// Note: Due to limited context, this only verifies the
3054 /// cryptographic signature, checks the signature's type, and
3055 /// checks that the key predates the signature. Further
3056 /// constraints on the signature, like creation and expiration
3057 /// time, or signature revocations must be checked by the caller.
3058 ///
3059 /// Likewise, this function does not check whether `key` can make
3060 /// valid signatures; it is up to the caller to make sure the key
3061 /// is not revoked, not expired, has a valid self-signature, has a
3062 /// subkey binding signature (if appropriate), has the signing
3063 /// capability, etc.
3064 pub fn verify_timestamp<P, R>(&self, key: &Key<P, R>) -> Result<()>
3065 where P: key::KeyParts,
3066 R: key::KeyRole,
3067 {
3068 if self.typ() != SignatureType::Timestamp {
3069 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3070 }
3071
3072 // Timestamp signatures are like binary-signatures over the
3073 // zero-sized string.
3074 let mut hash =
3075 self.hash_algo().context()?.for_signature(self.version());
3076 self.hash_timestamp(&mut hash)?;
3077 self.verify_digest_internal(
3078 key.parts_as_public().role_as_unspecified(),
3079 Some(hash.into_digest()?.into()))
3080 }
3081
3082 /// Verifies the direct key signature.
3083 ///
3084 /// `self` is the direct key signature, `signer` is the
3085 /// key that allegedly made the signature, and `pk` is the primary
3086 /// key.
3087 ///
3088 /// For a self-signature, `signer` and `pk` will be the same.
3089 ///
3090 /// Note: Due to limited context, this only verifies the
3091 /// cryptographic signature, checks the signature's type, and
3092 /// checks that the key predates the signature. Further
3093 /// constraints on the signature, like creation and expiration
3094 /// time, or signature revocations must be checked by the caller.
3095 ///
3096 /// Likewise, this function does not check whether `signer` can
3097 /// make valid signatures; it is up to the caller to make sure the
3098 /// key is not revoked, not expired, has a valid self-signature,
3099 /// has a subkey binding signature (if appropriate), has the
3100 /// signing capability, etc.
3101 pub fn verify_direct_key<P, Q, R>(&self,
3102 signer: &Key<P, R>,
3103 pk: &Key<Q, key::PrimaryRole>)
3104 -> Result<()>
3105 where P: key::KeyParts,
3106 Q: key::KeyParts,
3107 R: key::KeyRole,
3108 {
3109 if self.typ() != SignatureType::DirectKey {
3110 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3111 }
3112
3113 let mut hash =
3114 self.hash_algo().context()?.for_signature(self.version());
3115 self.hash_direct_key(&mut hash, pk)?;
3116 self.verify_digest_internal(
3117 signer.parts_as_public().role_as_unspecified(),
3118 Some(hash.into_digest()?.into()))
3119 }
3120
3121 /// Verifies the primary key revocation certificate.
3122 ///
3123 /// `self` is the primary key revocation certificate, `signer` is
3124 /// the key that allegedly made the signature, and `pk` is the
3125 /// primary key,
3126 ///
3127 /// For a self-signature, `signer` and `pk` will be the same.
3128 ///
3129 /// Note: Due to limited context, this only verifies the
3130 /// cryptographic signature, checks the signature's type, and
3131 /// checks that the key predates the signature. Further
3132 /// constraints on the signature, like creation and expiration
3133 /// time, or signature revocations must be checked by the caller.
3134 ///
3135 /// Likewise, this function does not check whether `signer` can
3136 /// make valid signatures; it is up to the caller to make sure the
3137 /// key is not revoked, not expired, has a valid self-signature,
3138 /// has a subkey binding signature (if appropriate), has the
3139 /// signing capability, etc.
3140 pub fn verify_primary_key_revocation<P, Q, R>(&self,
3141 signer: &Key<P, R>,
3142 pk: &Key<Q, key::PrimaryRole>)
3143 -> Result<()>
3144 where P: key::KeyParts,
3145 Q: key::KeyParts,
3146 R: key::KeyRole,
3147 {
3148 if self.typ() != SignatureType::KeyRevocation {
3149 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3150 }
3151
3152 let mut hash =
3153 self.hash_algo().context()?.for_signature(self.version());
3154 self.hash_direct_key(&mut hash, pk)?;
3155 self.verify_digest_internal(
3156 signer.parts_as_public().role_as_unspecified(),
3157 Some(hash.into_digest()?.into()))
3158 }
3159
3160 /// Verifies the subkey binding.
3161 ///
3162 /// `self` is the subkey key binding signature, `signer` is the
3163 /// key that allegedly made the signature, `pk` is the primary
3164 /// key, and `subkey` is the subkey.
3165 ///
3166 /// For a self-signature, `signer` and `pk` will be the same.
3167 ///
3168 /// If the signature indicates that this is a `Signing` capable
3169 /// subkey, then the back signature is also verified. If it is
3170 /// missing or can't be verified, then this function returns
3171 /// false.
3172 ///
3173 /// Note: Due to limited context, this only verifies the
3174 /// cryptographic signature, checks the signature's type, and
3175 /// checks that the key predates the signature. Further
3176 /// constraints on the signature, like creation and expiration
3177 /// time, or signature revocations must be checked by the caller.
3178 ///
3179 /// Likewise, this function does not check whether `signer` can
3180 /// make valid signatures; it is up to the caller to make sure the
3181 /// key is not revoked, not expired, has a valid self-signature,
3182 /// has a subkey binding signature (if appropriate), has the
3183 /// signing capability, etc.
3184 pub fn verify_subkey_binding<P, Q, R, S>(
3185 &self,
3186 signer: &Key<P, R>,
3187 pk: &Key<Q, key::PrimaryRole>,
3188 subkey: &Key<S, key::SubordinateRole>)
3189 -> Result<()>
3190 where P: key::KeyParts,
3191 Q: key::KeyParts,
3192 R: key::KeyRole,
3193 S: key::KeyParts,
3194 {
3195 if self.typ() != SignatureType::SubkeyBinding {
3196 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3197 }
3198
3199 let mut hash =
3200 self.hash_algo().context()?.for_signature(self.version());
3201 self.hash_subkey_binding(&mut hash, pk, subkey)?;
3202 self.verify_digest_internal(
3203 signer.parts_as_public().role_as_unspecified(),
3204 Some(hash.into_digest()?.into()))?;
3205
3206 // The signature is good, but we may still need to verify the
3207 // back sig.
3208 if self.key_flags().map(|kf| kf.for_signing()).unwrap_or(false) {
3209 let mut last_result = Err(Error::BadSignature(
3210 "Primary key binding signature missing".into()).into());
3211
3212 for backsig in self.subpackets(SubpacketTag::EmbeddedSignature)
3213 {
3214 let result =
3215 if let SubpacketValue::EmbeddedSignature(sig) =
3216 backsig.value()
3217 {
3218 sig.verify_primary_key_binding(pk, subkey)
3219 } else {
3220 unreachable!("subpackets(EmbeddedSignature) returns \
3221 EmbeddedSignatures");
3222 };
3223 if result.is_ok() {
3224 // Mark the subpacket as authenticated by the
3225 // embedded signature.
3226 backsig.set_authenticated(true);
3227 return result;
3228 }
3229 last_result = result;
3230 }
3231 last_result
3232 } else {
3233 // No backsig required.
3234 Ok(())
3235 }
3236 }
3237
3238 /// Verifies the primary key binding.
3239 ///
3240 /// `self` is the primary key binding signature, `pk` is the
3241 /// primary key, and `subkey` is the subkey.
3242 ///
3243 /// Note: Due to limited context, this only verifies the
3244 /// cryptographic signature, checks the signature's type, and
3245 /// checks that the key predates the signature. Further
3246 /// constraints on the signature, like creation and expiration
3247 /// time, or signature revocations must be checked by the caller.
3248 ///
3249 /// Likewise, this function does not check whether `subkey` can
3250 /// make valid signatures; it is up to the caller to make sure the
3251 /// key is not revoked, not expired, has a valid self-signature,
3252 /// has a subkey binding signature (if appropriate), has the
3253 /// signing capability, etc.
3254 pub fn verify_primary_key_binding<P, Q>(
3255 &self,
3256 pk: &Key<P, key::PrimaryRole>,
3257 subkey: &Key<Q, key::SubordinateRole>)
3258 -> Result<()>
3259 where P: key::KeyParts,
3260 Q: key::KeyParts,
3261 {
3262 if self.typ() != SignatureType::PrimaryKeyBinding {
3263 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3264 }
3265
3266 let mut hash =
3267 self.hash_algo().context()?.for_signature(self.version());
3268 self.hash_primary_key_binding(&mut hash, pk, subkey)?;
3269 self.verify_digest_internal(
3270 subkey.parts_as_public().role_as_unspecified(),
3271 Some(hash.into_digest()?.into()))
3272 }
3273
3274 /// Verifies the subkey revocation.
3275 ///
3276 /// `self` is the subkey key revocation certificate, `signer` is
3277 /// the key that allegedly made the signature, `pk` is the primary
3278 /// key, and `subkey` is the subkey.
3279 ///
3280 /// For a self-revocation, `signer` and `pk` will be the same.
3281 ///
3282 /// Note: Due to limited context, this only verifies the
3283 /// cryptographic signature, checks the signature's type, and
3284 /// checks that the key predates the signature. Further
3285 /// constraints on the signature, like creation and expiration
3286 /// time, or signature revocations must be checked by the caller.
3287 ///
3288 /// Likewise, this function does not check whether `signer` can
3289 /// make valid signatures; it is up to the caller to make sure the
3290 /// key is not revoked, not expired, has a valid self-signature,
3291 /// has a subkey binding signature (if appropriate), has the
3292 /// signing capability, etc.
3293 pub fn verify_subkey_revocation<P, Q, R, S>(
3294 &self,
3295 signer: &Key<P, R>,
3296 pk: &Key<Q, key::PrimaryRole>,
3297 subkey: &Key<S, key::SubordinateRole>)
3298 -> Result<()>
3299 where P: key::KeyParts,
3300 Q: key::KeyParts,
3301 R: key::KeyRole,
3302 S: key::KeyParts,
3303 {
3304 if self.typ() != SignatureType::SubkeyRevocation {
3305 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3306 }
3307
3308 let mut hash =
3309 self.hash_algo().context()?.for_signature(self.version());
3310 self.hash_subkey_binding(&mut hash, pk, subkey)?;
3311 self.verify_digest_internal(
3312 signer.parts_as_public().role_as_unspecified(),
3313 Some(hash.into_digest()?.into()))
3314 }
3315
3316 /// Verifies the user id binding.
3317 ///
3318 /// `self` is the user id binding signature, `signer` is the key
3319 /// that allegedly made the signature, `pk` is the primary key,
3320 /// and `userid` is the user id.
3321 ///
3322 /// For a self-signature, `signer` and `pk` will be the same.
3323 ///
3324 /// Note: Due to limited context, this only verifies the
3325 /// cryptographic signature, checks the signature's type, and
3326 /// checks that the key predates the signature. Further
3327 /// constraints on the signature, like creation and expiration
3328 /// time, or signature revocations must be checked by the caller.
3329 ///
3330 /// Likewise, this function does not check whether `signer` can
3331 /// make valid signatures; it is up to the caller to make sure the
3332 /// key is not revoked, not expired, has a valid self-signature,
3333 /// has a subkey binding signature (if appropriate), has the
3334 /// signing capability, etc.
3335 pub fn verify_userid_binding<P, Q, R>(&self,
3336 signer: &Key<P, R>,
3337 pk: &Key<Q, key::PrimaryRole>,
3338 userid: &UserID)
3339 -> Result<()>
3340 where P: key::KeyParts,
3341 Q: key::KeyParts,
3342 R: key::KeyRole,
3343 {
3344 if !(self.typ() == SignatureType::GenericCertification
3345 || self.typ() == SignatureType::PersonaCertification
3346 || self.typ() == SignatureType::CasualCertification
3347 || self.typ() == SignatureType::PositiveCertification) {
3348 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3349 }
3350
3351 let mut hash =
3352 self.hash_algo().context()?.for_signature(self.version());
3353 self.hash_userid_binding(&mut hash, pk, userid)?;
3354 self.verify_digest_internal(
3355 signer.parts_as_public().role_as_unspecified(),
3356 Some(hash.into_digest()?.into()))
3357 }
3358
3359 /// Verifies the user id revocation certificate.
3360 ///
3361 /// `self` is the revocation certificate, `signer` is the key
3362 /// that allegedly made the signature, `pk` is the primary key,
3363 /// and `userid` is the user id.
3364 ///
3365 /// For a self-signature, `signer` and `pk` will be the same.
3366 ///
3367 /// Note: Due to limited context, this only verifies the
3368 /// cryptographic signature, checks the signature's type, and
3369 /// checks that the key predates the signature. Further
3370 /// constraints on the signature, like creation and expiration
3371 /// time, or signature revocations must be checked by the caller.
3372 ///
3373 /// Likewise, this function does not check whether `signer` can
3374 /// make valid signatures; it is up to the caller to make sure the
3375 /// key is not revoked, not expired, has a valid self-signature,
3376 /// has a subkey binding signature (if appropriate), has the
3377 /// signing capability, etc.
3378 pub fn verify_userid_revocation<P, Q, R>(&self,
3379 signer: &Key<P, R>,
3380 pk: &Key<Q, key::PrimaryRole>,
3381 userid: &UserID)
3382 -> Result<()>
3383 where P: key::KeyParts,
3384 Q: key::KeyParts,
3385 R: key::KeyRole,
3386 {
3387 if self.typ() != SignatureType::CertificationRevocation {
3388 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3389 }
3390
3391 let mut hash =
3392 self.hash_algo().context()?.for_signature(self.version());
3393 self.hash_userid_binding(&mut hash, pk, userid)?;
3394 self.verify_digest_internal(
3395 signer.parts_as_public().role_as_unspecified(),
3396 Some(hash.into_digest()?.into()))
3397 }
3398
3399 /// Verifies an certification approval key signature on a user ID.
3400 ///
3401 /// This feature is [experimental](crate#experimental-features).
3402 ///
3403 /// Allows the certificate owner to approve of third party
3404 /// certifications. See [Certification Approval Key Signature] for
3405 /// details.
3406 ///
3407 /// `self` is the certification approval key signature, `signer`
3408 /// is the key that allegedly made the signature, `pk` is the
3409 /// primary key, and `userid` is the user ID.
3410 ///
3411 /// Note: Due to limited context, this only verifies the
3412 /// cryptographic signature, checks the signature's type, and
3413 /// checks that the key predates the signature. Further
3414 /// constraints on the signature, like creation and expiration
3415 /// time, or signature revocations must be checked by the caller.
3416 ///
3417 /// Likewise, this function does not check whether `signer` can
3418 /// make valid signatures; it is up to the caller to make sure the
3419 /// key is not revoked, not expired, has a valid self-signature,
3420 /// has a subkey binding signature (if appropriate), has the
3421 /// signing capability, etc.
3422 ///
3423 /// [Certification Approval Key Signature]: https://www.ietf.org/archive/id/draft-dkg-openpgp-1pa3pc-02.html#name-certification-approval-key-
3424 pub fn verify_userid_approval<P, Q, R>(
3425 &self,
3426 signer: &Key<P, R>,
3427 pk: &Key<Q, key::PrimaryRole>,
3428 userid: &UserID)
3429 -> Result<()>
3430 where P: key::KeyParts,
3431 Q: key::KeyParts,
3432 R: key::KeyRole,
3433 {
3434 let mut hash =
3435 self.hash_algo().context()?.for_signature(self.version());
3436
3437 if self.approved_certifications()?
3438 .any(|d| d.len() != hash.digest_size())
3439 {
3440 return Err(Error::BadSignature(
3441 "Wrong number of bytes in certification subpacket".into())
3442 .into());
3443 }
3444
3445 self.hash_userid_approval(&mut hash, pk, userid)?;
3446 self.verify_digest_internal(
3447 signer.parts_as_public().role_as_unspecified(),
3448 Some(hash.into_digest()?.into()))
3449 }
3450
3451 /// Verifies the user attribute binding.
3452 ///
3453 /// `self` is the user attribute binding signature, `signer` is
3454 /// the key that allegedly made the signature, `pk` is the primary
3455 /// key, and `ua` is the user attribute.
3456 ///
3457 /// For a self-signature, `signer` and `pk` will be the same.
3458 ///
3459 /// Note: Due to limited context, this only verifies the
3460 /// cryptographic signature, checks the signature's type, and
3461 /// checks that the key predates the signature. Further
3462 /// constraints on the signature, like creation and expiration
3463 /// time, or signature revocations must be checked by the caller.
3464 ///
3465 /// Likewise, this function does not check whether `signer` can
3466 /// make valid signatures; it is up to the caller to make sure the
3467 /// key is not revoked, not expired, has a valid self-signature,
3468 /// has a subkey binding signature (if appropriate), has the
3469 /// signing capability, etc.
3470 pub fn verify_user_attribute_binding<P, Q, R>(&self,
3471 signer: &Key<P, R>,
3472 pk: &Key<Q, key::PrimaryRole>,
3473 ua: &UserAttribute)
3474 -> Result<()>
3475 where P: key::KeyParts,
3476 Q: key::KeyParts,
3477 R: key::KeyRole,
3478 {
3479 if !(self.typ() == SignatureType::GenericCertification
3480 || self.typ() == SignatureType::PersonaCertification
3481 || self.typ() == SignatureType::CasualCertification
3482 || self.typ() == SignatureType::PositiveCertification) {
3483 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3484 }
3485
3486 let mut hash =
3487 self.hash_algo().context()?.for_signature(self.version());
3488 self.hash_user_attribute_binding(&mut hash, pk, ua)?;
3489 self.verify_digest_internal(
3490 signer.parts_as_public().role_as_unspecified(),
3491 Some(hash.into_digest()?.into()))
3492 }
3493
3494 /// Verifies the user attribute revocation certificate.
3495 ///
3496 /// `self` is the user attribute binding signature, `signer` is
3497 /// the key that allegedly made the signature, `pk` is the primary
3498 /// key, and `ua` is the user attribute.
3499 ///
3500 /// For a self-signature, `signer` and `pk` will be the same.
3501 ///
3502 /// Note: Due to limited context, this only verifies the
3503 /// cryptographic signature, checks the signature's type, and
3504 /// checks that the key predates the signature. Further
3505 /// constraints on the signature, like creation and expiration
3506 /// time, or signature revocations must be checked by the caller.
3507 ///
3508 /// Likewise, this function does not check whether `signer` can
3509 /// make valid signatures; it is up to the caller to make sure the
3510 /// key is not revoked, not expired, has a valid self-signature,
3511 /// has a subkey binding signature (if appropriate), has the
3512 /// signing capability, etc.
3513 pub fn verify_user_attribute_revocation<P, Q, R>(
3514 &self,
3515 signer: &Key<P, R>,
3516 pk: &Key<Q, key::PrimaryRole>,
3517 ua: &UserAttribute)
3518 -> Result<()>
3519 where P: key::KeyParts,
3520 Q: key::KeyParts,
3521 R: key::KeyRole,
3522 {
3523 if self.typ() != SignatureType::CertificationRevocation {
3524 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3525 }
3526
3527 let mut hash =
3528 self.hash_algo().context()?.for_signature(self.version());
3529 self.hash_user_attribute_binding(&mut hash, pk, ua)?;
3530 self.verify_digest_internal(
3531 signer.parts_as_public().role_as_unspecified(),
3532 Some(hash.into_digest()?.into()))
3533 }
3534
3535 /// Verifies an certification approval key signature on a user
3536 /// attribute.
3537 ///
3538 /// This feature is [experimental](crate#experimental-features).
3539 ///
3540 /// Allows the certificate owner to approve of third party
3541 /// certifications. See [Certification Approval Key Signature] for
3542 /// details.
3543 ///
3544 /// `self` is the certification approval key signature, `signer`
3545 /// is the key that allegedly made the signature, `pk` is the
3546 /// primary key, and `ua` is the user attribute.
3547 ///
3548 /// Note: Due to limited context, this only verifies the
3549 /// cryptographic signature, checks the signature's type, and
3550 /// checks that the key predates the signature. Further
3551 /// constraints on the signature, like creation and expiration
3552 /// time, or signature revocations must be checked by the caller.
3553 ///
3554 /// Likewise, this function does not check whether `signer` can
3555 /// make valid signatures; it is up to the caller to make sure the
3556 /// key is not revoked, not expired, has a valid self-signature,
3557 /// has a subkey binding signature (if appropriate), has the
3558 /// signing capability, etc.
3559 ///
3560 /// [Certification Approval Key Signature]: https://www.ietf.org/archive/id/draft-dkg-openpgp-1pa3pc-02.html#name-certification-approval-key-
3561 pub fn verify_user_attribute_approval<P, Q, R>(
3562 &self,
3563 signer: &Key<P, R>,
3564 pk: &Key<Q, key::PrimaryRole>,
3565 ua: &UserAttribute)
3566 -> Result<()>
3567 where P: key::KeyParts,
3568 Q: key::KeyParts,
3569 R: key::KeyRole,
3570 {
3571 let mut hash =
3572 self.hash_algo().context()?.for_signature(self.version());
3573
3574 if self.approved_certifications()?
3575 .any(|d| d.len() != hash.digest_size())
3576 {
3577 return Err(Error::BadSignature(
3578 "Wrong number of bytes in certification subpacket".into())
3579 .into());
3580 }
3581
3582 self.hash_user_attribute_approval(&mut hash, pk, ua)?;
3583 self.verify_digest_internal(
3584 signer.parts_as_public().role_as_unspecified(),
3585 Some(hash.into_digest()?.into()))
3586 }
3587
3588 /// Verifies a signature of a message.
3589 ///
3590 /// `self` is the message signature, `signer` is
3591 /// the key that allegedly made the signature and `msg` is the message.
3592 ///
3593 /// This function is for short messages, if you want to verify larger files
3594 /// use `Verifier`.
3595 ///
3596 /// Note: Due to limited context, this only verifies the
3597 /// cryptographic signature, checks the signature's type, and
3598 /// checks that the key predates the signature. Further
3599 /// constraints on the signature, like creation and expiration
3600 /// time, or signature revocations must be checked by the caller.
3601 ///
3602 /// Likewise, this function does not check whether `signer` can
3603 /// make valid signatures; it is up to the caller to make sure the
3604 /// key is not revoked, not expired, has a valid self-signature,
3605 /// has a subkey binding signature (if appropriate), has the
3606 /// signing capability, etc.
3607 pub fn verify_message<M, P, R>(&self, signer: &Key<P, R>,
3608 msg: M)
3609 -> Result<()>
3610 where M: AsRef<[u8]>,
3611 P: key::KeyParts,
3612 R: key::KeyRole,
3613 {
3614 if self.typ() != SignatureType::Binary &&
3615 self.typ() != SignatureType::Text {
3616 return Err(Error::UnsupportedSignatureType(self.typ()).into());
3617 }
3618
3619 // Compute the digest.
3620 let mut hash =
3621 self.hash_algo().context()?.for_signature(self.version());
3622 if let Some(salt) = self.salt() {
3623 hash.update(salt);
3624 }
3625
3626 hash.update(msg.as_ref());
3627 self.hash(&mut hash)?;
3628 self.verify_digest_internal(
3629 signer.parts_as_public().role_as_unspecified(),
3630 Some(hash.into_digest()?.into()))
3631 }
3632}
3633
3634impl From<Signature3> for Packet {
3635 fn from(s: Signature3) -> Self {
3636 Packet::Signature(s.into())
3637 }
3638}
3639
3640impl From<Signature3> for super::Signature {
3641 fn from(s: Signature3) -> Self {
3642 super::Signature::V3(s)
3643 }
3644}
3645
3646impl From<Signature4> for Packet {
3647 fn from(s: Signature4) -> Self {
3648 Packet::Signature(s.into())
3649 }
3650}
3651
3652impl From<Signature4> for super::Signature {
3653 fn from(s: Signature4) -> Self {
3654 super::Signature::V4(s)
3655 }
3656}
3657
3658#[cfg(test)]
3659impl ArbitraryBounded for super::Signature {
3660 fn arbitrary_bounded(g: &mut Gen, depth: usize) -> Self {
3661 match u8::arbitrary(g) % 3 {
3662 0 => Signature3::arbitrary_bounded(g, depth).into(),
3663 1 => Signature4::arbitrary_bounded(g, depth).into(),
3664 2 => Signature6::arbitrary_bounded(g, depth).into(),
3665 _ => unreachable!(),
3666 }
3667 }
3668}
3669
3670#[cfg(test)]
3671impl_arbitrary_with_bound!(super::Signature);
3672
3673#[cfg(test)]
3674impl ArbitraryBounded for Signature4 {
3675 fn arbitrary_bounded(g: &mut Gen, depth: usize) -> Self {
3676 use mpi::MPI;
3677 use PublicKeyAlgorithm::*;
3678
3679 let fields = SignatureFields::arbitrary_bounded(g, depth);
3680 #[allow(deprecated)]
3681 let mpis = match fields.pk_algo() {
3682 RSAEncryptSign | RSASign => mpi::Signature::RSA {
3683 s: MPI::arbitrary(g),
3684 },
3685
3686 DSA => mpi::Signature::DSA {
3687 r: MPI::arbitrary(g),
3688 s: MPI::arbitrary(g),
3689 },
3690
3691 EdDSA => mpi::Signature::EdDSA {
3692 r: MPI::arbitrary(g),
3693 s: MPI::arbitrary(g),
3694 },
3695
3696 ECDSA => mpi::Signature::ECDSA {
3697 r: MPI::arbitrary(g),
3698 s: MPI::arbitrary(g),
3699 },
3700
3701 Ed25519 => mpi::Signature::Ed25519 {
3702 s: {
3703 let mut s = [0; 64];
3704 s.iter_mut().for_each(|p| *p = u8::arbitrary(g));
3705 Box::new(s)
3706 },
3707 },
3708 Ed448 => mpi::Signature::Ed448 {
3709 s: {
3710 let mut s = [0; 114];
3711 s.iter_mut().for_each(|p| *p = u8::arbitrary(g));
3712 Box::new(s)
3713 },
3714 },
3715
3716 ElGamalEncryptSign |
3717 RSAEncrypt | ElGamalEncrypt | ECDH |
3718 X25519 | X448 |
3719 Private(_) | Unknown(_) => unreachable!(),
3720 };
3721
3722 Signature4 {
3723 common: Arbitrary::arbitrary(g),
3724 fields,
3725 digest_prefix: [Arbitrary::arbitrary(g),
3726 Arbitrary::arbitrary(g)],
3727 mpis,
3728 computed_digest: OnceLock::new(),
3729 level: 0,
3730 additional_issuers: OnceLock::new(),
3731 }
3732 }
3733}
3734
3735#[cfg(test)]
3736impl_arbitrary_with_bound!(Signature4);
3737
3738#[cfg(test)]
3739impl ArbitraryBounded for Signature3 {
3740 fn arbitrary_bounded(g: &mut Gen, _depth: usize) -> Self {
3741 use mpi::{arbitrarize, MPI};
3742 use PublicKeyAlgorithm::*;
3743
3744 let pk_algo = PublicKeyAlgorithm::arbitrary_for_signing(g);
3745
3746 #[allow(deprecated)]
3747 let mpis = match pk_algo {
3748 RSAEncryptSign | RSASign => mpi::Signature::RSA {
3749 s: MPI::arbitrary(g),
3750 },
3751
3752 DSA => mpi::Signature::DSA {
3753 r: MPI::arbitrary(g),
3754 s: MPI::arbitrary(g),
3755 },
3756
3757 EdDSA => mpi::Signature::EdDSA {
3758 r: MPI::arbitrary(g),
3759 s: MPI::arbitrary(g),
3760 },
3761
3762 ECDSA => mpi::Signature::ECDSA {
3763 r: MPI::arbitrary(g),
3764 s: MPI::arbitrary(g),
3765 },
3766
3767 Ed25519 => mpi::Signature::Ed25519 {
3768 s: Box::new(arbitrarize(g, [0; 64])),
3769 },
3770
3771 Ed448 => mpi::Signature::Ed448 {
3772 s: Box::new(arbitrarize(g, [0; 114])),
3773 },
3774
3775 _ => unreachable!(),
3776 };
3777
3778 Signature3::new(
3779 SignatureType::arbitrary(g),
3780 Timestamp::arbitrary(g),
3781 KeyID::arbitrary(g),
3782 pk_algo,
3783 HashAlgorithm::arbitrary(g),
3784 [Arbitrary::arbitrary(g), Arbitrary::arbitrary(g)],
3785 mpis)
3786 }
3787}
3788
3789#[cfg(test)]
3790impl_arbitrary_with_bound!(Signature3);
3791
3792#[cfg(test)]
3793mod test {
3794 use super::*;
3795 use crate::KeyID;
3796 use crate::cert::prelude::*;
3797 use crate::crypto;
3798 use crate::parse::Parse;
3799 use crate::packet::Key;
3800 use crate::packet::key::{Key4, Key6};
3801 use crate::types::Curve;
3802 use crate::policy::StandardPolicy as P;
3803
3804 #[cfg(feature = "compression-deflate")]
3805 #[test]
3806 fn signature_verification_test() {
3807 use super::*;
3808
3809 use crate::Cert;
3810 use crate::parse::{
3811 PacketParserBuilder,
3812 PacketParserResult,
3813 PacketParser,
3814 };
3815
3816 struct Test<'a> {
3817 key: &'a str,
3818 data: &'a str,
3819 good: usize,
3820 }
3821
3822 let tests = [
3823 Test {
3824 key: "neal.pgp",
3825 data: "signed-1.pgp",
3826 good: 1,
3827 },
3828 Test {
3829 key: "neal.pgp",
3830 data: "signed-1-sha1-neal.pgp",
3831 good: 1,
3832 },
3833 Test {
3834 key: "testy.pgp",
3835 data: "signed-1-sha256-testy.pgp",
3836 good: 1,
3837 },
3838 Test {
3839 key: "dennis-simon-anton.pgp",
3840 data: "signed-1-dsa.pgp",
3841 good: 1,
3842 },
3843 Test {
3844 key: "erika-corinna-daniela-simone-antonia-nistp256.pgp",
3845 data: "signed-1-ecdsa-nistp256.pgp",
3846 good: 1,
3847 },
3848 Test {
3849 key: "erika-corinna-daniela-simone-antonia-nistp384.pgp",
3850 data: "signed-1-ecdsa-nistp384.pgp",
3851 good: 1,
3852 },
3853 Test {
3854 key: "erika-corinna-daniela-simone-antonia-nistp521.pgp",
3855 data: "signed-1-ecdsa-nistp521.pgp",
3856 good: 1,
3857 },
3858 Test {
3859 key: "emmelie-dorothea-dina-samantha-awina-ed25519.pgp",
3860 data: "signed-1-eddsa-ed25519.pgp",
3861 good: 1,
3862 },
3863 Test {
3864 key: "emmelie-dorothea-dina-samantha-awina-ed25519.pgp",
3865 data: "signed-twice-by-ed25519.pgp",
3866 good: 2,
3867 },
3868 Test {
3869 key: "neal.pgp",
3870 data: "signed-1-notarized-by-ed25519.pgp",
3871 good: 1,
3872 },
3873 Test {
3874 key: "emmelie-dorothea-dina-samantha-awina-ed25519.pgp",
3875 data: "signed-1-notarized-by-ed25519.pgp",
3876 good: 1,
3877 },
3878 // Check with the wrong key.
3879 Test {
3880 key: "neal.pgp",
3881 data: "signed-1-sha256-testy.pgp",
3882 good: 0,
3883 },
3884 Test {
3885 key: "neal.pgp",
3886 data: "signed-2-partial-body.pgp",
3887 good: 1,
3888 },
3889 ];
3890
3891 for test in tests.iter() {
3892 eprintln!("{}, expect {} good signatures:",
3893 test.data, test.good);
3894
3895 let cert = Cert::from_bytes(crate::tests::key(test.key)).unwrap();
3896
3897 if ! cert.keys().all(|ka| ka.key().pk_algo().is_supported()) {
3898 eprintln!("Skipping because one algorithm is not supported");
3899 continue;
3900 }
3901
3902 if let Some(curve) = match cert.primary_key().key().mpis() {
3903 mpi::PublicKey::EdDSA { curve, .. } => Some(curve),
3904 mpi::PublicKey::ECDSA { curve, .. } => Some(curve),
3905 _ => None,
3906 } {
3907 if ! curve.is_supported() {
3908 eprintln!("Skipping because we don't support {}", curve);
3909 continue;
3910 }
3911 }
3912
3913 let mut good = 0;
3914 let mut ppr = PacketParser::from_bytes(
3915 crate::tests::message(test.data)).unwrap();
3916 while let PacketParserResult::Some(mut pp) = ppr {
3917 if let Packet::Signature(sig) = &mut pp.packet {
3918 let result = sig.verify_document(cert.primary_key().key()).is_ok();
3919 eprintln!(" Primary {:?}: {:?}",
3920 cert.fingerprint(), result);
3921 if result {
3922 good += 1;
3923 }
3924
3925 for sk in cert.subkeys() {
3926 let result = sig.verify_document(sk.key()).is_ok();
3927 eprintln!(" Subkey {:?}: {:?}",
3928 sk.key().fingerprint(), result);
3929 if result {
3930 good += 1;
3931 }
3932 }
3933 }
3934
3935 // Get the next packet.
3936 ppr = pp.recurse().unwrap().1;
3937 }
3938
3939 assert_eq!(good, test.good, "Signature verification failed.");
3940
3941 // Again, this time with explicit hashing.
3942 let mut good = 0;
3943 let mut ppr = PacketParserBuilder::from_bytes(
3944 crate::tests::message(test.data)).unwrap()
3945 .automatic_hashing(false)
3946 .build().unwrap();
3947 while let PacketParserResult::Some(mut pp) = ppr {
3948 if let Packet::OnePassSig(_) = &pp.packet {
3949 pp.start_hashing().unwrap();
3950 }
3951
3952 if let Packet::Signature(sig) = &mut pp.packet {
3953 let result = sig.verify_document(cert.primary_key().key()).is_ok();
3954 eprintln!(" Primary {:?}: {:?}",
3955 cert.fingerprint(), result);
3956 if result {
3957 good += 1;
3958 }
3959
3960 for sk in cert.subkeys() {
3961 let result = sig.verify_document(sk.key()).is_ok();
3962 eprintln!(" Subkey {:?}: {:?}",
3963 sk.key().fingerprint(), result);
3964 if result {
3965 good += 1;
3966 }
3967 }
3968 }
3969
3970 // Get the next packet.
3971 ppr = pp.recurse().unwrap().1;
3972 }
3973
3974 assert_eq!(good, test.good, "Signature verification with \
3975 explicit hashing failed.");
3976 }
3977 }
3978
3979 #[test]
3980 fn signature_level() {
3981 use crate::PacketPile;
3982 let p = PacketPile::from_bytes(
3983 crate::tests::message("signed-1-notarized-by-ed25519.pgp")).unwrap()
3984 .into_children().collect::<Vec<Packet>>();
3985
3986 if let Packet::Signature(ref sig) = &p[3] {
3987 assert_eq!(sig.level(), 0);
3988 } else {
3989 panic!("expected signature")
3990 }
3991
3992 if let Packet::Signature(ref sig) = &p[4] {
3993 assert_eq!(sig.level(), 1);
3994 } else {
3995 panic!("expected signature")
3996 }
3997 }
3998
3999 #[test]
4000 fn sign_verify() {
4001 let hash_algo = HashAlgorithm::SHA512;
4002 let mut hash = vec![0; hash_algo.digest_size().unwrap()];
4003 crypto::random(&mut hash).unwrap();
4004
4005 for key in &[
4006 "testy-private.pgp",
4007 "dennis-simon-anton-private.pgp",
4008 "erika-corinna-daniela-simone-antonia-nistp256-private.pgp",
4009 "erika-corinna-daniela-simone-antonia-nistp384-private.pgp",
4010 "erika-corinna-daniela-simone-antonia-nistp521-private.pgp",
4011 "emmelie-dorothea-dina-samantha-awina-ed25519-private.pgp",
4012 ] {
4013 eprintln!("{}...", key);
4014 let cert = Cert::from_bytes(crate::tests::key(key)).unwrap();
4015
4016 if ! cert.primary_key().key().pk_algo().is_supported() {
4017 eprintln!("Skipping because we don't support the algo");
4018 continue;
4019 }
4020
4021 if let Some(curve) = match cert.primary_key().key().mpis() {
4022 mpi::PublicKey::EdDSA { curve, .. } => Some(curve),
4023 mpi::PublicKey::ECDSA { curve, .. } => Some(curve),
4024 _ => None,
4025 } {
4026 if ! curve.is_supported() {
4027 eprintln!("Skipping because we don't support {}", curve);
4028 continue;
4029 }
4030 }
4031
4032 let mut pair = cert.primary_key().key().clone()
4033 .parts_into_secret().unwrap()
4034 .into_keypair()
4035 .expect("secret key is encrypted/missing");
4036
4037 let sig = SignatureBuilder::new(SignatureType::Binary);
4038 let hash = hash_algo.context().unwrap()
4039 .for_signature(pair.public().version());
4040
4041 // Make signature.
4042 let sig = sig.sign_hash(&mut pair, hash).unwrap();
4043
4044 // Good signature.
4045 let mut hash = hash_algo.context().unwrap()
4046 .for_signature(sig.version());
4047 sig.hash(&mut hash).unwrap();
4048 let mut digest = vec![0u8; hash.digest_size()];
4049 hash.digest(&mut digest).unwrap();
4050 sig.verify_digest(pair.public(), &digest[..]).unwrap();
4051
4052 // Bad signature.
4053 digest[0] ^= 0xff;
4054 sig.verify_digest(pair.public(), &digest[..]).unwrap_err();
4055 }
4056 }
4057
4058 #[test]
4059 fn sign_message() {
4060 use crate::types::Curve::*;
4061
4062 for curve in vec![
4063 Ed25519,
4064 NistP256,
4065 NistP384,
4066 NistP521,
4067 ] {
4068 if ! curve.is_supported() {
4069 eprintln!("Skipping unsupported {:?}", curve);
4070 continue;
4071 }
4072
4073 let key: Key<key::SecretParts, key::PrimaryRole>
4074 = Key6::generate_ecc(true, curve).unwrap().into();
4075 let msg = b"Hello, World";
4076 let mut pair = key.into_keypair().unwrap();
4077 let sig = SignatureBuilder::new(SignatureType::Binary)
4078 .sign_message(&mut pair, msg).unwrap();
4079
4080 sig.verify_message(pair.public(), msg).unwrap();
4081 }
4082 }
4083
4084 #[test]
4085 fn verify_message() {
4086 let cert = Cert::from_bytes(crate::tests::key(
4087 "emmelie-dorothea-dina-samantha-awina-ed25519.pgp")).unwrap();
4088 let msg = crate::tests::manifesto();
4089 let p = Packet::from_bytes(
4090 crate::tests::message("a-cypherpunks-manifesto.txt.ed25519.sig"))
4091 .unwrap();
4092 let sig = if let Packet::Signature(s) = p {
4093 s
4094 } else {
4095 panic!("Expected a Signature, got: {:?}", p);
4096 };
4097
4098 sig.verify_message(cert.primary_key().key(), msg).unwrap();
4099 }
4100
4101 #[test]
4102 #[allow(deprecated)]
4103 fn verify_v3_sig() {
4104 if ! PublicKeyAlgorithm::DSA.is_supported() {
4105 return;
4106 }
4107
4108 let cert = Cert::from_bytes(crate::tests::key(
4109 "dennis-simon-anton-private.pgp")).unwrap();
4110 let msg = crate::tests::manifesto();
4111 let p = Packet::from_bytes(
4112 crate::tests::message("a-cypherpunks-manifesto.txt.dennis-simon-anton-v3.sig"))
4113 .unwrap();
4114 let sig = if let Packet::Signature(s) = p {
4115 assert_eq!(s.version(), 3);
4116 s
4117 } else {
4118 panic!("Expected a Signature, got: {:?}", p);
4119 };
4120
4121 sig.verify_message(cert.primary_key().key(), msg).unwrap();
4122 }
4123
4124 #[test]
4125 fn sign_with_short_ed25519_secret_key() {
4126 // 20 byte sec key
4127 let secret_key = [
4128 0x0,0x0,
4129 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
4130 0x1,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,
4131 0x1,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2
4132 ];
4133
4134 let key: key::SecretKey = Key4::import_secret_ed25519(&secret_key, None)
4135 .unwrap().into();
4136
4137 let mut pair = key.into_keypair().unwrap();
4138 let msg = b"Hello, World";
4139 let mut hash = HashAlgorithm::SHA256.context().unwrap()
4140 .for_signature(pair.public().version());
4141
4142 hash.update(&msg[..]);
4143
4144 SignatureBuilder::new(SignatureType::Text)
4145 .sign_hash(&mut pair, hash).unwrap();
4146 }
4147
4148 #[test]
4149 fn verify_gpg_3rd_party_cert() {
4150 use crate::Cert;
4151
4152 let p = &P::new();
4153
4154 let test1 = Cert::from_bytes(
4155 crate::tests::key("test1-certification-key.pgp")).unwrap();
4156 let cert_key1 = test1.keys().with_policy(p, None)
4157 .for_certification()
4158 .next()
4159 .map(|ka| ka.key())
4160 .unwrap();
4161 let test2 = Cert::from_bytes(
4162 crate::tests::key("test2-signed-by-test1.pgp")).unwrap();
4163 let uid = test2.userids().with_policy(p, None).next().unwrap();
4164 let cert = uid.certifications().next().unwrap().clone();
4165
4166 cert.verify_userid_binding(cert_key1,
4167 test2.primary_key().key(),
4168 uid.userid()).unwrap();
4169 }
4170
4171 #[test]
4172 fn normalize() {
4173 use crate::Fingerprint;
4174 use crate::packet::signature::subpacket::*;
4175
4176 let key : key::SecretKey
4177 = Key6::generate_ecc(true, Curve::Ed25519).unwrap().into();
4178 let mut pair = key.into_keypair().unwrap();
4179 let msg = b"Hello, World";
4180 let mut hash = HashAlgorithm::SHA256.context().unwrap()
4181 .for_signature(pair.public().version());
4182 hash.update(&msg[..]);
4183
4184 let fp =
4185 Fingerprint::from_bytes(4, b"bbbbbbbbbbbbbbbbbbbb").unwrap();
4186 let keyid = KeyID::from(&fp);
4187
4188 // First, make sure any superfluous subpackets are removed,
4189 // yet the Issuer, IssuerFingerprint and EmbeddedSignature
4190 // ones are kept.
4191 let mut builder = SignatureBuilder::new(SignatureType::Text);
4192 builder.unhashed_area_mut().add(Subpacket::new(
4193 SubpacketValue::IssuerFingerprint(fp.clone()), false).unwrap())
4194 .unwrap();
4195 builder.unhashed_area_mut().add(Subpacket::new(
4196 SubpacketValue::Issuer(keyid.clone()), false).unwrap())
4197 .unwrap();
4198 // This subpacket does not belong there, and should be
4199 // removed.
4200 builder.unhashed_area_mut().add(Subpacket::new(
4201 SubpacketValue::PreferredSymmetricAlgorithms(Vec::new()),
4202 false).unwrap()).unwrap();
4203
4204 // Build and add an embedded sig.
4205 let embedded_sig = SignatureBuilder::new(SignatureType::PrimaryKeyBinding)
4206 .sign_hash(&mut pair, hash.clone()).unwrap();
4207 builder.unhashed_area_mut().add(Subpacket::new(
4208 SubpacketValue::EmbeddedSignature(embedded_sig), false).unwrap())
4209 .unwrap();
4210 let sig = builder.sign_hash(&mut pair,
4211 hash.clone()).unwrap().normalize();
4212 assert_eq!(sig.unhashed_area().iter().count(), 3);
4213 assert_eq!(*sig.unhashed_area().iter().next().unwrap(),
4214 Subpacket::new(SubpacketValue::Issuer(keyid.clone()),
4215 false).unwrap());
4216 assert_eq!(sig.unhashed_area().iter().nth(1).unwrap().tag(),
4217 SubpacketTag::EmbeddedSignature);
4218 assert_eq!(*sig.unhashed_area().iter().nth(2).unwrap(),
4219 Subpacket::new(SubpacketValue::IssuerFingerprint(fp.clone()),
4220 false).unwrap());
4221 }
4222
4223 #[test]
4224 fn standalone_signature_roundtrip() {
4225 let key : key::SecretKey
4226 = Key6::generate_ecc(true, Curve::Ed25519).unwrap().into();
4227 let mut pair = key.into_keypair().unwrap();
4228
4229 let sig = SignatureBuilder::new(SignatureType::Standalone)
4230 .sign_standalone(&mut pair)
4231 .unwrap();
4232
4233 sig.verify_standalone(pair.public()).unwrap();
4234 }
4235
4236 #[test]
4237 #[allow(deprecated)]
4238 fn timestamp_signature() {
4239 if ! PublicKeyAlgorithm::DSA.is_supported() {
4240 eprintln!("Skipping test, algorithm is not supported.");
4241 return;
4242 }
4243
4244 let alpha = Cert::from_bytes(crate::tests::file(
4245 "contrib/gnupg/keys/alpha.pgp")).unwrap();
4246 let p = Packet::from_bytes(crate::tests::file(
4247 "contrib/gnupg/timestamp-signature-by-alice.asc")).unwrap();
4248 if let Packet::Signature(sig) = p {
4249 let mut hash = sig.hash_algo().context().unwrap()
4250 .for_signature(sig.version());
4251 sig.hash_timestamp(&mut hash).unwrap();
4252 let digest = hash.into_digest().unwrap();
4253 eprintln!("{}", crate::fmt::hex::encode(&digest));
4254 sig.verify_timestamp(alpha.primary_key().key()).unwrap();
4255 } else {
4256 panic!("expected a signature packet");
4257 }
4258 }
4259
4260 #[test]
4261 fn timestamp_signature_roundtrip() {
4262 let key : key::SecretKey
4263 = Key6::generate_ecc(true, Curve::Ed25519).unwrap().into();
4264 let mut pair = key.into_keypair().unwrap();
4265
4266 let sig = SignatureBuilder::new(SignatureType::Timestamp)
4267 .sign_timestamp(&mut pair)
4268 .unwrap();
4269
4270 sig.verify_timestamp(pair.public()).unwrap();
4271 }
4272
4273 #[test]
4274 fn get_issuers_prefers_fingerprints() -> Result<()> {
4275 use crate::KeyHandle;
4276 for f in [
4277 // This has Fingerprint in the hashed, Issuer in the
4278 // unhashed area.
4279 "messages/sig.pgp",
4280 // This has [Issuer, Fingerprint] in the hashed area.
4281 "contrib/gnupg/timestamp-signature-by-alice.asc",
4282 ].iter() {
4283 let p = Packet::from_bytes(crate::tests::file(f))?;
4284 if let Packet::Signature(sig) = p {
4285 let issuers = sig.get_issuers();
4286 assert_match!(KeyHandle::Fingerprint(_) = &issuers[0]);
4287 assert_match!(KeyHandle::KeyID(_) = &issuers[1]);
4288 } else {
4289 panic!("expected a signature packet");
4290 }
4291 }
4292 Ok(())
4293 }
4294
4295 /// Checks that binding signatures of newly created certificates
4296 /// can be conveniently and robustly be overwritten without
4297 /// fiddling with creation timestamps.
4298 #[test]
4299 fn binding_signatures_are_overrideable() -> Result<()> {
4300 use crate::packet::signature::subpacket::NotationDataFlags;
4301 let notation_key = "override-test@sequoia-pgp.org";
4302 let p = &P::new();
4303
4304 // Create a certificate and try to update the userid's binding
4305 // signature.
4306 let (mut alice, _) =
4307 CertBuilder::general_purpose(Some("alice@example.org"))
4308 .generate()?;
4309 let mut primary_signer = alice.primary_key().key().clone()
4310 .parts_into_secret()?.into_keypair()?;
4311 assert_eq!(alice.userids().len(), 1);
4312 assert_eq!(alice.userids().next().unwrap().self_signatures().count(), 1);
4313
4314 const TRIES: u64 = 5;
4315 assert!(TRIES * 10 < SIG_BACKDATE_BY);
4316 for i in 0..TRIES {
4317 assert_eq!(alice.userids().next().unwrap().self_signatures().count(),
4318 1 + i as usize);
4319
4320 // Get the binding signature so that we can modify it.
4321 let sig = alice.with_policy(p, None)?.userids().next().unwrap()
4322 .binding_signature().clone();
4323
4324 let new_sig = match
4325 SignatureBuilder::from(sig)
4326 .set_notation(notation_key,
4327 i.to_string().as_bytes(),
4328 NotationDataFlags::empty().set_human_readable(),
4329 false)?
4330 .sign_userid_binding(&mut primary_signer,
4331 alice.primary_key().component(),
4332 alice.userids().next().unwrap().userid()) {
4333 Ok(v) => v,
4334 Err(e) => {
4335 eprintln!("Failed to make {} signatures on top of \
4336 the original one.", i);
4337 return Err(e); // Not cool.
4338 },
4339 };
4340
4341 // Merge it and check that the new binding signature is
4342 // the current one.
4343 alice = alice.insert_packets(new_sig.clone())?.0;
4344 let sig = alice.with_policy(p, None)?.userids().next().unwrap()
4345 .binding_signature();
4346 assert_eq!(sig, &new_sig);
4347 }
4348
4349 Ok(())
4350 }
4351
4352 /// Checks that subpackets are marked as authentic on signature
4353 /// verification.
4354 #[test]
4355 fn subpacket_authentication() -> Result<()> {
4356 use subpacket::{Subpacket, SubpacketValue};
4357
4358 // We'll study this certificate, because it contains a
4359 // signing-capable subkey.
4360 let mut pp = crate::PacketPile::from_bytes(crate::tests::key(
4361 "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
4362 assert_eq!(pp.children().count(), 5);
4363
4364 // The signatures have not been verified, hence no subpacket
4365 // is authenticated.
4366 if let Some(Packet::Signature(sig)) = pp.path_ref_mut(&[4]) {
4367 assert!(sig.hashed_area().iter().all(|p| ! p.authenticated()));
4368 assert!(sig.unhashed_area().iter().all(|p| ! p.authenticated()));
4369
4370 // Add a bogus issuer subpacket.
4371 sig.unhashed_area_mut().add(Subpacket::new(
4372 SubpacketValue::Issuer("AAAA BBBB CCCC DDDD".parse()?),
4373 false)?)?;
4374 } else {
4375 panic!("expected a signature");
4376 }
4377
4378 // Break the userid binding signature.
4379 if let Some(Packet::Signature(sig)) = pp.path_ref_mut(&[2]) {
4380 assert!(sig.hashed_area().iter().all(|p| ! p.authenticated()));
4381 assert!(sig.unhashed_area().iter().all(|p| ! p.authenticated()));
4382
4383 // Add a bogus issuer subpacket to the hashed area
4384 // breaking the signature.
4385 sig.hashed_area_mut().add(Subpacket::new(
4386 SubpacketValue::Issuer("AAAA BBBB CCCC DDDD".parse()?),
4387 false)?)?;
4388 } else {
4389 panic!("expected a signature");
4390 }
4391
4392 // Parse into cert verifying the signatures.
4393 use std::convert::TryFrom;
4394 let cert = Cert::try_from(pp)?;
4395 assert_eq!(cert.bad_signatures().count(), 1);
4396 assert_eq!(cert.keys().subkeys().count(), 1);
4397 let subkey = cert.keys().subkeys().next().unwrap();
4398 assert_eq!(subkey.self_signatures().count(), 1);
4399
4400 // All the authentic information in the self signature has
4401 // been authenticated by the verification process.
4402 let sig = &subkey.self_signatures().next().unwrap();
4403 assert!(sig.hashed_area().iter().all(|p| p.authenticated()));
4404 // All but our fake issuer information.
4405 assert!(sig.unhashed_area().iter().all(|p| {
4406 if let SubpacketValue::Issuer(id) = p.value() {
4407 if id == &"AAAA BBBB CCCC DDDD".parse().unwrap() {
4408 // Our fake id...
4409 true
4410 } else {
4411 p.authenticated()
4412 }
4413 } else {
4414 p.authenticated()
4415 }
4416 }));
4417 // Check the subpackets in the embedded signature.
4418 let sig = sig.embedded_signatures().next().unwrap();
4419 assert!(sig.hashed_area().iter().all(|p| p.authenticated()));
4420 assert!(sig.unhashed_area().iter().all(|p| p.authenticated()));
4421
4422 // No information in the bad signature has been authenticated.
4423 let sig = cert.bad_signatures().next().unwrap();
4424 assert!(sig.hashed_area().iter().all(|p| ! p.authenticated()));
4425 assert!(sig.unhashed_area().iter().all(|p| ! p.authenticated()));
4426 Ok(())
4427 }
4428
4429 /// Checks that signature normalization adds missing issuer
4430 /// information.
4431 #[test]
4432 fn normalization_adds_missing_issuers() -> Result<()> {
4433 use subpacket::SubpacketTag;
4434
4435 let mut pp = crate::PacketPile::from_bytes(crate::tests::key(
4436 "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
4437 assert_eq!(pp.children().count(), 5);
4438
4439 // Remove the issuer subpacket from a binding signature.
4440 if let Some(Packet::Signature(sig)) = pp.path_ref_mut(&[4]) {
4441 sig.unhashed_area_mut().remove_all(SubpacketTag::Issuer);
4442 assert_eq!(sig.get_issuers().len(), 1);
4443 } else {
4444 panic!("expected a signature");
4445 }
4446
4447 // Verify the subkey binding without parsing into cert.
4448 let primary_key =
4449 if let Some(Packet::PublicKey(key)) = pp.path_ref(&[0]) {
4450 key
4451 } else {
4452 panic!("Expected a primary key");
4453 };
4454 let subkey =
4455 if let Some(Packet::PublicSubkey(key)) = pp.path_ref(&[3]) {
4456 key
4457 } else {
4458 panic!("Expected a subkey");
4459 };
4460 let sig =
4461 if let Some(Packet::Signature(sig)) = pp.path_ref(&[4]) {
4462 sig.clone()
4463 } else {
4464 panic!("expected a signature");
4465 };
4466
4467
4468 // The signature has only an issuer fingerprint.
4469 assert_eq!(sig.get_issuers().len(), 1);
4470 assert_eq!(sig.subpackets(SubpacketTag::Issuer).count(), 0);
4471 // But normalization after verification adds the missing
4472 // information.
4473 sig.verify_subkey_binding(primary_key, primary_key, subkey)?;
4474 let normalized_sig = sig.normalize();
4475 assert_eq!(normalized_sig.subpackets(SubpacketTag::Issuer).count(), 1);
4476 Ok(())
4477 }
4478
4479 /// Tests signature merging.
4480 #[test]
4481 fn merging() -> Result<()> {
4482 use crate::packet::signature::subpacket::*;
4483
4484 let key: key::SecretKey
4485 = Key6::generate_ecc(true, Curve::Ed25519)?.into();
4486 let mut pair = key.into_keypair()?;
4487 let msg = b"Hello, World";
4488 let mut hash = HashAlgorithm::SHA256.context()?
4489 .for_signature(pair.public().version());
4490 hash.update(&msg[..]);
4491
4492 let fp = pair.public().fingerprint();
4493 let keyid = KeyID::from(&fp);
4494
4495 // Make a feeble signature with issuer information in the
4496 // unhashed area.
4497 let sig = SignatureBuilder::new(SignatureType::Text)
4498 .modify_unhashed_area(|mut a| {
4499 a.add(Subpacket::new(
4500 SubpacketValue::IssuerFingerprint(fp.clone()), false)?)?;
4501 a.add(Subpacket::new(
4502 SubpacketValue::Issuer(keyid.clone()), false)?)?;
4503 Ok(a)
4504 })?
4505 .sign_hash(&mut pair, hash.clone())?;
4506
4507 // Try to displace the issuer information.
4508 let dummy: crate::KeyID = "AAAA BBBB CCCC DDDD".parse()?;
4509 let mut malicious = sig.clone();
4510 malicious.unhashed_area_mut().clear();
4511 loop {
4512 let r = malicious.unhashed_area_mut().add(Subpacket::new(
4513 SubpacketValue::Issuer(dummy.clone()), false)?);
4514 if r.is_err() {
4515 break;
4516 }
4517 }
4518
4519 // Merge and check that the issuer information is intact.
4520 // This works without any issuer being authenticated because
4521 // of the deduplicating nature of the merge.
4522 let merged = sig.clone().merge(malicious.clone())?;
4523 let issuers = merged.get_issuers();
4524 let keyid_issuers = merged.issuers().collect::<Vec<&KeyID>>();
4525 assert_eq!(issuers.len(), 3);
4526 assert!(issuers.contains(&KeyHandle::from(&fp)));
4527 assert!(keyid_issuers.contains(&&keyid));
4528 assert!(keyid_issuers.contains(&&dummy));
4529
4530 // Same, but the other way around.
4531 let merged = malicious.clone().merge(sig.clone())?;
4532 let issuers = merged.get_issuers();
4533 let keyid_issuers = merged.issuers().collect::<Vec<_>>();
4534 assert_eq!(issuers.len(), 3);
4535 assert!(issuers.contains(&KeyHandle::from(&fp)));
4536 assert!(keyid_issuers.contains(&&keyid));
4537 assert!(keyid_issuers.contains(&&dummy));
4538
4539 // Try to displace the issuer information using garbage
4540 // packets.
4541 let mut malicious = sig.clone();
4542 malicious.unhashed_area_mut().clear();
4543 let mut i: u64 = 0;
4544 loop {
4545 let r = malicious.unhashed_area_mut().add(Subpacket::new(
4546 SubpacketValue::Unknown {
4547 tag: SubpacketTag::Unknown(231),
4548 body: i.to_be_bytes().iter().cloned().collect(),
4549 }, false)?);
4550 if r.is_err() {
4551 break;
4552 }
4553 i += 1;
4554 }
4555
4556 // Merge and check that the issuer information is intact.
4557 // This works without any issuer being authenticated because
4558 // the merge prefers plausible packets.
4559 let merged = sig.clone().merge(malicious.clone())?;
4560 let issuers = merged.get_issuers();
4561 let keyid_issuers = merged.issuers().collect::<Vec<_>>();
4562 assert_eq!(issuers.len(), 2);
4563 assert!(issuers.contains(&KeyHandle::from(&fp)));
4564 assert!(keyid_issuers.contains(&&keyid));
4565
4566 // Same, but the other way around.
4567 let merged = malicious.clone().merge(sig.clone())?;
4568 let issuers = merged.get_issuers();
4569 let keyid_issuers = merged.issuers().collect::<Vec<_>>();
4570 assert_eq!(issuers.len(), 2);
4571 assert!(issuers.contains(&KeyHandle::from(&fp)));
4572 assert!(keyid_issuers.contains(&&keyid));
4573
4574 // Try to displace the issuer information by using random keyids.
4575 let mut malicious = sig.clone();
4576 malicious.unhashed_area_mut().clear();
4577 let mut i: u64 = 1;
4578 loop {
4579 let r = malicious.unhashed_area_mut().add(Subpacket::new(
4580 SubpacketValue::Issuer(i.into()), false)?);
4581 if r.is_err() {
4582 break;
4583 }
4584 i += 1;
4585 }
4586
4587 // Merge and check that the issuer information is intact.
4588 // This works because the issuer information is being
4589 // authenticated by the verification, and the merge process
4590 // prefers authenticated information.
4591 let verified = sig.clone();
4592 verified.verify_hash(pair.public(), hash.clone())?;
4593
4594 let merged = verified.clone().merge(malicious.clone())?;
4595 let issuers = merged.get_issuers();
4596 let keyid_issuers = merged.issuers().collect::<Vec<_>>();
4597 assert!(issuers.contains(&KeyHandle::from(&fp)));
4598 assert!(keyid_issuers.contains(&&keyid));
4599
4600 // Same, but the other way around.
4601 let merged = malicious.clone().merge(verified.clone())?;
4602 let issuers = merged.get_issuers();
4603 let keyid_issuers = merged.issuers().collect::<Vec<_>>();
4604 assert!(issuers.contains(&KeyHandle::from(&fp)));
4605 assert!(keyid_issuers.contains(&&keyid));
4606
4607 Ok(())
4608 }
4609
4610 #[test]
4611 fn issue_998() -> Result<()> {
4612 let now_t = Timestamp::try_from(crate::now())?;
4613 let now = SystemTime::from(now_t);
4614 let hour = std::time::Duration::new(3600, 0);
4615 let hour_t = crate::types::Duration::from(3600);
4616 let past = now - 2 * hour;
4617
4618 let sig = SignatureBuilder::new(SignatureType::PositiveCertification)
4619 .modify_hashed_area(|mut a| {
4620 a.add(Subpacket::new(
4621 SubpacketValue::SignatureCreationTime(now_t), true)?)?;
4622 a.add(Subpacket::new(
4623 SubpacketValue::SignatureExpirationTime(hour_t), true)?)?;
4624 Ok(a)
4625 })?;
4626 let sig = sig.set_reference_time(now)?;
4627 assert_eq!(sig.signature_expiration_time(), Some(now + hour));
4628 let sig = sig.set_reference_time(past)?;
4629 assert_eq!(sig.signature_expiration_time(), Some(now - hour));
4630 Ok(())
4631 }
4632}