sequoia_openpgp/packet/signature/subpacket.rs
1//! Signature subpackets.
2//!
3//! OpenPGP signature packets include a set of key-value attributes
4//! called subpackets. These subpackets are used to indicate when a
5//! signature was created, who created the signature, user &
6//! implementation preferences, etc. The full details are in [Section
7//! 5.2.3.7 of RFC 9580].
8//!
9//! [Section 5.2.3.7 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.7
10//!
11//! The standard assigns each subpacket a numeric id, and describes
12//! the format of its value. One subpacket is called Notation Data
13//! and is intended as a generic key-value store. The combined size
14//! of the subpackets (including notation data) is limited to 64 KB.
15//!
16//! Subpackets and notations can be marked as critical. If an OpenPGP
17//! implementation processes a packet that includes critical
18//! subpackets or notations that it does not understand, it is
19//! required to abort processing. This allows for forwards compatible
20//! changes by indicating whether it is safe to ignore an unknown
21//! subpacket or notation.
22//!
23//! A number of methods are defined on [`Signature`] for working with
24//! subpackets.
25//!
26//! [`Signature`]: super::super::Signature
27//!
28//! # Examples
29//!
30//! Print any Issuer Fingerprint subpackets:
31//!
32//! ```rust
33//! # use sequoia_openpgp as openpgp;
34//! # use openpgp::Result;
35//! # use openpgp::Packet;
36//! # use openpgp::parse::{Parse, PacketParserResult, PacketParser};
37//! #
38//! # f(include_bytes!("../../../tests/data/messages/signed.pgp"));
39//! #
40//! # fn f(message_data: &[u8]) -> Result<()> {
41//! let mut ppr = PacketParser::from_bytes(message_data)?;
42//! while let PacketParserResult::Some(mut pp) = ppr {
43//! if let Packet::Signature(ref sig) = pp.packet {
44//! for fp in sig.issuer_fingerprints() {
45//! eprintln!("Signature allegedly issued by: {}", fp.to_string());
46//! }
47//! }
48//!
49//! // Get the next packet.
50//! ppr = pp.recurse()?.1;
51//! }
52//! # Ok(())
53//! # }
54//! ```
55
56use std::cmp::Ordering;
57use std::convert::{TryInto, TryFrom};
58use std::hash::{Hash, Hasher};
59use std::ops::{Deref, DerefMut};
60use std::fmt;
61use std::cmp;
62use std::sync::atomic;
63use std::time;
64
65#[cfg(test)]
66use quickcheck::{Arbitrary, Gen};
67#[cfg(test)]
68use crate::packet::signature::ArbitraryBounded;
69
70use crate::{
71 Error,
72 Result,
73 packet::header::BodyLength,
74 packet::Signature,
75 packet::signature::{self, Signature4},
76 packet::key,
77 packet::Key,
78 Fingerprint,
79 KeyID,
80 serialize::MarshalInto,
81};
82use crate::types::{
83 AEADAlgorithm,
84 CompressionAlgorithm,
85 Duration,
86 Features,
87 HashAlgorithm,
88 KeyFlags,
89 KeyServerPreferences,
90 PublicKeyAlgorithm,
91 ReasonForRevocation,
92 RevocationKey,
93 SymmetricAlgorithm,
94 Timestamp,
95};
96
97/// The default amount of tolerance to use when comparing
98/// some timestamps.
99///
100/// Used by `Subpacket::signature_alive`.
101///
102/// When determining whether a timestamp generated on another
103/// machine is valid *now*, we need to account for clock skew.
104/// (Note: you don't normally need to consider clock skew when
105/// evaluating a signature's validity at some time in the past.)
106///
107/// We tolerate half an hour of skew based on the following
108/// anecdote: In 2019, a developer using Sequoia in a Windows VM
109/// running inside Virtual Box on Mac OS X reported that he
110/// typically observed a few minutes of clock skew and
111/// occasionally saw over 20 minutes of clock skew.
112///
113/// Note: when new messages override older messages, and their
114/// signatures are evaluated at some arbitrary point in time, an
115/// application may not see a consistent state if it uses a
116/// tolerance. Consider an application that has two messages and
117/// wants to get the current message at time te:
118///
119/// - t0: message 0
120/// - te: "get current message"
121/// - t1: message 1
122///
123/// If te is close to t1, then t1 may be considered valid, which
124/// is probably not what you want.
125pub const CLOCK_SKEW_TOLERANCE: time::Duration
126 = time::Duration::new(30 * 60, 0);
127
128/// The subpacket types.
129///
130/// The `SubpacketTag` enum holds a [`Subpacket`]'s identifier, the
131/// so-called tag.
132#[non_exhaustive]
133#[derive(Debug)]
134#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
135#[derive(Clone, Copy)]
136pub enum SubpacketTag {
137 /// The time the signature was made.
138 ///
139 /// See [Section 5.2.3.11 of RFC 9580] for details.
140 ///
141 /// [Section 5.2.3.11 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
142 SignatureCreationTime,
143 /// The validity period of the signature.
144 ///
145 /// The validity is relative to the time stored in the signature's
146 /// Signature Creation Time subpacket.
147 ///
148 /// See [Section 5.2.3.18 of RFC 9580] for details.
149 ///
150 /// [Section 5.2.3.18 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.18
151 SignatureExpirationTime,
152 /// Whether a signature should be published.
153 ///
154 /// See [Section 5.2.3.19 of RFC 9580] for details.
155 ///
156 /// [Section 5.2.3.19 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.19
157 ExportableCertification,
158 /// Signer asserts that the key is not only valid but also trustworthy at
159 /// the specified level.
160 ///
161 /// See [Section 5.2.3.21 of RFC 9580] for details.
162 ///
163 /// [Section 5.2.3.21 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.21
164 TrustSignature,
165 /// Used in conjunction with Trust Signature packets (of level > 0) to
166 /// limit the scope of trust that is extended.
167 ///
168 /// See [Section 5.2.3.22 of RFC 9580] for details.
169 ///
170 /// [Section 5.2.3.22 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.22
171 RegularExpression,
172 /// Whether a signature can later be revoked.
173 ///
174 /// See [Section 5.2.3.20 of RFC 9580] for details.
175 ///
176 /// [Section 5.2.3.20 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.20
177 Revocable,
178 /// The validity period of the key.
179 ///
180 /// The validity period is relative to the key's (not the signature's) creation time.
181 ///
182 /// See [Section 5.2.3.13 of RFC 9580] for details.
183 ///
184 /// [Section 5.2.3.13 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
185 KeyExpirationTime,
186 /// Deprecated
187 PlaceholderForBackwardCompatibility,
188 /// The Symmetric algorithms that the certificate holder prefers.
189 ///
190 /// See [Section 5.2.3.14 of RFC 9580] for details.
191 ///
192 /// [Section 5.2.3.14 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.14
193 PreferredSymmetricAlgorithms,
194 /// Authorizes the specified key to issue revocation signatures for this
195 /// certificate.
196 ///
197 /// See [Section 5.2.3.23 of RFC 9580] for details.
198 ///
199 /// [Section 5.2.3.23 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.23
200 RevocationKey,
201 /// The OpenPGP Key ID of the key issuing the signature.
202 ///
203 /// See [Section 5.2.3.12 of RFC 9580] for details.
204 ///
205 /// [Section 5.2.3.12 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
206 Issuer,
207 /// A "notation" on the signature.
208 ///
209 /// See [Section 5.2.3.24 of RFC 9580] for details.
210 ///
211 /// [Section 5.2.3.24 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
212 NotationData,
213 /// The Hash algorithms that the certificate holder prefers.
214 ///
215 /// See [Section 5.2.3.16 of RFC 9580] for details.
216 ///
217 /// [Section 5.2.3.16 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.16
218 PreferredHashAlgorithms,
219 /// The compression algorithms that the certificate holder prefers.
220 ///
221 /// See [Section 5.2.3.17 of RFC 9580] for details.
222 ///
223 /// [Section 5.2.3.17 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.17
224 PreferredCompressionAlgorithms,
225 /// A list of flags that indicate preferences that the certificate
226 /// holder has about how the key is handled by a key server.
227 ///
228 /// See [Section 5.2.3.25 of RFC 9580] for details.
229 ///
230 /// [Section 5.2.3.25 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.25
231 KeyServerPreferences,
232 /// The URI of a key server where the certificate holder keeps
233 /// their certificate up to date.
234 ///
235 /// See [Section 5.2.3.26 of RFC 9580] for details.
236 ///
237 /// [Section 5.2.3.26 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.26
238 PreferredKeyServer,
239 /// A flag in a User ID's self-signature that states whether this
240 /// User ID is the primary User ID for this certificate.
241 ///
242 /// See [Section 5.2.3.27 of RFC 9580] for details.
243 ///
244 /// [Section 5.2.3.27 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.27
245 PrimaryUserID,
246 /// The URI of a document that describes the policy under which
247 /// the signature was issued.
248 ///
249 /// See [Section 5.2.3.28 of RFC 9580] for details.
250 ///
251 /// [Section 5.2.3.28 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.28
252 PolicyURI,
253 /// A list of flags that hold information about a key.
254 ///
255 /// See [Section 5.2.3.29 of RFC 9580] for details.
256 ///
257 /// [Section 5.2.3.29 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.29
258 KeyFlags,
259 /// The User ID that is responsible for the signature.
260 ///
261 /// See [Section 5.2.3.30 of RFC 9580] for details.
262 ///
263 /// [Section 5.2.3.30 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.30
264 SignersUserID,
265 /// The reason for a revocation, used in key revocations and
266 /// certification revocation signatures.
267 ///
268 /// See [Section 5.2.3.31 of RFC 9580] for details.
269 ///
270 /// [Section 5.2.3.31 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.31
271 ReasonForRevocation,
272 /// The OpenPGP features a user's implementation supports.
273 ///
274 /// See [Section 5.2.3.32 of RFC 9580] for details.
275 ///
276 /// [Section 5.2.3.32 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.32
277 Features,
278 /// A signature to which this signature refers.
279 ///
280 /// See [Section 5.2.3.33 of RFC 9580] for details.
281 ///
282 /// [Section 5.2.3.33 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.33
283 SignatureTarget,
284 /// A complete Signature packet body.
285 ///
286 /// This is used to store a backsig in a subkey binding signature.
287 ///
288 /// See [Section 5.2.3.34 of RFC 9580] for details.
289 ///
290 /// [Section 5.2.3.34 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.34
291 EmbeddedSignature,
292
293 /// The Fingerprint of the key that issued the signature.
294 ///
295 /// See [Section 5.2.3.35 of RFC 9580] for details.
296 ///
297 /// [Section 5.2.3.35 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
298 IssuerFingerprint,
299
300 /// Reserved (was: AEAD algorithms that the certificate holder prefers).
301 #[deprecated(note = "Use PreferredAEADCiphersuites instead")]
302 PreferredAEADAlgorithms,
303
304 /// Who the signed message was intended for.
305 ///
306 /// See [Section 5.2.3.36 of RFC 9580] for details.
307 ///
308 /// [Section 5.2.3.36 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#name-intended-recipient-fingerpr
309 IntendedRecipient,
310
311 /// The Approved Certifications subpacket (experimental).
312 ///
313 /// Allows the certificate holder to attest to third party
314 /// certifications, allowing them to be distributed with the
315 /// certificate. This can be used to address certificate flooding
316 /// concerns.
317 ///
318 /// See [Section 2.2 of draft-dkg-openpgp-1pa3pc-02] for details.
319 ///
320 /// [Section 2.2 of draft-dkg-openpgp-1pa3pc-02]: https://www.ietf.org/archive/id/draft-dkg-openpgp-1pa3pc-02.html#approved-certifications-subpacket
321 ApprovedCertifications,
322
323 /// The AEAD Ciphersuites that the certificate holder prefers.
324 ///
325 /// A series of paired algorithm identifiers indicating how the
326 /// keyholder prefers to receive version 2 Symmetrically Encrypted
327 /// Integrity Protected Data. Each pair of octets indicates a
328 /// combination of a symmetric cipher and an AEAD mode that the
329 /// key holder prefers to use.
330 ///
331 /// It is assumed that only the combinations of algorithms listed
332 /// are supported by the recipient's software, with the exception
333 /// of the mandatory-to-implement combination of AES-128 and OCB.
334 /// If AES-128 and OCB are not found in the subpacket, it is
335 /// implicitly listed at the end.
336 ///
337 /// See [Section 5.2.3.15 of RFC 9580] for details.
338 ///
339 /// [Section 5.2.3.15 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#name-preferred-aead-ciphersuites
340 PreferredAEADCiphersuites,
341
342 /// Reserved subpacket tag.
343 Reserved(u8),
344 /// Private subpacket tag.
345 Private(u8),
346 /// Unknown subpacket tag.
347 Unknown(u8),
348
349 // If you add a new variant, make sure to add it to the
350 // conversions and to SUBPACKET_TAG_VARIANTS.
351}
352assert_send_and_sync!(SubpacketTag);
353
354impl fmt::Display for SubpacketTag {
355 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
356 write!(f, "{:?}", self)
357 }
358}
359
360impl From<u8> for SubpacketTag {
361 fn from(u: u8) -> Self {
362 #[allow(deprecated)]
363 match u {
364 2 => SubpacketTag::SignatureCreationTime,
365 3 => SubpacketTag::SignatureExpirationTime,
366 4 => SubpacketTag::ExportableCertification,
367 5 => SubpacketTag::TrustSignature,
368 6 => SubpacketTag::RegularExpression,
369 7 => SubpacketTag::Revocable,
370 9 => SubpacketTag::KeyExpirationTime,
371 10 => SubpacketTag::PlaceholderForBackwardCompatibility,
372 11 => SubpacketTag::PreferredSymmetricAlgorithms,
373 12 => SubpacketTag::RevocationKey,
374 16 => SubpacketTag::Issuer,
375 20 => SubpacketTag::NotationData,
376 21 => SubpacketTag::PreferredHashAlgorithms,
377 22 => SubpacketTag::PreferredCompressionAlgorithms,
378 23 => SubpacketTag::KeyServerPreferences,
379 24 => SubpacketTag::PreferredKeyServer,
380 25 => SubpacketTag::PrimaryUserID,
381 26 => SubpacketTag::PolicyURI,
382 27 => SubpacketTag::KeyFlags,
383 28 => SubpacketTag::SignersUserID,
384 29 => SubpacketTag::ReasonForRevocation,
385 30 => SubpacketTag::Features,
386 31 => SubpacketTag::SignatureTarget,
387 32 => SubpacketTag::EmbeddedSignature,
388 33 => SubpacketTag::IssuerFingerprint,
389 34 => SubpacketTag::PreferredAEADAlgorithms,
390 35 => SubpacketTag::IntendedRecipient,
391 37 => SubpacketTag::ApprovedCertifications,
392 39 => SubpacketTag::PreferredAEADCiphersuites,
393 0| 1| 8| 13| 14| 15| 17| 18| 19 | 38 => SubpacketTag::Reserved(u),
394 100..=110 => SubpacketTag::Private(u),
395 _ => SubpacketTag::Unknown(u),
396 }
397 }
398}
399
400impl From<SubpacketTag> for u8 {
401 fn from(t: SubpacketTag) -> Self {
402 #[allow(deprecated)]
403 match t {
404 SubpacketTag::SignatureCreationTime => 2,
405 SubpacketTag::SignatureExpirationTime => 3,
406 SubpacketTag::ExportableCertification => 4,
407 SubpacketTag::TrustSignature => 5,
408 SubpacketTag::RegularExpression => 6,
409 SubpacketTag::Revocable => 7,
410 SubpacketTag::KeyExpirationTime => 9,
411 SubpacketTag::PlaceholderForBackwardCompatibility => 10,
412 SubpacketTag::PreferredSymmetricAlgorithms => 11,
413 SubpacketTag::RevocationKey => 12,
414 SubpacketTag::Issuer => 16,
415 SubpacketTag::NotationData => 20,
416 SubpacketTag::PreferredHashAlgorithms => 21,
417 SubpacketTag::PreferredCompressionAlgorithms => 22,
418 SubpacketTag::KeyServerPreferences => 23,
419 SubpacketTag::PreferredKeyServer => 24,
420 SubpacketTag::PrimaryUserID => 25,
421 SubpacketTag::PolicyURI => 26,
422 SubpacketTag::KeyFlags => 27,
423 SubpacketTag::SignersUserID => 28,
424 SubpacketTag::ReasonForRevocation => 29,
425 SubpacketTag::Features => 30,
426 SubpacketTag::SignatureTarget => 31,
427 SubpacketTag::EmbeddedSignature => 32,
428 SubpacketTag::IssuerFingerprint => 33,
429 SubpacketTag::PreferredAEADAlgorithms => 34,
430 SubpacketTag::IntendedRecipient => 35,
431 SubpacketTag::ApprovedCertifications => 37,
432 SubpacketTag::PreferredAEADCiphersuites => 39,
433 SubpacketTag::Reserved(u) => u,
434 SubpacketTag::Private(u) => u,
435 SubpacketTag::Unknown(u) => u,
436 }
437 }
438}
439
440#[allow(deprecated)]
441const SUBPACKET_TAG_VARIANTS: [SubpacketTag; 29] = [
442 SubpacketTag::SignatureCreationTime,
443 SubpacketTag::SignatureExpirationTime,
444 SubpacketTag::ExportableCertification,
445 SubpacketTag::TrustSignature,
446 SubpacketTag::RegularExpression,
447 SubpacketTag::Revocable,
448 SubpacketTag::KeyExpirationTime,
449 SubpacketTag::PlaceholderForBackwardCompatibility,
450 SubpacketTag::PreferredSymmetricAlgorithms,
451 SubpacketTag::RevocationKey,
452 SubpacketTag::Issuer,
453 SubpacketTag::NotationData,
454 SubpacketTag::PreferredHashAlgorithms,
455 SubpacketTag::PreferredCompressionAlgorithms,
456 SubpacketTag::KeyServerPreferences,
457 SubpacketTag::PreferredKeyServer,
458 SubpacketTag::PrimaryUserID,
459 SubpacketTag::PolicyURI,
460 SubpacketTag::KeyFlags,
461 SubpacketTag::SignersUserID,
462 SubpacketTag::ReasonForRevocation,
463 SubpacketTag::Features,
464 SubpacketTag::SignatureTarget,
465 SubpacketTag::EmbeddedSignature,
466 SubpacketTag::IssuerFingerprint,
467 SubpacketTag::PreferredAEADAlgorithms,
468 SubpacketTag::IntendedRecipient,
469 SubpacketTag::ApprovedCertifications,
470 SubpacketTag::PreferredAEADCiphersuites,
471];
472
473impl SubpacketTag {
474 /// Returns an iterator over all valid variants.
475 ///
476 /// Returns an iterator over all known variants. This does not
477 /// include the [`SubpacketTag::Reserved`],
478 /// [`SubpacketTag::Private`], or [`SubpacketTag::Unknown`]
479 /// variants.
480 pub fn variants() -> impl Iterator<Item=Self> {
481 SUBPACKET_TAG_VARIANTS.iter().cloned()
482 }
483}
484
485#[cfg(test)]
486impl Arbitrary for SubpacketTag {
487 fn arbitrary(g: &mut Gen) -> Self {
488 u8::arbitrary(g).into()
489 }
490}
491
492#[cfg(test)]
493mod tests {
494 use super::*;
495 quickcheck! {
496 fn roundtrip(tag: SubpacketTag) -> bool {
497 let val: u8 = tag.into();
498 tag == SubpacketTag::from(val)
499 }
500 }
501
502 quickcheck! {
503 fn parse(tag: SubpacketTag) -> bool {
504 match tag {
505 SubpacketTag::Reserved(u) =>
506 u == 0 || u == 1 || u == 8
507 || u == 13 || u == 14 || u == 15
508 || u == 17 || u == 18 || u == 19
509 || u == 38,
510 SubpacketTag::Private(u) => (100..=110).contains(&u),
511 SubpacketTag::Unknown(u) => (u > 33 && u < 100) || u > 110,
512 _ => true
513 }
514 }
515 }
516
517 #[test]
518 fn subpacket_tag_variants() {
519 use std::collections::HashSet;
520 use std::iter::FromIterator;
521
522 // SUBPACKET_TAG_VARIANTS is a list. Derive it in a different way
523 // to double-check that nothing is missing.
524 let derived_variants = (0..=u8::MAX)
525 .map(SubpacketTag::from)
526 .filter(|t| {
527 match t {
528 SubpacketTag::Reserved(_) => false,
529 SubpacketTag::Private(_) => false,
530 SubpacketTag::Unknown(_) => false,
531 _ => true,
532 }
533 })
534 .collect::<HashSet<_>>();
535
536 let known_variants
537 = HashSet::from_iter(SUBPACKET_TAG_VARIANTS.iter().cloned());
538
539 let missing = known_variants
540 .symmetric_difference(&derived_variants)
541 .collect::<Vec<_>>();
542
543 assert!(missing.is_empty(), "{:?}", missing);
544 }
545}
546
547/// Subpacket area.
548///
549/// A version 4 Signature contains two areas that can stored
550/// [signature subpackets]: a so-called hashed subpacket area, and a
551/// so-called unhashed subpacket area. The hashed subpacket area is
552/// protected by the signature; the unhashed area is not. This makes
553/// the unhashed subpacket area only appropriate for
554/// self-authenticating data, like the [`Issuer`] subpacket. The
555/// [`SubpacketAreas`] data structure understands these nuances and
556/// routes lookups appropriately. As such, it is usually better to
557/// work with subpackets using that interface.
558///
559/// [signature subpackets]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.7
560/// [`Issuer`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
561///
562/// # Examples
563///
564/// ```
565/// # use sequoia_openpgp as openpgp;
566/// # use openpgp::cert::prelude::*;
567/// # use openpgp::packet::prelude::*;
568/// # use openpgp::policy::StandardPolicy;
569/// # use openpgp::types::SignatureType;
570/// #
571/// # fn main() -> openpgp::Result<()> {
572/// # let p = &StandardPolicy::new();
573/// #
574/// # let (cert, _) = CertBuilder::new().generate()?;
575/// #
576/// # let key : &Key<_, _> = cert.primary_key().key();
577/// # let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
578/// #
579/// # let msg = b"Hello, world!";
580/// # let mut sig = SignatureBuilder::new(SignatureType::Binary)
581/// # .sign_message(&mut signer, msg)?;
582/// #
583/// # // Verify it.
584/// # sig.verify_message(signer.public(), msg)?;
585/// fn sig_stats(sig: &Signature) {
586/// eprintln!("Hashed subpacket area has {} subpackets",
587/// sig.hashed_area().iter().count());
588/// eprintln!("Unhashed subpacket area has {} subpackets",
589/// sig.unhashed_area().iter().count());
590/// }
591/// # sig_stats(&sig);
592/// # Ok(())
593/// # }
594/// ```
595#[derive(Clone)]
596pub struct SubpacketArea {
597 /// The subpackets.
598 packets: Vec<Subpacket>,
599
600 // The subpacket area, but parsed so that the vector is indexed by
601 // the subpacket tag, and the value is the index of the *last*
602 // occurrence of that subpacket in the subpacket area.
603 //
604 // Since self-referential structs are a no-no, we use an index
605 // to reference the content in the area.
606 //
607 // Note: A subpacket area is at most 2**16-1 bytes large. A
608 // subpacket is at least two bytes long (one for the length, and
609 // one for the subpacket type). Thus, a subpacket area can't have
610 // more than 2**15 subpackets. This means that we need at most 15
611 // bits. Thus, instead of using an `Option<u16>`, which requires
612 // 32 bits, we use an unused value to mean not present.
613 parsed: std::sync::OnceLock<Vec<u16>>,
614}
615assert_send_and_sync!(SubpacketArea);
616
617// The value for an entry of `SubpacketArea::parsed` when the
618// subpacket is not present.
619//
620// We don't use an `Option<u16>`, as that would require 32 bits, and
621// this value is not used. See the comment for
622// `SubpacketArea::parsed`.
623const SUBPACKET_NOT_PRESENT: u16 = u16::MAX;
624
625#[cfg(test)]
626impl ArbitraryBounded for SubpacketArea {
627 fn arbitrary_bounded(g: &mut Gen, depth: usize) -> Self {
628 use crate::arbitrary_helper::gen_arbitrary_from_range;
629
630 let mut a = Self::default();
631 for _ in 0..gen_arbitrary_from_range(0..32, g) {
632 let _ = a.add(ArbitraryBounded::arbitrary_bounded(g, depth));
633 }
634
635 a
636 }
637}
638
639#[cfg(test)]
640impl_arbitrary_with_bound!(SubpacketArea);
641
642impl Default for SubpacketArea {
643 fn default() -> Self {
644 Self::new(Default::default()).unwrap()
645 }
646}
647
648impl PartialEq for SubpacketArea {
649 fn eq(&self, other: &SubpacketArea) -> bool {
650 self.cmp(other) == Ordering::Equal
651 }
652}
653
654impl Eq for SubpacketArea {}
655
656impl PartialOrd for SubpacketArea {
657 fn partial_cmp(&self, other: &SubpacketArea) -> Option<Ordering> {
658 Some(self.cmp(other))
659 }
660}
661
662impl Ord for SubpacketArea {
663 fn cmp(&self, other: &SubpacketArea) -> Ordering {
664 self.packets.cmp(&other.packets)
665 }
666}
667
668impl Hash for SubpacketArea {
669 fn hash<H: Hasher>(&self, state: &mut H) {
670 // We hash only the data, the cache is a hashmap and does not
671 // implement hash.
672 self.packets.hash(state);
673 }
674}
675
676impl fmt::Debug for SubpacketArea {
677 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
678 f.debug_list()
679 .entries(self.iter())
680 .finish()
681 }
682}
683
684impl<'a> IntoIterator for &'a SubpacketArea {
685 type Item = &'a Subpacket;
686 type IntoIter = std::slice::Iter<'a, Subpacket>;
687
688 fn into_iter(self) -> Self::IntoIter {
689 self.packets.iter()
690 }
691}
692
693impl SubpacketArea {
694 /// The maximum size of a subpacket area.
695 pub const MAX_SIZE: usize = (1 << 16) - 1;
696
697 /// Returns a new subpacket area containing the given `packets`.
698 pub fn new(packets: Vec<Subpacket>) -> Result<SubpacketArea> {
699 let area = SubpacketArea {
700 packets,
701 parsed: std::sync::OnceLock::new(),
702 };
703 Ok(area)
704 }
705
706 /// Initialize the cache mapping subpacket tags to positions in
707 /// the subpacket area.
708 ///
709 /// If the cache is already initialized, this is a NOP.
710 ///
711 /// Returns the locked cache.
712 fn cache_init(&self) -> &Vec<u16>
713 {
714 self.parsed.get_or_init(|| {
715 // The largest defined subpacket in the crypto refresh is
716 // 39.
717 if let Some(max)
718 = self.packets.iter().map(|sp| u8::from(sp.tag())).max()
719 {
720 let max = max as usize;
721
722 let mut index = vec![ SUBPACKET_NOT_PRESENT; max + 1 ];
723 for (i, sp) in self.packets.iter().enumerate() {
724 index[u8::from(sp.tag()) as usize] = i as u16;
725 }
726 index
727 } else {
728 Vec::new()
729 }
730 })
731 }
732
733 /// Invalidates the cache.
734 fn cache_invalidate(&mut self) {
735 self.parsed = std::sync::OnceLock::new();
736 }
737
738 /// Iterates over the subpackets.
739 ///
740 /// # Examples
741 ///
742 /// Print the number of different types of subpackets in a
743 /// Signature's hashed subpacket area:
744 ///
745 /// ```
746 /// # use sequoia_openpgp as openpgp;
747 /// # use openpgp::cert::prelude::*;
748 /// # use openpgp::packet::prelude::*;
749 /// # use openpgp::types::SignatureType;
750 /// #
751 /// # fn main() -> openpgp::Result<()> {
752 /// # let (cert, _) = CertBuilder::new().generate()?;
753 /// #
754 /// # let key : &Key<_, _> = cert.primary_key().key();
755 /// # let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
756 /// #
757 /// # let msg = b"Hello, world!";
758 /// # let mut sig = SignatureBuilder::new(SignatureType::Binary)
759 /// # .sign_message(&mut signer, msg)?;
760 /// #
761 /// # // Verify it.
762 /// # sig.verify_message(signer.public(), msg)?;
763 /// #
764 /// let mut tags: Vec<_> = sig.hashed_area().iter().map(|sb| {
765 /// sb.tag()
766 /// }).collect();
767 /// tags.sort();
768 /// tags.dedup();
769 ///
770 /// eprintln!("The hashed area contains {} types of subpackets",
771 /// tags.len());
772 /// # Ok(())
773 /// # }
774 /// ```
775 pub fn iter(&self) -> impl Iterator<Item = &Subpacket> + Send + Sync {
776 self.packets.iter()
777 }
778
779 pub(crate) fn iter_mut(&mut self)
780 -> impl Iterator<Item = &mut Subpacket> + Send + Sync
781 {
782 self.packets.iter_mut()
783 }
784
785 /// Returns a reference to the *last* instance of the specified
786 /// subpacket, if any.
787 ///
788 /// A given subpacket may occur multiple times. For some, like
789 /// the [`Notation Data`] subpacket, this is reasonable. For
790 /// others, like the [`Signature Creation Time`] subpacket, this
791 /// results in an ambiguity. [Section 5.2.3.9 of RFC 9580] says:
792 ///
793 /// > a signature may contain multiple copies of a preference or
794 /// > multiple expiration times. In most cases, an implementation
795 /// > SHOULD use the last subpacket in the signature, but MAY use
796 /// > any conflict resolution scheme that makes more sense.
797 ///
798 /// [`Notation Data`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
799 /// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
800 /// [Section 5.2.3.9 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.9
801 ///
802 /// This function implements the recommended strategy of returning
803 /// the last subpacket.
804 ///
805 /// # Examples
806 ///
807 /// All signatures must have a `Signature Creation Time` subpacket
808 /// in the hashed subpacket area:
809 ///
810 /// ```
811 /// use sequoia_openpgp as openpgp;
812 /// # use openpgp::cert::prelude::*;
813 /// # use openpgp::packet::prelude::*;
814 /// use openpgp::packet::signature::subpacket::SubpacketTag;
815 /// # use openpgp::types::SignatureType;
816 ///
817 /// # fn main() -> openpgp::Result<()> {
818 /// # let (cert, _) = CertBuilder::new().generate()?;
819 /// #
820 /// # let key : &Key<_, _> = cert.primary_key().key();
821 /// # let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
822 /// #
823 /// # let msg = b"Hello, world!";
824 /// # let mut sig = SignatureBuilder::new(SignatureType::Binary)
825 /// # .sign_message(&mut signer, msg)?;
826 /// #
827 /// # // Verify it.
828 /// # sig.verify_message(signer.public(), msg)?;
829 /// #
830 /// if sig.hashed_area().subpacket(SubpacketTag::SignatureCreationTime).is_none() {
831 /// eprintln!("Invalid signature.");
832 /// }
833 /// # Ok(())
834 /// # }
835 /// ```
836 pub fn subpacket(&self, tag: SubpacketTag) -> Option<&Subpacket> {
837 match self.cache_init().get(u8::from(tag) as usize) {
838 Some(&SUBPACKET_NOT_PRESENT) => None,
839 Some(&n) => Some(&self.packets[n as usize]),
840 _ => None,
841 }
842 }
843
844 /// Returns a mutable reference to the *last* instance of the
845 /// specified subpacket, if any.
846 ///
847 /// A given subpacket may occur multiple times. For some, like
848 /// the [`Notation Data`] subpacket, this is reasonable. For
849 /// others, like the [`Signature Creation Time`] subpacket, this
850 /// results in an ambiguity. [Section 5.2.3.9 of RFC 9580] says:
851 ///
852 /// > a signature may contain multiple copies of a preference or
853 /// > multiple expiration times. In most cases, an implementation
854 /// > SHOULD use the last subpacket in the signature, but MAY use
855 /// > any conflict resolution scheme that makes more sense.
856 ///
857 /// [`Notation Data`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
858 /// [`Signature Creation Time`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
859 /// [Section 5.2.3.9 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.9
860 ///
861 /// This function implements the recommended strategy of returning
862 /// the last subpacket.
863 ///
864 /// # Examples
865 ///
866 /// All signatures must have a `Signature Creation Time` subpacket
867 /// in the hashed subpacket area:
868 ///
869 /// ```
870 /// use sequoia_openpgp as openpgp;
871 /// # use openpgp::cert::prelude::*;
872 /// # use openpgp::packet::prelude::*;
873 /// use openpgp::packet::signature::subpacket::SubpacketTag;
874 /// # use openpgp::types::SignatureType;
875 ///
876 /// # fn main() -> openpgp::Result<()> {
877 /// # let (cert, _) = CertBuilder::new().generate()?;
878 /// #
879 /// # let key : &Key<_, _> = cert.primary_key().key();
880 /// # let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
881 /// #
882 /// # let msg = b"Hello, world!";
883 /// # let mut sig = SignatureBuilder::new(SignatureType::Binary)
884 /// # .sign_message(&mut signer, msg)?;
885 /// #
886 /// # // Verify it.
887 /// # sig.verify_message(signer.public(), msg)?;
888 /// #
889 /// if sig.hashed_area().subpacket(SubpacketTag::SignatureCreationTime).is_none() {
890 /// eprintln!("Invalid signature.");
891 /// }
892 /// # Ok(())
893 /// # }
894 /// ```
895 pub fn subpacket_mut(&mut self, tag: SubpacketTag)
896 -> Option<&mut Subpacket> {
897 match self.cache_init().get(u8::from(tag) as usize) {
898 Some(&SUBPACKET_NOT_PRESENT) => None,
899 Some(&n) => Some(&mut self.packets[n as usize]),
900 _ => None,
901 }
902 }
903
904 /// Returns all instances of the specified subpacket.
905 ///
906 /// For most subpackets, only a single instance of the subpacket
907 /// makes sense. [`SubpacketArea::subpacket`] resolves this
908 /// ambiguity by returning the last instance of the request
909 /// subpacket type. But, for some subpackets, like the [`Notation
910 /// Data`] subpacket, multiple instances of the subpacket are
911 /// reasonable.
912 ///
913 /// [`SubpacketArea::subpacket`]: Self::subpacket()
914 /// [`Notation Data`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
915 ///
916 /// # Examples
917 ///
918 /// Count the number of `Notation Data` subpackets in the hashed
919 /// subpacket area:
920 ///
921 /// ```
922 /// use sequoia_openpgp as openpgp;
923 /// # use openpgp::cert::prelude::*;
924 /// # use openpgp::packet::prelude::*;
925 /// use openpgp::packet::signature::subpacket::SubpacketTag;
926 /// # use openpgp::types::SignatureType;
927 ///
928 /// # fn main() -> openpgp::Result<()> {
929 /// # let (cert, _) = CertBuilder::new().generate()?;
930 /// #
931 /// # let key : &Key<_, _> = cert.primary_key().key();
932 /// # let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
933 /// #
934 /// # let msg = b"Hello, world!";
935 /// # let mut sig = SignatureBuilder::new(SignatureType::Binary)
936 /// # .sign_message(&mut signer, msg)?;
937 /// #
938 /// # // Verify it.
939 /// # sig.verify_message(signer.public(), msg)?;
940 /// #
941 /// eprintln!("Signature has {} notations.",
942 /// sig.hashed_area().subpackets(SubpacketTag::NotationData).count());
943 /// # Ok(())
944 /// # }
945 /// ```
946 pub fn subpackets(&self, target: SubpacketTag)
947 -> impl Iterator<Item = &Subpacket> + Send + Sync
948 {
949 self.iter().filter(move |sp| sp.tag() == target)
950 }
951
952 pub(crate) fn subpackets_mut(&mut self, target: SubpacketTag)
953 -> impl Iterator<Item = &mut Subpacket> + Send + Sync
954 {
955 self.iter_mut().filter(move |sp| sp.tag() == target)
956 }
957
958 /// Adds the given subpacket.
959 ///
960 /// Adds the given subpacket to the subpacket area. If the
961 /// subpacket area already contains subpackets with the same tag,
962 /// they are left in place. If you want to replace them, you
963 /// should instead use the [`SubpacketArea::replace`] method.
964 ///
965 /// [`SubpacketArea::replace`]: Self::replace()
966 ///
967 /// # Errors
968 ///
969 /// Returns `Error::MalformedPacket` if adding the packet makes
970 /// the subpacket area exceed the size limit.
971 ///
972 /// # Examples
973 ///
974 /// Adds an additional `Issuer` subpacket to the unhashed
975 /// subpacket area. (This is useful if the key material is
976 /// associated with multiple certificates, e.g., a v4 and a v5
977 /// certificate.) Because the subpacket is added to the unhashed
978 /// area, the signature remains valid.
979 ///
980 /// ```
981 /// use sequoia_openpgp as openpgp;
982 /// # use openpgp::cert::prelude::*;
983 /// use openpgp::KeyID;
984 /// # use openpgp::packet::prelude::*;
985 /// use openpgp::packet::signature::subpacket::{
986 /// Subpacket,
987 /// SubpacketTag,
988 /// SubpacketValue,
989 /// };
990 /// # use openpgp::types::SignatureType;
991 ///
992 /// # fn main() -> openpgp::Result<()> {
993 /// # let (cert, _) = CertBuilder::new().generate()?;
994 /// #
995 /// # let key : &Key<_, _> = cert.primary_key().key();
996 /// # let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
997 /// #
998 /// # let msg = b"Hello, world!";
999 /// # let mut sig = SignatureBuilder::new(SignatureType::Binary)
1000 /// # .sign_message(&mut signer, msg)?;
1001 /// #
1002 /// # // Verify it.
1003 /// # sig.verify_message(signer.public(), msg)?;
1004 /// #
1005 /// # assert_eq!(sig
1006 /// # .hashed_area()
1007 /// # .iter()
1008 /// # .filter(|sp| sp.tag() == SubpacketTag::Issuer)
1009 /// # .count(),
1010 /// # 1);
1011 /// let mut sig: Signature = sig;
1012 /// sig.unhashed_area_mut().add(
1013 /// Subpacket::new(
1014 /// SubpacketValue::Issuer(KeyID::from_hex("AAAA BBBB CCCC DDDD")?),
1015 /// false)?);
1016 ///
1017 /// sig.verify_message(signer.public(), msg)?;
1018 /// # assert_eq!(sig
1019 /// # .unhashed_area()
1020 /// # .iter()
1021 /// # .filter(|sp| sp.tag() == SubpacketTag::Issuer)
1022 /// # .count(),
1023 /// # 1);
1024 /// # Ok(())
1025 /// # }
1026 /// ```
1027 pub fn add(&mut self, packet: Subpacket) -> Result<()> {
1028 self.add_internal(packet, false)
1029 }
1030
1031 /// Adds `packet`, setting its authenticated flag to `authenticated`.
1032 pub(super) fn add_internal(&mut self, packet: Subpacket,
1033 authenticated: bool)
1034 -> Result<()>
1035 {
1036 if self.serialized_len() + packet.serialized_len()
1037 > ::std::u16::MAX as usize
1038 {
1039 return Err(Error::MalformedPacket(
1040 "Subpacket area exceeds maximum size".into()).into());
1041 }
1042
1043 self.cache_invalidate();
1044 packet.set_authenticated(authenticated);
1045 self.packets.push(packet);
1046 Ok(())
1047 }
1048
1049 /// Adds the given subpacket, replacing all other subpackets with
1050 /// the same tag.
1051 ///
1052 /// Adds the given subpacket to the subpacket area. If the
1053 /// subpacket area already contains subpackets with the same tag,
1054 /// they are first removed. If you want to preserve them, you
1055 /// should instead use the [`SubpacketArea::add`] method.
1056 ///
1057 /// [`SubpacketArea::add`]: Self::add()
1058 ///
1059 /// # Errors
1060 ///
1061 /// Returns `Error::MalformedPacket` if adding the packet makes
1062 /// the subpacket area exceed the size limit.
1063 ///
1064 /// # Examples
1065 ///
1066 /// Assuming we have a signature with an additional `Issuer`
1067 /// subpacket in the unhashed area (see the example for
1068 /// [`SubpacketArea::add`]), this replaces the `Issuer` subpacket
1069 /// in the unhashed area. Because the unhashed area is not
1070 /// protected by the signature, the signature remains valid:
1071 ///
1072 /// ```
1073 /// use sequoia_openpgp as openpgp;
1074 /// # use openpgp::cert::prelude::*;
1075 /// use openpgp::KeyID;
1076 /// # use openpgp::packet::prelude::*;
1077 /// use openpgp::packet::signature::subpacket::{
1078 /// Subpacket,
1079 /// SubpacketTag,
1080 /// SubpacketValue,
1081 /// };
1082 /// # use openpgp::types::SignatureType;
1083 ///
1084 /// # fn main() -> openpgp::Result<()> {
1085 /// # let (cert, _) = CertBuilder::new().generate()?;
1086 /// #
1087 /// # let key : &Key<_, _> = cert.primary_key().key();
1088 /// # let mut signer = key.clone().parts_into_secret()?.into_keypair()?;
1089 /// #
1090 /// # let msg = b"Hello, world!";
1091 /// # let mut sig = SignatureBuilder::new(SignatureType::Binary)
1092 /// # .sign_message(&mut signer, msg)?;
1093 /// #
1094 /// # // Verify it.
1095 /// # sig.verify_message(signer.public(), msg)?;
1096 /// #
1097 /// # assert_eq!(sig
1098 /// # .hashed_area()
1099 /// # .iter()
1100 /// # .filter(|sp| sp.tag() == SubpacketTag::Issuer)
1101 /// # .count(),
1102 /// # 1);
1103 /// // First, add a subpacket to the unhashed area.
1104 /// let mut sig: Signature = sig;
1105 /// sig.unhashed_area_mut().add(
1106 /// Subpacket::new(
1107 /// SubpacketValue::Issuer(KeyID::from_hex("DDDD CCCC BBBB AAAA")?),
1108 /// false)?);
1109 ///
1110 /// // Now, replace it.
1111 /// sig.unhashed_area_mut().replace(
1112 /// Subpacket::new(
1113 /// SubpacketValue::Issuer(KeyID::from_hex("AAAA BBBB CCCC DDDD")?),
1114 /// false)?);
1115 ///
1116 /// sig.verify_message(signer.public(), msg)?;
1117 /// # assert_eq!(sig
1118 /// # .unhashed_area()
1119 /// # .iter()
1120 /// # .filter(|sp| sp.tag() == SubpacketTag::Issuer)
1121 /// # .count(),
1122 /// # 1);
1123 /// # Ok(())
1124 /// # }
1125 /// ```
1126 pub fn replace(&mut self, packet: Subpacket) -> Result<()> {
1127 if self.iter().filter_map(|sp| if sp.tag() != packet.tag() {
1128 Some(sp.serialized_len())
1129 } else {
1130 None
1131 }).sum::<usize>() + packet.serialized_len() > std::u16::MAX as usize {
1132 return Err(Error::MalformedPacket(
1133 "Subpacket area exceeds maximum size".into()).into());
1134 }
1135 self.remove_all(packet.tag());
1136 packet.set_authenticated(false);
1137 self.packets.push(packet);
1138 Ok(())
1139 }
1140
1141 /// Removes all subpackets with the given tag.
1142 pub fn remove_all(&mut self, tag: SubpacketTag) {
1143 self.cache_invalidate();
1144 self.packets.retain(|sp| sp.tag() != tag);
1145 }
1146
1147 /// Removes all subpackets.
1148 pub fn clear(&mut self) {
1149 self.cache_invalidate();
1150 self.packets.clear();
1151 }
1152
1153 /// Sorts the subpackets by subpacket tag.
1154 ///
1155 /// This normalizes the subpacket area, and accelerates lookups in
1156 /// implementations that sort the in-core representation and use
1157 /// binary search for lookups.
1158 ///
1159 /// The subpackets are sorted by the numeric value of their tag.
1160 /// The sort is stable. So, if there are multiple [`Notation Data`]
1161 /// subpackets, for instance, they will remain in the same order.
1162 ///
1163 /// The [`SignatureBuilder`] sorts the subpacket areas just before
1164 /// creating the signature.
1165 ///
1166 /// [`Notation Data`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
1167 /// [`SignatureBuilder`]: super::SignatureBuilder
1168 pub fn sort(&mut self) {
1169 self.cache_invalidate();
1170 // slice::sort_by is stable.
1171 self.packets.sort_by(|a, b| u8::from(a.tag()).cmp(&b.tag().into()));
1172 }
1173}
1174
1175/// Payload of a Notation Data subpacket.
1176///
1177/// The [`Notation Data`] subpacket provides a mechanism for a
1178/// message's signer to insert nearly arbitrary data into the
1179/// signature. Because notations can be marked as critical, it is
1180/// possible to add security relevant notations, which the receiving
1181/// OpenPGP implementation will respect (in the sense that an
1182/// implementation will reject signatures that include unknown,
1183/// critical notations), even if they don't understand the notations
1184/// themselves.
1185///
1186/// [`Notation Data`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
1187///
1188/// It is possible to control how Sequoia's higher-level functionality
1189/// handles unknown, critical notations using a [`Policy`] object.
1190/// Depending on the degree of control required, it may be sufficient
1191/// to customize a [`StandardPolicy`] object using, for instance, the
1192/// [`StandardPolicy::good_critical_notations`] method.
1193///
1194/// [`Policy`]: crate::policy::Policy
1195/// [`StandardPolicy`]: crate::policy::StandardPolicy
1196/// [`StandardPolicy::good_critical_notations`]: crate::policy::StandardPolicy::good_critical_notations()
1197///
1198/// Notation names are human-readable UTF-8 strings. There are two
1199/// namespaces: The user namespace and the IETF namespace. Names in
1200/// the user namespace have the form `name@example.org` and are
1201/// managed by the owner of the domain. Names in the IETF namespace
1202/// may not contain an `@` and are managed by IANA. See [Section
1203/// 5.2.3.24 of RFC 9580] for details.
1204///
1205/// [Section 5.2.3.24 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
1206#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1207pub struct NotationData {
1208 flags: NotationDataFlags,
1209 name: String,
1210 value: Vec<u8>,
1211}
1212assert_send_and_sync!(NotationData);
1213
1214impl fmt::Display for NotationData {
1215 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1216 write!(f, "{}", self.name)?;
1217
1218 let flags = format!("{:?}", self.flags);
1219 if ! flags.is_empty() {
1220 write!(f, " ({})", flags)?;
1221 }
1222
1223 if self.flags.human_readable() {
1224 write!(f, ": {}", String::from_utf8_lossy(&self.value))?;
1225 } else {
1226 let hex = crate::fmt::hex::encode(&self.value);
1227 write!(f, ": {}", hex)?;
1228 }
1229
1230 Ok(())
1231 }
1232}
1233
1234impl fmt::Debug for NotationData {
1235 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1236 let mut dbg = f.debug_struct("NotationData");
1237 dbg.field("name", &self.name);
1238
1239 let flags = format!("{:?}", self.flags);
1240 if ! flags.is_empty() {
1241 dbg.field("flags", &flags);
1242 }
1243
1244 if self.flags.human_readable() {
1245 match std::str::from_utf8(&self.value) {
1246 Ok(s) => {
1247 dbg.field("value", &s);
1248 },
1249 Err(e) => {
1250 let s = format!("({}): {}", e,
1251 crate::fmt::hex::encode(&self.value));
1252 dbg.field("value", &s);
1253 },
1254 }
1255 } else {
1256 let hex = crate::fmt::hex::encode(&self.value);
1257 dbg.field("value", &hex);
1258 }
1259
1260 dbg.finish()
1261 }
1262}
1263
1264#[cfg(test)]
1265impl Arbitrary for NotationData {
1266 fn arbitrary(g: &mut Gen) -> Self {
1267 NotationData {
1268 flags: Arbitrary::arbitrary(g),
1269 name: Arbitrary::arbitrary(g),
1270 value: Arbitrary::arbitrary(g),
1271 }
1272 }
1273}
1274
1275impl NotationData {
1276 /// Creates a new Notation Data subpacket payload.
1277 pub fn new<N, V, F>(name: N, value: V, flags: F) -> Self
1278 where N: AsRef<str>,
1279 V: AsRef<[u8]>,
1280 F: Into<Option<NotationDataFlags>>,
1281 {
1282 Self {
1283 flags: flags.into().unwrap_or_else(NotationDataFlags::empty),
1284 name: name.as_ref().into(),
1285 value: value.as_ref().into(),
1286 }
1287 }
1288
1289 /// Returns the flags.
1290 pub fn flags(&self) -> &NotationDataFlags {
1291 &self.flags
1292 }
1293
1294 /// Returns the name.
1295 pub fn name(&self) -> &str {
1296 &self.name
1297 }
1298
1299 /// Returns the value.
1300 pub fn value(&self) -> &[u8] {
1301 &self.value
1302 }
1303}
1304
1305/// Flags for the Notation Data subpacket.
1306#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1307pub struct NotationDataFlags(crate::types::Bitfield);
1308assert_send_and_sync!(NotationDataFlags);
1309
1310#[cfg(test)]
1311impl Arbitrary for NotationDataFlags {
1312 fn arbitrary(g: &mut Gen) -> Self {
1313 NotationDataFlags(vec![u8::arbitrary(g), u8::arbitrary(g),
1314 u8::arbitrary(g), u8::arbitrary(g)].into())
1315 }
1316}
1317
1318impl fmt::Debug for NotationDataFlags {
1319 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1320 let mut need_comma = false;
1321 if self.human_readable() {
1322 f.write_str("human readable")?;
1323 need_comma = true;
1324 }
1325
1326 for i in self.0.iter_set() {
1327 match i {
1328 NOTATION_DATA_FLAG_HUMAN_READABLE => (),
1329 i => {
1330 if need_comma { f.write_str(", ")?; }
1331 write!(f, "#{}", i)?;
1332 need_comma = true;
1333 },
1334 }
1335 }
1336
1337 // Don't mention padding, the bit field always has the same
1338 // size.
1339
1340 Ok(())
1341 }
1342}
1343
1344const NOTATION_DATA_FLAG_HUMAN_READABLE: usize = 7;
1345
1346impl NotationDataFlags {
1347 /// Creates a new instance from `bits`.
1348 pub fn new<B: AsRef<[u8]>>(bits: B) -> Result<Self> {
1349 if bits.as_ref().len() == 4 {
1350 Ok(Self(bits.as_ref().to_vec().into()))
1351 } else {
1352 Err(Error::InvalidArgument(
1353 format!("Need four bytes of flags, got: {:?}", bits.as_ref()))
1354 .into())
1355 }
1356 }
1357
1358 /// Returns an empty key server preference set.
1359 pub fn empty() -> Self {
1360 Self::new(&[0, 0, 0, 0]).unwrap()
1361 }
1362
1363 /// Returns a reference to the underlying
1364 /// [`Bitfield`](crate::types::Bitfield).
1365 pub fn as_bitfield(&self) -> &crate::types::Bitfield {
1366 &self.0
1367 }
1368
1369 /// Returns whether the specified notation data flag is set.
1370 ///
1371 /// # Examples
1372 ///
1373 /// ```
1374 /// use sequoia_openpgp as openpgp;
1375 /// use openpgp::packet::signature::subpacket::NotationDataFlags;
1376 ///
1377 /// # fn main() -> openpgp::Result<()> {
1378 /// // Notation Data flags 0 and 2.
1379 /// let ndf = NotationDataFlags::new(&[5, 0, 0, 0])?;
1380 ///
1381 /// assert!(ndf.get(0));
1382 /// assert!(! ndf.get(1));
1383 /// assert!(ndf.get(2));
1384 /// assert!(! ndf.get(3));
1385 /// assert!(! ndf.get(8));
1386 /// assert!(! ndf.get(80));
1387 /// # assert!(! ndf.human_readable());
1388 /// # Ok(()) }
1389 /// ```
1390 pub fn get(&self, bit: usize) -> bool {
1391 self.0.get(bit)
1392 }
1393
1394 /// Sets the specified notation data flag.
1395 ///
1396 /// # Examples
1397 ///
1398 /// ```
1399 /// use sequoia_openpgp as openpgp;
1400 /// use openpgp::packet::signature::subpacket::NotationDataFlags;
1401 ///
1402 /// # fn main() -> openpgp::Result<()> {
1403 /// let ndf = NotationDataFlags::empty().set(0)?.set(2)?;
1404 ///
1405 /// assert!(ndf.get(0));
1406 /// assert!(! ndf.get(1));
1407 /// assert!(ndf.get(2));
1408 /// assert!(! ndf.get(3));
1409 /// # assert!(! ndf.human_readable());
1410 /// # Ok(()) }
1411 /// ```
1412 pub fn set(mut self, bit: usize) -> Result<Self> {
1413 assert_eq!(self.0.as_bytes().len(), 4);
1414 let byte = bit / 8;
1415 if byte < 4 {
1416 self.0.set(bit);
1417 Ok(self)
1418 } else {
1419 Err(Error::InvalidArgument(
1420 format!("flag index out of bounds: {}", bit)).into())
1421 }
1422 }
1423
1424 /// Clears the specified notation data flag.
1425 ///
1426 /// # Examples
1427 ///
1428 /// ```
1429 /// use sequoia_openpgp as openpgp;
1430 /// use openpgp::packet::signature::subpacket::NotationDataFlags;
1431 ///
1432 /// # fn main() -> openpgp::Result<()> {
1433 /// let ndf = NotationDataFlags::empty().set(0)?.set(2)?.clear(2)?;
1434 ///
1435 /// assert!(ndf.get(0));
1436 /// assert!(! ndf.get(1));
1437 /// assert!(! ndf.get(2));
1438 /// assert!(! ndf.get(3));
1439 /// # assert!(! ndf.human_readable());
1440 /// # Ok(()) }
1441 /// ```
1442 pub fn clear(mut self, bit: usize) -> Result<Self> {
1443 assert_eq!(self.0.as_bytes().len(), 4);
1444 let byte = bit / 8;
1445 if byte < 4 {
1446 self.0.clear(bit);
1447 Ok(self)
1448 } else {
1449 Err(Error::InvalidArgument(
1450 format!("flag index out of bounds: {}", bit)).into())
1451 }
1452 }
1453
1454 /// Returns whether the value is human-readable.
1455 pub fn human_readable(&self) -> bool {
1456 self.get(NOTATION_DATA_FLAG_HUMAN_READABLE)
1457 }
1458
1459 /// Asserts that the value is human-readable.
1460 pub fn set_human_readable(self) -> Self {
1461 self.set(NOTATION_DATA_FLAG_HUMAN_READABLE).unwrap()
1462 }
1463
1464 /// Clear the assertion that the value is human-readable.
1465 pub fn clear_human_readable(self) -> Self {
1466 self.clear(NOTATION_DATA_FLAG_HUMAN_READABLE).unwrap()
1467 }
1468}
1469
1470/// Holds an arbitrary, well-structured subpacket.
1471///
1472/// The `SubpacketValue` enum holds a [`Subpacket`]'s value. The
1473/// values are well-structured in the sense that they have been parsed
1474/// into Sequoia's native data types rather than just holding the raw
1475/// byte vector. For instance, the [`Issuer`] variant holds a
1476/// [`KeyID`].
1477///
1478/// [`Issuer`]: SubpacketValue::Issuer
1479/// [`KeyID`]: super::super::super::KeyID
1480#[non_exhaustive]
1481#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
1482pub enum SubpacketValue {
1483 /// An unknown subpacket.
1484 Unknown {
1485 /// The unknown subpacket's tag.
1486 tag: SubpacketTag,
1487 /// The unknown subpacket's uninterpreted body.
1488 body: Vec<u8>
1489 },
1490
1491 /// The time the signature was made.
1492 ///
1493 /// See [Section 5.2.3.11 of RFC 9580] for details.
1494 ///
1495 /// [Section 5.2.3.11 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
1496 SignatureCreationTime(Timestamp),
1497 /// The validity period of the signature.
1498 ///
1499 /// The validity is relative to the time stored in the signature's
1500 /// Signature Creation Time subpacket.
1501 ///
1502 /// See [Section 5.2.3.18 of RFC 9580] for details.
1503 ///
1504 /// [Section 5.2.3.18 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.18
1505 SignatureExpirationTime(Duration),
1506 /// Whether a signature should be published.
1507 ///
1508 /// See [Section 5.2.3.19 of RFC 9580] for details.
1509 ///
1510 /// [Section 5.2.3.19 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.19
1511 ExportableCertification(bool),
1512 /// Signer asserts that the key is not only valid but also trustworthy at
1513 /// the specified level.
1514 ///
1515 /// See [Section 5.2.3.21 of RFC 9580] for details.
1516 ///
1517 /// [Section 5.2.3.21 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.21
1518 TrustSignature {
1519 /// Trust level, or depth.
1520 ///
1521 /// Level 0 has the same meaning as an ordinary validity
1522 /// signature. Level 1 means that the signed key is asserted
1523 /// to be a valid trusted introducer, with the 2nd octet of
1524 /// the body specifying the degree of trust. Level 2 means
1525 /// that the signed key is asserted to be trusted to issue
1526 /// level 1 trust signatures, i.e., that it is a "meta
1527 /// introducer".
1528 level: u8,
1529
1530 /// Trust amount.
1531 ///
1532 /// This is interpreted such that values less than 120
1533 /// indicate partial trust and values of 120 or greater
1534 /// indicate complete trust. Implementations SHOULD emit
1535 /// values of 60 for partial trust and 120 for complete trust.
1536 trust: u8,
1537 },
1538 /// Used in conjunction with Trust Signature packets (of level > 0) to
1539 /// limit the scope of trust that is extended.
1540 ///
1541 /// See [Section 5.2.3.22 of RFC 9580] for details.
1542 ///
1543 /// [Section 5.2.3.22 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.22
1544 ///
1545 /// Note: The RFC requires that the serialized form includes a
1546 /// trailing NUL byte. When Sequoia parses the regular expression
1547 /// subpacket, it strips the trailing NUL. (If it doesn't include
1548 /// a NUL, then parsing fails.) Likewise, when it serializes a
1549 /// regular expression subpacket, it unconditionally adds a NUL.
1550 RegularExpression(Vec<u8>),
1551 /// Whether a signature can later be revoked.
1552 ///
1553 /// See [Section 5.2.3.20 of RFC 9580] for details.
1554 ///
1555 /// [Section 5.2.3.20 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.20
1556 Revocable(bool),
1557 /// The validity period of the key.
1558 ///
1559 /// The validity period is relative to the key's (not the signature's) creation time.
1560 ///
1561 /// See [Section 5.2.3.13 of RFC 9580] for details.
1562 ///
1563 /// [Section 5.2.3.13 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
1564 KeyExpirationTime(Duration),
1565 /// The Symmetric algorithms that the certificate holder prefers.
1566 ///
1567 /// See [Section 5.2.3.14 of RFC 9580] for details.
1568 ///
1569 /// [Section 5.2.3.14 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.14
1570 PreferredSymmetricAlgorithms(Vec<SymmetricAlgorithm>),
1571 /// Authorizes the specified key to issue revocation signatures for this
1572 /// certificate.
1573 ///
1574 /// See [Section 5.2.3.23 of RFC 9580] for details.
1575 ///
1576 /// [Section 5.2.3.23 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.23
1577 RevocationKey(RevocationKey),
1578 /// The OpenPGP Key ID of the key issuing the signature.
1579 ///
1580 /// See [Section 5.2.3.12 of RFC 9580] for details.
1581 ///
1582 /// [Section 5.2.3.12 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
1583 Issuer(KeyID),
1584 /// A "notation" on the signature.
1585 ///
1586 /// See [Section 5.2.3.24 of RFC 9580] for details.
1587 ///
1588 /// [Section 5.2.3.24 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
1589 NotationData(NotationData),
1590 /// The Hash algorithms that the certificate holder prefers.
1591 ///
1592 /// See [Section 5.2.3.16 of RFC 9580] for details.
1593 ///
1594 /// [Section 5.2.3.16 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.16
1595 PreferredHashAlgorithms(Vec<HashAlgorithm>),
1596 /// The compression algorithms that the certificate holder prefers.
1597 ///
1598 /// See [Section 5.2.3.17 of RFC 9580] for details.
1599 ///
1600 /// [Section 5.2.3.17 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.17
1601 PreferredCompressionAlgorithms(Vec<CompressionAlgorithm>),
1602 /// A list of flags that indicate preferences that the certificate
1603 /// holder has about how the key is handled by a key server.
1604 ///
1605 /// See [Section 5.2.3.25 of RFC 9580] for details.
1606 ///
1607 /// [Section 5.2.3.25 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.25
1608 KeyServerPreferences(KeyServerPreferences),
1609 /// The URI of a key server where the certificate holder keeps
1610 /// their certificate up to date.
1611 ///
1612 /// See [Section 5.2.3.26 of RFC 9580] for details.
1613 ///
1614 /// [Section 5.2.3.26 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.26
1615 PreferredKeyServer(Vec<u8>),
1616 /// A flag in a User ID's self-signature that states whether this
1617 /// User ID is the primary User ID for this certificate.
1618 ///
1619 /// See [Section 5.2.3.27 of RFC 9580] for details.
1620 ///
1621 /// [Section 5.2.3.27 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.27
1622 PrimaryUserID(bool),
1623 /// The URI of a document that describes the policy under which
1624 /// the signature was issued.
1625 ///
1626 /// See [Section 5.2.3.28 of RFC 9580] for details.
1627 ///
1628 /// [Section 5.2.3.28 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.28
1629 PolicyURI(Vec<u8>),
1630 /// A list of flags that hold information about a key.
1631 ///
1632 /// See [Section 5.2.3.29 of RFC 9580] for details.
1633 ///
1634 /// [Section 5.2.3.29 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.29
1635 KeyFlags(KeyFlags),
1636 /// The User ID that is responsible for the signature.
1637 ///
1638 /// See [Section 5.2.3.30 of RFC 9580] for details.
1639 ///
1640 /// [Section 5.2.3.30 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.30
1641 SignersUserID(Vec<u8>),
1642 /// The reason for a revocation, used in key revocations and
1643 /// certification revocation signatures.
1644 ///
1645 /// See [Section 5.2.3.31 of RFC 9580] for details.
1646 ///
1647 /// [Section 5.2.3.31 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.31
1648 ReasonForRevocation {
1649 /// Machine-readable reason for revocation.
1650 code: ReasonForRevocation,
1651
1652 /// Human-readable reason for revocation.
1653 reason: Vec<u8>,
1654 },
1655 /// The OpenPGP features a user's implementation supports.
1656 ///
1657 /// See [Section 5.2.3.32 of RFC 9580] for details.
1658 ///
1659 /// [Section 5.2.3.32 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.32
1660 Features(Features),
1661 /// A signature to which this signature refers.
1662 ///
1663 /// See [Section 5.2.3.33 of RFC 9580] for details.
1664 ///
1665 /// [Section 5.2.3.33 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.33
1666 SignatureTarget {
1667 /// Public-key algorithm of the target signature.
1668 pk_algo: PublicKeyAlgorithm,
1669 /// Hash algorithm of the target signature.
1670 hash_algo: HashAlgorithm,
1671 /// Hash digest of the target signature.
1672 digest: Vec<u8>,
1673 },
1674 /// A complete Signature packet body.
1675 ///
1676 /// This is used to store a backsig in a subkey binding signature.
1677 ///
1678 /// See [Section 5.2.3.34 of RFC 9580] for details.
1679 ///
1680 /// [Section 5.2.3.34 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.34
1681 EmbeddedSignature(Signature),
1682
1683 /// The Fingerprint of the key that issued the signature.
1684 ///
1685 /// See [Section 5.2.3.35 of RFC 9580]
1686 /// for details.
1687 ///
1688 /// [Section 5.2.3.35 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
1689 IssuerFingerprint(Fingerprint),
1690
1691 /// Who the signed message was intended for.
1692 ///
1693 /// See [Section 5.2.3.36 of RFC 9580] for details.
1694 ///
1695 /// [Section 5.2.3.36 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#name-intended-recipient-fingerpr
1696 IntendedRecipient(Fingerprint),
1697
1698 /// The Approved Certifications subpacket (experimental).
1699 ///
1700 /// Allows the certificate holder to attest to third party
1701 /// certifications, allowing them to be distributed with the
1702 /// certificate. This can be used to address certificate flooding
1703 /// concerns.
1704 ///
1705 /// See [Section 2.2 of draft-dkg-openpgp-1pa3pc-02] for details.
1706 ///
1707 /// [Section 2.2 of draft-dkg-openpgp-1pa3pc-02]: https://www.ietf.org/archive/id/draft-dkg-openpgp-1pa3pc-02.html#approved-certifications-subpacket
1708 ApprovedCertifications(Vec<Box<[u8]>>),
1709
1710 /// The AEAD Ciphersuites that the certificate holder prefers.
1711 ///
1712 /// A series of paired algorithm identifiers indicating how the
1713 /// keyholder prefers to receive version 2 Symmetrically Encrypted
1714 /// Integrity Protected Data. Each pair of octets indicates a
1715 /// combination of a symmetric cipher and an AEAD mode that the
1716 /// key holder prefers to use.
1717 ///
1718 /// It is assumed that only the combinations of algorithms listed
1719 /// are supported by the recipient's software, with the exception
1720 /// of the mandatory-to-implement combination of AES-128 and OCB.
1721 /// If AES-128 and OCB are not found in the subpacket, it is
1722 /// implicitly listed at the end.
1723 ///
1724 /// See [Section 5.2.3.15 of RFC 9580] for details.
1725 ///
1726 /// [Section 5.2.3.15 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#name-preferred-aead-ciphersuites
1727 PreferredAEADCiphersuites(Vec<(SymmetricAlgorithm, AEADAlgorithm)>),
1728}
1729assert_send_and_sync!(SubpacketValue);
1730
1731#[cfg(test)]
1732impl ArbitraryBounded for SubpacketValue {
1733 fn arbitrary_bounded(g: &mut Gen, depth: usize) -> Self {
1734 use self::SubpacketValue::*;
1735 use crate::arbitrary_helper::gen_arbitrary_from_range;
1736
1737 #[allow(deprecated)]
1738 loop {
1739 #[allow(deprecated)]
1740 break match gen_arbitrary_from_range(0..27, g) {
1741 0 => SignatureCreationTime(Arbitrary::arbitrary(g)),
1742 1 => SignatureExpirationTime(Arbitrary::arbitrary(g)),
1743 2 => ExportableCertification(Arbitrary::arbitrary(g)),
1744 3 => TrustSignature {
1745 level: Arbitrary::arbitrary(g),
1746 trust: Arbitrary::arbitrary(g),
1747 },
1748 4 => RegularExpression(Arbitrary::arbitrary(g)),
1749 5 => Revocable(Arbitrary::arbitrary(g)),
1750 6 => KeyExpirationTime(Arbitrary::arbitrary(g)),
1751 7 => PreferredSymmetricAlgorithms(Arbitrary::arbitrary(g)),
1752 8 => RevocationKey(Arbitrary::arbitrary(g)),
1753 9 => Issuer(Arbitrary::arbitrary(g)),
1754 10 => NotationData(Arbitrary::arbitrary(g)),
1755 11 => PreferredHashAlgorithms(Arbitrary::arbitrary(g)),
1756 12 => PreferredCompressionAlgorithms(Arbitrary::arbitrary(g)),
1757 13 => KeyServerPreferences(Arbitrary::arbitrary(g)),
1758 14 => PreferredKeyServer(Arbitrary::arbitrary(g)),
1759 15 => PrimaryUserID(Arbitrary::arbitrary(g)),
1760 16 => PolicyURI(Arbitrary::arbitrary(g)),
1761 17 => KeyFlags(Arbitrary::arbitrary(g)),
1762 18 => SignersUserID(Arbitrary::arbitrary(g)),
1763 19 => ReasonForRevocation {
1764 code: Arbitrary::arbitrary(g),
1765 reason: Arbitrary::arbitrary(g),
1766 },
1767 20 => Features(Arbitrary::arbitrary(g)),
1768 21 => SignatureTarget {
1769 pk_algo: Arbitrary::arbitrary(g),
1770 hash_algo: Arbitrary::arbitrary(g),
1771 digest: Arbitrary::arbitrary(g),
1772 },
1773 22 if depth == 0 => continue, // Don't recurse, try again.
1774 22 => EmbeddedSignature(
1775 // Set depth to 0: don't create embedded
1776 // signatures in embedded signatures.
1777 ArbitraryBounded::arbitrary_bounded(g, 0)),
1778 23 => IssuerFingerprint(Arbitrary::arbitrary(g)),
1779 24 => Unknown {
1780 tag: SubpacketTag::PreferredAEADAlgorithms,
1781 body: Arbitrary::arbitrary(g),
1782 },
1783 25 => IntendedRecipient(Arbitrary::arbitrary(g)),
1784 26 => PreferredAEADCiphersuites(Arbitrary::arbitrary(g)),
1785 _ => unreachable!(),
1786 }
1787 }
1788 }
1789}
1790
1791#[cfg(test)]
1792impl_arbitrary_with_bound!(SubpacketValue);
1793
1794impl SubpacketValue {
1795 /// Returns the subpacket tag for this value.
1796 pub fn tag(&self) -> SubpacketTag {
1797 use self::SubpacketValue::*;
1798 #[allow(deprecated)]
1799 match &self {
1800 SignatureCreationTime(_) => SubpacketTag::SignatureCreationTime,
1801 SignatureExpirationTime(_) =>
1802 SubpacketTag::SignatureExpirationTime,
1803 ExportableCertification(_) =>
1804 SubpacketTag::ExportableCertification,
1805 TrustSignature { .. } => SubpacketTag::TrustSignature,
1806 RegularExpression(_) => SubpacketTag::RegularExpression,
1807 Revocable(_) => SubpacketTag::Revocable,
1808 KeyExpirationTime(_) => SubpacketTag::KeyExpirationTime,
1809 PreferredSymmetricAlgorithms(_) =>
1810 SubpacketTag::PreferredSymmetricAlgorithms,
1811 RevocationKey { .. } => SubpacketTag::RevocationKey,
1812 Issuer(_) => SubpacketTag::Issuer,
1813 NotationData(_) => SubpacketTag::NotationData,
1814 PreferredHashAlgorithms(_) =>
1815 SubpacketTag::PreferredHashAlgorithms,
1816 PreferredCompressionAlgorithms(_) =>
1817 SubpacketTag::PreferredCompressionAlgorithms,
1818 KeyServerPreferences(_) => SubpacketTag::KeyServerPreferences,
1819 PreferredKeyServer(_) => SubpacketTag::PreferredKeyServer,
1820 PrimaryUserID(_) => SubpacketTag::PrimaryUserID,
1821 PolicyURI(_) => SubpacketTag::PolicyURI,
1822 KeyFlags(_) => SubpacketTag::KeyFlags,
1823 SignersUserID(_) => SubpacketTag::SignersUserID,
1824 ReasonForRevocation { .. } => SubpacketTag::ReasonForRevocation,
1825 Features(_) => SubpacketTag::Features,
1826 SignatureTarget { .. } => SubpacketTag::SignatureTarget,
1827 EmbeddedSignature(_) => SubpacketTag::EmbeddedSignature,
1828 IssuerFingerprint(_) => SubpacketTag::IssuerFingerprint,
1829 IntendedRecipient(_) => SubpacketTag::IntendedRecipient,
1830 ApprovedCertifications(_) => SubpacketTag::ApprovedCertifications,
1831 PreferredAEADCiphersuites(_) =>
1832 SubpacketTag::PreferredAEADCiphersuites,
1833 Unknown { tag, .. } => *tag,
1834 }
1835 }
1836}
1837
1838/// Signature subpackets.
1839///
1840/// Most of a signature's attributes are not stored in fixed fields,
1841/// but in so-called subpackets. These subpackets are stored in a
1842/// [`Signature`]'s so-called subpacket areas, which are effectively
1843/// small key-value stores. The keys are subpacket tags
1844/// ([`SubpacketTag`]). The values are well-structured
1845/// ([`SubpacketValue`]).
1846///
1847/// [`Signature`]: super::super::Signature
1848///
1849/// In addition to their key and value, subpackets also include a
1850/// critical flag. When set, this flag indicates to the OpenPGP
1851/// implementation that if it doesn't understand the subpacket, it
1852/// must consider the signature to be invalid. (Likewise, if it isn't
1853/// set, then it means that it is safe for the implementation to
1854/// ignore the subpacket.) This enables forward compatibility with
1855/// security-relevant extensions.
1856///
1857/// It is possible to control how Sequoia's higher-level functionality
1858/// handles unknown, critical subpackets using a [`Policy`] object.
1859/// Depending on the degree of control required, it may be sufficient
1860/// to customize a [`StandardPolicy`] object using, for instance, the
1861/// [`StandardPolicy::accept_critical_subpacket`] method.
1862///
1863/// [`Policy`]: crate::policy::Policy
1864/// [`StandardPolicy`]: crate::policy::StandardPolicy
1865/// [`StandardPolicy::accept_critical_subpacket`]: crate::policy::StandardPolicy::accept_critical_subpacket()
1866///
1867/// The subpacket system is extensible in two ways. First, although
1868/// limited, the subpacket name space is not exhausted. So, it is
1869/// possible to introduce new packets. Second, one of the subpackets,
1870/// the [`Notation Data`] subpacket ([`NotationData`]), is explicitly
1871/// designed for adding arbitrary data to signatures.
1872///
1873/// [`Notation Data`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
1874///
1875/// Subpackets are described in [Section 5.2.3.7 of RFC 9580].
1876///
1877/// [Section 5.2.3.7 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.7
1878pub struct Subpacket {
1879 /// The length.
1880 ///
1881 /// In order not to break signatures, we need to be able to
1882 /// roundtrip the subpackets, perfectly reproducing all the bits.
1883 /// To allow for suboptimal encoding of lengths, we store the
1884 /// length when we parse subpackets.
1885 pub(crate) // For serialize/mod.rs, parse/parse.rs.
1886 length: SubpacketLength,
1887 /// Critical flag.
1888 critical: bool,
1889 /// Packet value, must match packet type.
1890 value: SubpacketValue,
1891 /// Whether the information in this subpacket are
1892 /// authenticated in the context of its signature.
1893 authenticated: atomic::AtomicBool,
1894}
1895assert_send_and_sync!(Subpacket);
1896
1897impl Clone for Subpacket {
1898 fn clone(&self) -> Self {
1899 Subpacket {
1900 length: self.length.clone(),
1901 critical: self.critical,
1902 value: self.value.clone(),
1903 authenticated: self.authenticated().into(),
1904 }
1905 }
1906}
1907
1908impl PartialEq for Subpacket {
1909 fn eq(&self, other: &Subpacket) -> bool {
1910 self.cmp(other) == Ordering::Equal
1911 }
1912}
1913
1914impl Eq for Subpacket {}
1915
1916impl PartialOrd for Subpacket {
1917 fn partial_cmp(&self, other: &Subpacket) -> Option<Ordering> {
1918 Some(self.cmp(other))
1919 }
1920}
1921
1922impl Ord for Subpacket {
1923 fn cmp(&self, other: &Subpacket) -> Ordering {
1924 self.length.cmp(&other.length)
1925 .then_with(|| self.critical.cmp(&other.critical))
1926 .then_with(|| self.value.cmp(&other.value))
1927 }
1928}
1929
1930impl Hash for Subpacket {
1931 fn hash<H: Hasher>(&self, state: &mut H) {
1932 self.length.hash(state);
1933 self.critical.hash(state);
1934 self.value.hash(state);
1935 }
1936}
1937
1938#[cfg(test)]
1939impl ArbitraryBounded for Subpacket {
1940 fn arbitrary_bounded(g: &mut Gen, depth: usize) -> Self {
1941 use crate::arbitrary_helper::gen_arbitrary_from_range;
1942
1943 fn encode_non_optimal(length: usize) -> SubpacketLength {
1944 // Calculate length the same way as Subpacket::new.
1945 let length = 1 /* Tag */ + length as u32;
1946
1947 let mut len_vec = Vec::<u8>::with_capacity(5);
1948 len_vec.push(0xFF);
1949 len_vec.extend_from_slice(&length.to_be_bytes());
1950 SubpacketLength::new(length, Some(len_vec))
1951 }
1952
1953 let critical = <bool>::arbitrary(g);
1954 let use_nonoptimal_encoding = <bool>::arbitrary(g);
1955 // We don't want to overrepresent large subpackets.
1956 let create_large_subpacket =
1957 gen_arbitrary_from_range(0..25, g) == 0;
1958
1959 let value = if create_large_subpacket {
1960 // Choose a size which makes sure the subpacket length must be
1961 // encoded with 2 or 5 octets.
1962 let value_size = gen_arbitrary_from_range(7000..9000, g);
1963 let nd = NotationData {
1964 flags: Arbitrary::arbitrary(g),
1965 name: Arbitrary::arbitrary(g),
1966 value: (0..value_size)
1967 .map(|_| <u8>::arbitrary(g))
1968 .collect::<Vec<u8>>(),
1969 };
1970 SubpacketValue::NotationData(nd)
1971 } else {
1972 SubpacketValue::arbitrary_bounded(g, depth)
1973 };
1974
1975 if use_nonoptimal_encoding {
1976 let length = encode_non_optimal(value.serialized_len());
1977 Subpacket::with_length(length, value, critical)
1978 } else {
1979 Subpacket::new(value, critical).unwrap()
1980 }
1981 }
1982}
1983
1984#[cfg(test)]
1985impl_arbitrary_with_bound!(Subpacket);
1986
1987impl fmt::Debug for Subpacket {
1988 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1989 let mut s = f.debug_struct("Subpacket");
1990 if self.length.raw.is_some() {
1991 s.field("length", &self.length);
1992 }
1993 if self.critical {
1994 s.field("critical", &self.critical);
1995 }
1996 s.field("value", &self.value);
1997 s.field("authenticated", &self.authenticated());
1998 s.finish()
1999 }
2000}
2001
2002impl Subpacket {
2003 /// Creates a new Subpacket.
2004 pub fn new(value: SubpacketValue, critical: bool)
2005 -> Result<Subpacket> {
2006 Ok(Self::with_length(
2007 SubpacketLength::from(1 /* Tag */ + value.serialized_len() as u32),
2008 value, critical))
2009 }
2010
2011 /// Creates a new subpacket with the given length and tag.
2012 pub(crate) fn with_length(length: SubpacketLength,
2013 value: SubpacketValue,
2014 critical: bool)
2015 -> Subpacket {
2016 Subpacket {
2017 length,
2018 critical,
2019 value,
2020 authenticated: false.into(),
2021 }
2022 }
2023
2024 /// Returns whether the critical bit is set.
2025 pub fn critical(&self) -> bool {
2026 self.critical
2027 }
2028
2029 /// Returns the Subpacket's tag.
2030 pub fn tag(&self) -> SubpacketTag {
2031 self.value.tag()
2032 }
2033
2034 /// Returns the Subpacket's value.
2035 pub fn value(&self) -> &SubpacketValue {
2036 &self.value
2037 }
2038
2039 /// Returns whether the information in this subpacket has been
2040 /// authenticated.
2041 ///
2042 /// There are three ways a subpacket can be authenticated:
2043 ///
2044 /// - It is in the hashed subpacket area and the signature has
2045 /// been verified.
2046 /// - It is in the unhashed subpacket area and the information
2047 /// is self-authenticating and has been authenticated by
2048 /// Sequoia. This can be done for issuer information and
2049 /// embedded Signatures.
2050 /// - The subpacket has been authenticated by the user and
2051 /// marked as such using [`Subpacket::set_authenticated`].
2052 ///
2053 /// Note: The authentication is only valid in the context of the
2054 /// signature the subpacket is in. If the authenticated
2055 /// `Subpacket` is added to a [`SubpacketArea`], the flag is
2056 /// cleared.
2057 pub fn authenticated(&self) -> bool {
2058 self.authenticated.load(atomic::Ordering::Relaxed)
2059 }
2060
2061 /// Marks the information in this subpacket as authenticated or
2062 /// not.
2063 ///
2064 /// See [`Subpacket::authenticated`] for more information.
2065 ///
2066 /// [`Subpacket::authenticated`]: Self::authenticated()
2067 pub fn set_authenticated(&self, authenticated: bool) -> bool {
2068 self.authenticated.swap(authenticated, atomic::Ordering::Relaxed)
2069 }
2070}
2071
2072#[derive(Clone, Debug)]
2073pub(crate) struct SubpacketLength {
2074 /// The length.
2075 pub(crate) len: u32,
2076 /// The length encoding used in the serialized form.
2077 /// If this is `None`, optimal encoding will be used.
2078 pub(crate) raw: Option<Vec<u8>>,
2079}
2080
2081impl From<u32> for SubpacketLength {
2082 fn from(len: u32) -> Self {
2083 SubpacketLength {
2084 len, raw: None,
2085 }
2086 }
2087}
2088
2089impl PartialEq for SubpacketLength {
2090 fn eq(&self, other: &Self) -> bool {
2091 self.cmp(other) == Ordering::Equal
2092 }
2093}
2094
2095impl Eq for SubpacketLength {}
2096
2097impl Hash for SubpacketLength {
2098 fn hash<H: Hasher>(&self, state: &mut H) {
2099 match &self.raw {
2100 Some(raw) => raw.hash(state),
2101 None => {
2102 let l = self.serialized_len();
2103 let mut raw = [0; 5];
2104 self.serialize_into(&mut raw[..l]).unwrap();
2105 raw[..l].hash(state);
2106 },
2107 }
2108 }
2109}
2110
2111impl PartialOrd for SubpacketLength {
2112 fn partial_cmp(&self, other: &SubpacketLength) -> Option<Ordering> {
2113 Some(self.cmp(other))
2114 }
2115}
2116
2117impl Ord for SubpacketLength {
2118 fn cmp(&self, other: &SubpacketLength) -> Ordering {
2119 match (&self.raw, &other.raw) {
2120 (None, None) => {
2121 self.len.cmp(&other.len)
2122 },
2123 // Compare serialized representations if at least one is given
2124 (Some(self_raw), Some(other_raw)) => {
2125 self_raw.cmp(other_raw)
2126 },
2127 (Some(self_raw), None) => {
2128 let mut other_raw = [0; 5];
2129 other.serialize_into(&mut other_raw[..self.serialized_len()])
2130 .unwrap();
2131 self_raw[..].cmp(&other_raw[..self.serialized_len()])
2132 },
2133 (None, Some(other_raw)) => {
2134 let mut self_raw = [0; 5];
2135 self.serialize_into(&mut self_raw[..self.serialized_len()])
2136 .unwrap();
2137 self_raw[..self.serialized_len()].cmp(&other_raw[..])
2138 },
2139 }
2140 }
2141}
2142
2143impl SubpacketLength {
2144 pub(crate) fn new(len: u32, raw: Option<Vec<u8>>) -> Self {
2145 Self { len, raw }
2146 }
2147
2148 /// Returns the length.
2149 pub(crate) fn len(&self) -> usize {
2150 self.len as usize
2151 }
2152
2153 /// Returns the length of the optimal encoding of `len`.
2154 pub(crate) fn len_optimal_encoding(len: u32) -> usize {
2155 BodyLength::serialized_len(&BodyLength::Full(len))
2156 }
2157}
2158
2159/// Subpacket storage.
2160///
2161/// Subpackets are stored either in a so-called hashed area or a
2162/// so-called unhashed area. Packets stored in the hashed area are
2163/// protected by the signature's hash whereas packets stored in the
2164/// unhashed area are not. Generally, two types of information are
2165/// stored in the unhashed area: self-authenticating data (the
2166/// `Issuer` subpacket, the `Issuer Fingerprint` subpacket, and the
2167/// `Embedded Signature` subpacket), and hints, like the features
2168/// subpacket.
2169///
2170/// When accessing subpackets directly via `SubpacketArea`s, the
2171/// subpackets are only looked up in the hashed area unless the
2172/// packets are self-authenticating in which case subpackets from the
2173/// hash area are preferred. To return packets from a specific area,
2174/// use the `hashed_area` and `unhashed_area` methods to get the
2175/// specific methods and then use their accessors.
2176#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2177pub struct SubpacketAreas {
2178 /// Subpackets that are part of the signature.
2179 hashed_area: SubpacketArea,
2180 /// Subpackets that are _not_ part of the signature.
2181 unhashed_area: SubpacketArea,
2182}
2183assert_send_and_sync!(SubpacketAreas);
2184
2185#[cfg(test)]
2186impl ArbitraryBounded for SubpacketAreas {
2187 fn arbitrary_bounded(g: &mut Gen, depth: usize) -> Self {
2188 SubpacketAreas::new(ArbitraryBounded::arbitrary_bounded(g, depth),
2189 ArbitraryBounded::arbitrary_bounded(g, depth))
2190 }
2191}
2192
2193#[cfg(test)]
2194impl_arbitrary_with_bound!(SubpacketAreas);
2195
2196impl SubpacketAreas {
2197 /// Returns a new `SubpacketAreas` object.
2198 pub fn new(hashed_area: SubpacketArea,
2199 unhashed_area: SubpacketArea) -> Self {
2200 Self {
2201 hashed_area,
2202 unhashed_area,
2203 }
2204 }
2205
2206 /// Gets a reference to the hashed area.
2207 pub fn hashed_area(&self) -> &SubpacketArea {
2208 &self.hashed_area
2209 }
2210
2211 /// Gets a mutable reference to the hashed area.
2212 ///
2213 /// Note: if you modify the hashed area of a [`Signature4`], this
2214 /// will invalidate the signature. Instead, you should normally
2215 /// convert the [`Signature4`] into a [`signature::SignatureBuilder`],
2216 /// modify that, and then create a new signature.
2217 pub fn hashed_area_mut(&mut self) -> &mut SubpacketArea {
2218 &mut self.hashed_area
2219 }
2220
2221 /// Gets a reference to the unhashed area.
2222 pub fn unhashed_area(&self) -> &SubpacketArea {
2223 &self.unhashed_area
2224 }
2225
2226 /// Gets a mutable reference to the unhashed area.
2227 pub fn unhashed_area_mut(&mut self) -> &mut SubpacketArea {
2228 &mut self.unhashed_area
2229 }
2230
2231 /// Sorts the subpacket areas.
2232 ///
2233 /// See [`SubpacketArea::sort()`].
2234 ///
2235 pub fn sort(&mut self) {
2236 self.hashed_area.sort();
2237 self.unhashed_area.sort();
2238 }
2239
2240 /// Returns a reference to the *last* instance of the specified
2241 /// subpacket, if any.
2242 ///
2243 /// This function returns the last instance of the specified
2244 /// subpacket in the subpacket areas in which it can occur. Thus,
2245 /// when looking for the `Signature Creation Time` subpacket, this
2246 /// function only considers the hashed subpacket area. But, when
2247 /// looking for the `Embedded Signature` subpacket, this function
2248 /// considers both subpacket areas.
2249 ///
2250 /// Unknown subpackets are assumed to only safely occur in the
2251 /// hashed subpacket area. Thus, any instances of them in the
2252 /// unhashed area are ignored.
2253 ///
2254 /// For subpackets that can safely occur in both subpacket areas,
2255 /// this function prefers instances in the hashed subpacket area.
2256 pub fn subpacket(&self, tag: SubpacketTag) -> Option<&Subpacket> {
2257 if let Some(sb) = self.hashed_area().subpacket(tag) {
2258 return Some(sb);
2259 }
2260
2261 // There are a couple of subpackets that we are willing to
2262 // take from the unhashed area. The others we ignore
2263 // completely.
2264 if !(tag == SubpacketTag::Issuer
2265 || tag == SubpacketTag::IssuerFingerprint
2266 || tag == SubpacketTag::EmbeddedSignature) {
2267 return None;
2268 }
2269
2270 self.unhashed_area().subpacket(tag)
2271 }
2272
2273 /// Returns a mutable reference to the *last* instance of the
2274 /// specified subpacket, if any.
2275 ///
2276 /// This function returns the last instance of the specified
2277 /// subpacket in the subpacket areas in which it can occur. Thus,
2278 /// when looking for the `Signature Creation Time` subpacket, this
2279 /// function only considers the hashed subpacket area. But, when
2280 /// looking for the `Embedded Signature` subpacket, this function
2281 /// considers both subpacket areas.
2282 ///
2283 /// Unknown subpackets are assumed to only safely occur in the
2284 /// hashed subpacket area. Thus, any instances of them in the
2285 /// unhashed area are ignored.
2286 ///
2287 /// For subpackets that can safely occur in both subpacket areas,
2288 /// this function prefers instances in the hashed subpacket area.
2289 pub fn subpacket_mut(&mut self, tag: SubpacketTag)
2290 -> Option<&mut Subpacket> {
2291 if let Some(_) = self.hashed_area().subpacket(tag) {
2292 return self.hashed_area_mut().subpacket_mut(tag);
2293 }
2294
2295 // There are a couple of subpackets that we are willing to
2296 // take from the unhashed area. The others we ignore
2297 // completely.
2298 if !(tag == SubpacketTag::Issuer
2299 || tag == SubpacketTag::IssuerFingerprint
2300 || tag == SubpacketTag::EmbeddedSignature) {
2301 return None;
2302 }
2303
2304 self.unhashed_area_mut().subpacket_mut(tag)
2305 }
2306
2307 /// Returns an iterator over all instances of the specified
2308 /// subpacket.
2309 ///
2310 /// This function returns an iterator over all instances of the
2311 /// specified subpacket in the subpacket areas in which it can
2312 /// occur. Thus, when looking for the `Issuer` subpacket, the
2313 /// iterator includes instances of the subpacket from both the
2314 /// hashed subpacket area and the unhashed subpacket area, but
2315 /// when looking for the `Signature Creation Time` subpacket, the
2316 /// iterator only includes instances of the subpacket from the
2317 /// hashed subpacket area; any instances of the subpacket in the
2318 /// unhashed subpacket area are ignored.
2319 ///
2320 /// Unknown subpackets are assumed to only safely occur in the
2321 /// hashed subpacket area. Thus, any instances of them in the
2322 /// unhashed area are ignored.
2323 pub fn subpackets(&self, tag: SubpacketTag)
2324 -> impl Iterator<Item = &Subpacket> + Send + Sync
2325 {
2326 // It would be nice to do:
2327 //
2328 // let iter = self.hashed_area().subpackets(tag);
2329 // if (subpacket allowed in unhashed area) {
2330 // iter.chain(self.unhashed_area().subpackets(tag))
2331 // } else {
2332 // iter
2333 // }
2334 //
2335 // but then we have different types. Instead, we need to
2336 // inline SubpacketArea::subpackets, add the additional
2337 // constraint in the closure, and hope that the optimizer is
2338 // smart enough to not unnecessarily iterate over the unhashed
2339 // area.
2340 self.hashed_area().subpackets(tag).chain(
2341 self.unhashed_area()
2342 .iter()
2343 .filter(move |sp| {
2344 (tag == SubpacketTag::Issuer
2345 || tag == SubpacketTag::IssuerFingerprint
2346 || tag == SubpacketTag::EmbeddedSignature)
2347 && sp.tag() == tag
2348 }))
2349 }
2350
2351 pub(crate) fn subpackets_mut(&mut self, tag: SubpacketTag)
2352 -> impl Iterator<Item = &mut Subpacket> + Send + Sync
2353 {
2354 self.hashed_area.subpackets_mut(tag).chain(
2355 self.unhashed_area
2356 .iter_mut()
2357 .filter(move |sp| {
2358 (tag == SubpacketTag::Issuer
2359 || tag == SubpacketTag::IssuerFingerprint
2360 || tag == SubpacketTag::EmbeddedSignature)
2361 && sp.tag() == tag
2362 }))
2363 }
2364
2365 /// Returns the value of the Signature Creation Time subpacket.
2366 ///
2367 /// The [Signature Creation Time subpacket] specifies when the
2368 /// signature was created. According to the standard, all
2369 /// signatures must include a Signature Creation Time subpacket in
2370 /// the signature's hashed area. This doesn't mean that the time
2371 /// stamp is correct: the issuer can always forge it.
2372 ///
2373 /// [Signature Creation Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
2374 ///
2375 /// If the subpacket is not present in the hashed subpacket area,
2376 /// this returns `None`.
2377 ///
2378 /// Note: if the signature contains multiple instances of this
2379 /// subpacket in the hashed subpacket area, the last one is
2380 /// returned.
2381 pub fn signature_creation_time(&self) -> Option<time::SystemTime> {
2382 // 4-octet time field
2383 if let Some(sb)
2384 = self.subpacket(SubpacketTag::SignatureCreationTime) {
2385 if let SubpacketValue::SignatureCreationTime(v) = sb.value {
2386 Some(v.into())
2387 } else {
2388 None
2389 }
2390 } else {
2391 None
2392 }
2393 }
2394
2395 /// Returns the value of the Signature Expiration Time subpacket.
2396 ///
2397 /// This function is called `signature_validity_period` and not
2398 /// `signature_expiration_time`, which would be more consistent
2399 /// with the subpacket's name, because the latter suggests an
2400 /// absolute time, but the time is actually relative to the
2401 /// signature's creation time, which is stored in the signature's
2402 /// [Signature Creation Time subpacket].
2403 ///
2404 /// [Signature Creation Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
2405 ///
2406 /// A [Signature Expiration Time subpacket] specifies when the
2407 /// signature expires. This is different from the [Key Expiration
2408 /// Time subpacket], which is accessed using
2409 /// [`SubpacketAreas::key_validity_period`], and used to
2410 /// specify when an associated key expires. The difference is
2411 /// that in the former case, the signature itself expires, but in
2412 /// the latter case, only the associated key expires. This
2413 /// difference is critical: if a binding signature expires, then
2414 /// an OpenPGP implementation will still consider the associated
2415 /// key to be valid if there is another valid binding signature,
2416 /// even if it is older than the expired signature; if the active
2417 /// binding signature indicates that the key has expired, then
2418 /// OpenPGP implementations will not fall back to an older binding
2419 /// signature.
2420 ///
2421 /// [Signature Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.18
2422 /// [Key Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
2423 /// [`SubpacketAreas::key_validity_period`]: SubpacketAreas::key_validity_period()
2424 ///
2425 /// There are several cases where having a signature expire is
2426 /// useful. Say Alice certifies Bob's certificate for
2427 /// `bob@example.org`. She can limit the lifetime of the
2428 /// certification to force her to reevaluate the certification
2429 /// shortly before it expires. For instance, is Bob still
2430 /// associated with `example.org`? Does she have reason to
2431 /// believe that his key has been compromised? Using an
2432 /// expiration is common in the X.509 ecosystem. For instance,
2433 /// [Let's Encrypt] issues certificates with 90-day lifetimes.
2434 ///
2435 /// [Let's Encrypt]: https://letsencrypt.org/2015/11/09/why-90-days.html
2436 ///
2437 /// Having signatures expire can also be useful when deploying
2438 /// software. For instance, you might have a service that
2439 /// installs an update if it has been signed by a trusted
2440 /// certificate. To prevent an adversary from coercing the
2441 /// service to install an older version, you could limit the
2442 /// signature's lifetime to just a few minutes.
2443 ///
2444 /// If the subpacket is not present in the hashed subpacket area,
2445 /// this returns `None`. If this function returns `None`, or the
2446 /// returned period is `0`, the signature does not expire.
2447 ///
2448 /// Note: if the signature contains multiple instances of this
2449 /// subpacket in the hashed subpacket area, the last one is
2450 /// returned.
2451 pub fn signature_validity_period(&self) -> Option<time::Duration> {
2452 // 4-octet time field
2453 if let Some(sb)
2454 = self.subpacket(SubpacketTag::SignatureExpirationTime) {
2455 if let SubpacketValue::SignatureExpirationTime(v) = sb.value {
2456 Some(v.into())
2457 } else {
2458 None
2459 }
2460 } else {
2461 None
2462 }
2463 }
2464
2465 /// Returns the value of the Signature Expiration Time subpacket
2466 /// as an absolute time.
2467 ///
2468 /// A [Signature Expiration Time subpacket] specifies when the
2469 /// signature expires. The value stored is not an absolute time,
2470 /// but a duration, which is relative to the Signature's creation
2471 /// time. To better reflect the subpacket's name, this method
2472 /// returns the absolute expiry time, and the
2473 /// [`SubpacketAreas::signature_validity_period`] method returns
2474 /// the subpacket's raw value.
2475 ///
2476 /// [Signature Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.18
2477 /// [`SubpacketAreas::signature_validity_period`]: SubpacketAreas::signature_validity_period()
2478 ///
2479 /// The Signature Expiration Time subpacket is different from the
2480 /// [Key Expiration Time subpacket], which is accessed using
2481 /// [`SubpacketAreas::key_validity_period`], and used specifies
2482 /// when an associated key expires. The difference is that in the
2483 /// former case, the signature itself expires, but in the latter
2484 /// case, only the associated key expires. This difference is
2485 /// critical: if a binding signature expires, then an OpenPGP
2486 /// implementation will still consider the associated key to be
2487 /// valid if there is another valid binding signature, even if it
2488 /// is older than the expired signature; if the active binding
2489 /// signature indicates that the key has expired, then OpenPGP
2490 /// implementations will not fall back to an older binding
2491 /// signature.
2492 ///
2493 /// [Key Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
2494 /// [`SubpacketAreas::key_validity_period`]: SubpacketAreas::key_validity_period()
2495 ///
2496 /// There are several cases where having a signature expire is
2497 /// useful. Say Alice certifies Bob's certificate for
2498 /// `bob@example.org`. She can limit the lifetime of the
2499 /// certification to force her to reevaluate the certification
2500 /// shortly before it expires. For instance, is Bob still
2501 /// associated with `example.org`? Does she have reason to
2502 /// believe that his key has been compromised? Using an
2503 /// expiration is common in the X.509 ecosystem. For instance,
2504 /// [Let's Encrypt] issues certificates with 90-day lifetimes.
2505 ///
2506 /// [Let's Encrypt]: https://letsencrypt.org/2015/11/09/why-90-days.html
2507 ///
2508 /// Having signatures expire can also be useful when deploying
2509 /// software. For instance, you might have a service that
2510 /// installs an update if it has been signed by a trusted
2511 /// certificate. To prevent an adversary from coercing the
2512 /// service to install an older version, you could limit the
2513 /// signature's lifetime to just a few minutes.
2514 ///
2515 /// If the subpacket is not present in the hashed subpacket area,
2516 /// this returns `None`. If this function returns `None`, the
2517 /// signature does not expire.
2518 ///
2519 /// Note: if the signature contains multiple instances of this
2520 /// subpacket in the hashed subpacket area, the last one is
2521 /// returned.
2522 // Note: If you update this function, also update
2523 // SignatureBuilder::signature_expiration_time.
2524 pub fn signature_expiration_time(&self) -> Option<time::SystemTime> {
2525 match (self.signature_creation_time(), self.signature_validity_period())
2526 {
2527 (Some(ct), Some(vp)) if vp.as_secs() > 0 => Some(ct + vp),
2528 _ => None,
2529 }
2530 }
2531
2532 /// Returns whether the signature is alive at the specified
2533 /// time.
2534 ///
2535 /// A signature is considered to be alive if `creation time -
2536 /// tolerance <= time` and `time < expiration time`.
2537 ///
2538 /// This function does not check whether the key is revoked.
2539 ///
2540 /// If `time` is `None`, then this function uses the current time
2541 /// for `time`.
2542 ///
2543 /// If `time` is `None`, and `clock_skew_tolerance` is `None`,
2544 /// then this function uses [`CLOCK_SKEW_TOLERANCE`] for the
2545 /// tolerance. If `time` is not `None `and `clock_skew_tolerance`
2546 /// is `None`, it uses no tolerance. The intuition here is that
2547 /// we only need a tolerance when checking if a signature is alive
2548 /// right now; if we are checking at a specific time, we don't
2549 /// want to use a tolerance.
2550 ///
2551 ///
2552 /// A small amount of tolerance for clock skew is necessary,
2553 /// because although most computers synchronize their clocks with
2554 /// a time server, up to a few seconds of clock skew are not
2555 /// unusual in practice. And, even worse, several minutes of
2556 /// clock skew appear to be not uncommon on virtual machines.
2557 ///
2558 /// Not accounting for clock skew can result in signatures being
2559 /// unexpectedly considered invalid. Consider: computer A sends a
2560 /// message to computer B at 9:00, but computer B, whose clock
2561 /// says the current time is 8:59, rejects it, because the
2562 /// signature appears to have been made in the future. This is
2563 /// particularly problematic for low-latency protocols built on
2564 /// top of OpenPGP, e.g., when two MUAs synchronize their state
2565 /// via a shared IMAP folder.
2566 ///
2567 /// Being tolerant to potential clock skew is not always
2568 /// appropriate. For instance, when determining a User ID's
2569 /// current self signature at time `t`, we don't ever want to
2570 /// consider a self-signature made after `t` to be valid, even if
2571 /// it was made just a few moments after `t`. This goes doubly so
2572 /// for soft revocation certificates: the user might send a
2573 /// message that she is retiring, and then immediately create a
2574 /// soft revocation. The soft revocation should not invalidate
2575 /// the message.
2576 ///
2577 /// Unfortunately, in many cases, whether we should account for
2578 /// clock skew or not depends on application-specific context. As
2579 /// a rule of thumb, if the time and the timestamp come from
2580 /// different clocks, you probably want to account for clock skew.
2581 ///
2582 /// # Errors
2583 ///
2584 /// [Section 5.2.3.11 of RFC 9580] states that a Signature Creation
2585 /// Time subpacket "MUST be present in the hashed area."
2586 /// Consequently, if such a packet does not exist, this function
2587 /// returns [`Error::MalformedPacket`].
2588 ///
2589 /// [Section 5.2.3.11 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
2590 /// [`Error::MalformedPacket`]: super::super::super::Error::MalformedPacket
2591 ///
2592 /// # Examples
2593 ///
2594 /// Alice's desktop computer and laptop exchange messages in real
2595 /// time via a shared IMAP folder. Unfortunately, the clocks are
2596 /// not perfectly synchronized: the desktop computer's clock is a
2597 /// few seconds ahead of the laptop's clock. When there is little
2598 /// or no propagation delay, this means that the laptop will
2599 /// consider the signatures to be invalid, because they appear to
2600 /// have been created in the future. Using a tolerance prevents
2601 /// this from happening.
2602 ///
2603 /// ```
2604 /// use std::time::{SystemTime, Duration};
2605 /// use sequoia_openpgp as openpgp;
2606 /// use openpgp::cert::prelude::*;
2607 /// use openpgp::packet::signature::SignatureBuilder;
2608 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
2609 /// use openpgp::types::SignatureType;
2610 ///
2611 /// # fn main() -> openpgp::Result<()> {
2612 /// #
2613 /// let (alice, _) =
2614 /// CertBuilder::general_purpose(Some("alice@example.org"))
2615 /// .generate()?;
2616 ///
2617 /// // Alice's Desktop computer signs a message. Its clock is a
2618 /// // few seconds fast.
2619 /// let now = SystemTime::now() + Duration::new(5, 0);
2620 ///
2621 /// let mut alices_signer = alice.primary_key().key().clone()
2622 /// .parts_into_secret()?.into_keypair()?;
2623 /// let msg = "START PROTOCOL";
2624 /// let mut sig = SignatureBuilder::new(SignatureType::Binary)
2625 /// .set_signature_creation_time(now)?
2626 /// .sign_message(&mut alices_signer, msg)?;
2627 /// # assert!(sig.verify_message(alices_signer.public(), msg).is_ok());
2628 ///
2629 /// // The desktop computer transfers the message to the laptop
2630 /// // via the shared IMAP folder. Because the laptop receives a
2631 /// // push notification, it immediately processes it.
2632 /// // Unfortunately, it is considered to be invalid: the message
2633 /// // appears to be from the future!
2634 /// assert!(sig.signature_alive(None, Duration::new(0, 0)).is_err());
2635 ///
2636 /// // But, using the small default tolerance causes the laptop
2637 /// // to consider the signature to be alive.
2638 /// assert!(sig.signature_alive(None, None).is_ok());
2639 /// # Ok(()) }
2640 /// ```
2641 pub fn signature_alive<T, U>(&self, time: T, clock_skew_tolerance: U)
2642 -> Result<()>
2643 where T: Into<Option<time::SystemTime>>,
2644 U: Into<Option<time::Duration>>
2645 {
2646 let (time, tolerance)
2647 = match (time.into(), clock_skew_tolerance.into()) {
2648 (None, None) =>
2649 (crate::now(),
2650 CLOCK_SKEW_TOLERANCE),
2651 (None, Some(tolerance)) =>
2652 (crate::now(),
2653 tolerance),
2654 (Some(time), None) =>
2655 (time, time::Duration::new(0, 0)),
2656 (Some(time), Some(tolerance)) =>
2657 (time, tolerance)
2658 };
2659
2660 match (self.signature_creation_time(), self.signature_validity_period())
2661 {
2662 (None, _) =>
2663 Err(Error::MalformedPacket("no signature creation time".into())
2664 .into()),
2665 (Some(c), Some(e)) if e.as_secs() > 0 && (c + e) <= time =>
2666 Err(Error::Expired(c + e).into()),
2667 // Be careful to avoid underflow.
2668 (Some(c), _) if cmp::max(c, time::UNIX_EPOCH + tolerance)
2669 - tolerance > time =>
2670 Err(Error::NotYetLive(cmp::max(c, time::UNIX_EPOCH + tolerance)
2671 - tolerance).into()),
2672 _ => Ok(()),
2673 }
2674 }
2675
2676 /// Returns the value of the Key Expiration Time subpacket.
2677 ///
2678 /// This function is called `key_validity_period` and not
2679 /// `key_expiration_time`, which would be more consistent with
2680 /// the subpacket's name, because the latter suggests an absolute
2681 /// time, but the time is actually relative to the associated
2682 /// key's (*not* the signature's) creation time, which is stored
2683 /// in the [Key].
2684 ///
2685 /// [Key]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.5.2
2686 ///
2687 /// A [Key Expiration Time subpacket] specifies when the
2688 /// associated key expires. This is different from the [Signature
2689 /// Expiration Time subpacket] (accessed using
2690 /// [`SubpacketAreas::signature_validity_period`]), which is
2691 /// used to specify when the signature expires. That is, in the
2692 /// former case, the associated key expires, but in the latter
2693 /// case, the signature itself expires. This difference is
2694 /// critical: if a binding signature expires, then an OpenPGP
2695 /// implementation will still consider the associated key to be
2696 /// valid if there is another valid binding signature, even if it
2697 /// is older than the expired signature; if the active binding
2698 /// signature indicates that the key has expired, then OpenPGP
2699 /// implementations will not fall back to an older binding
2700 /// signature.
2701 ///
2702 /// [Key Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
2703 /// [Signature Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
2704 /// [`SubpacketAreas::signature_validity_period`]: Self::signature_validity_period()
2705 ///
2706 /// If the subpacket is not present in the hashed subpacket area,
2707 /// this returns `None`. If this function returns `None`, or the
2708 /// returned period is `0`, the key does not expire.
2709 ///
2710 /// Note: if the signature contains multiple instances of this
2711 /// subpacket in the hashed subpacket area, the last one is
2712 /// returned.
2713 pub fn key_validity_period(&self) -> Option<time::Duration> {
2714 // 4-octet time field
2715 if let Some(sb)
2716 = self.subpacket(SubpacketTag::KeyExpirationTime) {
2717 if let SubpacketValue::KeyExpirationTime(v) = sb.value {
2718 Some(v.into())
2719 } else {
2720 None
2721 }
2722 } else {
2723 None
2724 }
2725 }
2726
2727 /// Returns the value of the Key Expiration Time subpacket
2728 /// as an absolute time.
2729 ///
2730 /// A [Key Expiration Time subpacket] specifies when a key
2731 /// expires. The value stored is not an absolute time, but a
2732 /// duration, which is relative to the associated [Key]'s creation
2733 /// time, which is stored in the Key packet, not the binding
2734 /// signature. As such, the Key Expiration Time subpacket is only
2735 /// meaningful on a key's binding signature. To better reflect
2736 /// the subpacket's name, this method returns the absolute expiry
2737 /// time, and the [`SubpacketAreas::key_validity_period`] method
2738 /// returns the subpacket's raw value.
2739 ///
2740 /// [Key Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
2741 /// [Key]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.5.2
2742 /// [`SubpacketAreas::key_validity_period`]: Self::key_validity_period()
2743 ///
2744 /// The Key Expiration Time subpacket is different from the
2745 /// [Signature Expiration Time subpacket], which is accessed using
2746 /// [`SubpacketAreas::signature_validity_period`], and specifies
2747 /// when a signature expires. The difference is that in the
2748 /// former case, only the associated key expires, but in the
2749 /// latter case, the signature itself expires. This difference is
2750 /// critical: if a binding signature expires, then an OpenPGP
2751 /// implementation will still consider the associated key to be
2752 /// valid if there is another valid binding signature, even if it
2753 /// is older than the expired signature; if the active binding
2754 /// signature indicates that the key has expired, then OpenPGP
2755 /// implementations will not fall back to an older binding
2756 /// signature.
2757 ///
2758 /// [Signature Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.18
2759 /// [`SubpacketAreas::signature_validity_period`]: Self::signature_validity_period()
2760 ///
2761 /// Because the absolute time is relative to the key's creation
2762 /// time, which is stored in the key itself, this function needs
2763 /// the associated key. Since there is no way to get the
2764 /// associated key from a signature, the key must be passed to
2765 /// this function. This function does not check that the key is
2766 /// in fact associated with this signature.
2767 ///
2768 /// If the subpacket is not present in the hashed subpacket area,
2769 /// this returns `None`. If this function returns `None`, the
2770 /// signature does not expire.
2771 ///
2772 /// Note: if the signature contains multiple instances of this
2773 /// subpacket in the hashed subpacket area, the last one is
2774 /// returned.
2775 pub fn key_expiration_time<P, R>(&self, key: &Key<P, R>)
2776 -> Option<time::SystemTime>
2777 where P: key::KeyParts,
2778 R: key::KeyRole,
2779 {
2780 match self.key_validity_period() {
2781 Some(vp) if vp.as_secs() > 0 => Some(key.creation_time() + vp),
2782 _ => None,
2783 }
2784 }
2785
2786 /// Returns whether a key is alive at the specified
2787 /// time.
2788 ///
2789 /// A [Key] is considered to be alive if `creation time -
2790 /// tolerance <= time` and `time < expiration time`.
2791 ///
2792 /// [Key]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.5.2
2793 ///
2794 /// This function does not check whether the signature is alive
2795 /// (cf. [`SubpacketAreas::signature_alive`]), or whether the key
2796 /// is revoked (cf. [`ValidKeyAmalgamation::revoked`]).
2797 ///
2798 /// [`SubpacketAreas::signature_alive`]: Self::signature_alive()
2799 /// [`ValidKeyAmalgamation::revoked`]: crate::cert::amalgamation::key::ValidKeyAmalgamationIter::revoked()
2800 ///
2801 /// If `time` is `None`, then this function uses the current time
2802 /// for `time`.
2803 ///
2804 /// Whereas a Key's expiration time is stored in the Key's active
2805 /// binding signature in the [Key Expiration Time
2806 /// subpacket], its creation time is stored in the Key packet. As
2807 /// such, the associated Key must be passed to this function.
2808 /// This function, however, has no way to check that the signature
2809 /// is actually a binding signature for the specified Key.
2810 ///
2811 /// [Key Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
2812 ///
2813 /// # Examples
2814 ///
2815 /// Even keys that don't expire may not be considered alive. This
2816 /// is the case if they were created after the specified time.
2817 ///
2818 /// ```
2819 /// use std::time::{SystemTime, Duration};
2820 /// use sequoia_openpgp as openpgp;
2821 /// use openpgp::cert::prelude::*;
2822 /// use openpgp::policy::StandardPolicy;
2823 ///
2824 /// # fn main() -> openpgp::Result<()> {
2825 /// #
2826 /// let p = &StandardPolicy::new();
2827 ///
2828 /// let (cert, _) = CertBuilder::new().generate()?;
2829 ///
2830 /// let mut pk = cert.primary_key().key();
2831 /// let sig = cert.primary_key().with_policy(p, None)?.binding_signature();
2832 ///
2833 /// assert!(sig.key_alive(pk, None).is_ok());
2834 /// // A key is not considered alive prior to its creation time.
2835 /// let the_past = SystemTime::now() - Duration::new(300, 0);
2836 /// assert!(sig.key_alive(pk, the_past).is_err());
2837 /// # Ok(()) }
2838 /// ```
2839 pub fn key_alive<P, R, T>(&self, key: &Key<P, R>, t: T) -> Result<()>
2840 where P: key::KeyParts,
2841 R: key::KeyRole,
2842 T: Into<Option<time::SystemTime>>
2843 {
2844 let t = t.into().unwrap_or_else(crate::now);
2845
2846 match self.key_validity_period() {
2847 Some(e) if e.as_secs() > 0 && key.creation_time() + e <= t =>
2848 Err(Error::Expired(key.creation_time() + e).into()),
2849 _ if key.creation_time() > t =>
2850 Err(Error::NotYetLive(key.creation_time()).into()),
2851 _ => Ok(()),
2852 }
2853 }
2854
2855 /// Returns the value of the Exportable Certification subpacket.
2856 ///
2857 /// The [Exportable Certification subpacket] indicates whether the
2858 /// signature should be exported (e.g., published on a public key
2859 /// server) or not. When using [`Serialize::export`] to export a
2860 /// certificate, signatures that have this subpacket present and
2861 /// set to false are not serialized.
2862 ///
2863 /// [Exportable Certification subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.19
2864 /// [`Serialize::export`]: https://docs.sequoia-pgp.org/sequoia_openpgp/serialize/trait.Serialize.html#method.export
2865 ///
2866 /// Normally, you'll want to use [`Signature4::exportable`] to
2867 /// check if a signature should be exported. That function also
2868 /// checks whether the signature includes any sensitive
2869 /// [Revocation Key subpackets], which also shouldn't be exported.
2870 ///
2871 /// [`Signature4::exportable`]: super::Signature4::exportable()
2872 /// [Revocation Key subpackets]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.23
2873 ///
2874 /// If the subpacket is not present in the hashed subpacket area,
2875 /// this returns `None`.
2876 ///
2877 /// Note: if the signature contains multiple instances of this
2878 /// subpacket in the hashed subpacket area, the last one is
2879 /// returned.
2880 pub fn exportable_certification(&self) -> Option<bool> {
2881 // 1 octet of exportability, 0 for not, 1 for exportable
2882 if let Some(sb)
2883 = self.subpacket(SubpacketTag::ExportableCertification) {
2884 if let SubpacketValue::ExportableCertification(v) = sb.value {
2885 Some(v)
2886 } else {
2887 None
2888 }
2889 } else {
2890 None
2891 }
2892 }
2893
2894 /// Returns the value of the Trust Signature subpacket.
2895 ///
2896 /// The [Trust Signature subpacket] indicates the degree to which
2897 /// a certificate holder is trusted to certify other keys.
2898 ///
2899 /// [Trust Signature subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.21
2900 ///
2901 /// A level of 0 means that the certificate holder is not trusted
2902 /// to certificate other keys, a level of 1 means that the
2903 /// certificate holder is a trusted introducer (a [certificate
2904 /// authority]) and any certifications that they make should be
2905 /// considered valid. A level of 2 means the certificate holder
2906 /// can designate level 1 trusted introducers, etc.
2907 ///
2908 /// [certificate authority]: https://en.wikipedia.org/wiki/Certificate_authority
2909 ///
2910 /// The trust indicates the degree of confidence. A value of 120
2911 /// means that a certification should be considered valid. A
2912 /// value of 60 means that a certification should only be
2913 /// considered partially valid. In the latter case, typically
2914 /// three such certifications are required for a binding to be
2915 /// considered authenticated.
2916 ///
2917 /// If the subpacket is not present in the hashed subpacket area,
2918 /// this returns `None`.
2919 ///
2920 /// Note: if the signature contains multiple instances of this
2921 /// subpacket in the hashed subpacket area, the last one is
2922 /// returned.
2923 pub fn trust_signature(&self) -> Option<(u8, u8)> {
2924 // 1 octet "level" (depth), 1 octet of trust amount
2925 if let Some(sb) = self.subpacket(SubpacketTag::TrustSignature) {
2926 if let SubpacketValue::TrustSignature{ level, trust } = sb.value {
2927 Some((level, trust))
2928 } else {
2929 None
2930 }
2931 } else {
2932 None
2933 }
2934 }
2935
2936 /// Returns the values of all Regular Expression subpackets.
2937 ///
2938 /// The [Regular Expression subpacket] is used in conjunction with
2939 /// a [Trust Signature subpacket], which is accessed using
2940 /// [`SubpacketAreas::trust_signature`], to limit the scope
2941 /// of a trusted introducer. This is useful, for instance, when a
2942 /// company has a CA and you only want to trust them to certify
2943 /// their own employees.
2944 ///
2945 /// [Trust Signature subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.21
2946 /// [Regular Expression subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.22
2947 /// [`SubpacketAreas::trust_signature`]: Self::trust_signature()
2948 ///
2949 /// Note: The serialized form includes a trailing `NUL` byte.
2950 /// Sequoia strips the `NUL` when parsing the subpacket.
2951 ///
2952 /// This returns all instances of the Regular Expression subpacket
2953 /// in the hashed subpacket area.
2954 pub fn regular_expressions(&self) -> impl Iterator<Item=&[u8]> + Send + Sync
2955 {
2956 self.subpackets(SubpacketTag::RegularExpression).map(|sb| {
2957 match sb.value {
2958 SubpacketValue::RegularExpression(ref v) => &v[..],
2959 _ => unreachable!(),
2960 }
2961 })
2962 }
2963
2964 /// Returns the value of the Revocable subpacket.
2965 ///
2966 ///
2967 /// The [Revocable subpacket] indicates whether a certification
2968 /// may be later revoked by creating a [Certification revocation
2969 /// signature] (0x30) that targets the signature using the
2970 /// [Signature Target subpacket] (accessed using the
2971 /// [`SubpacketAreas::signature_target`] method).
2972 ///
2973 /// [Revocable subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.20
2974 /// [Certification revocation signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
2975 /// [Signature Target subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.33
2976 /// [`SubpacketAreas::signature_target`]: Self::signature_target()
2977 ///
2978 /// If the subpacket is not present in the hashed subpacket area,
2979 /// this returns `None`.
2980 ///
2981 /// Note: if the signature contains multiple instances of this
2982 /// subpacket in the hashed subpacket area, the last one is
2983 /// returned.
2984 pub fn revocable(&self) -> Option<bool> {
2985 // 1 octet of revocability, 0 for not, 1 for revocable
2986 if let Some(sb)
2987 = self.subpacket(SubpacketTag::Revocable) {
2988 if let SubpacketValue::Revocable(v) = sb.value {
2989 Some(v)
2990 } else {
2991 None
2992 }
2993 } else {
2994 None
2995 }
2996 }
2997
2998 /// Returns the values of all Revocation Key subpackets.
2999 ///
3000 /// A [Revocation Key subpacket] indicates certificates (so-called
3001 /// designated revokers) that are allowed to revoke the signer's
3002 /// certificate. For instance, if Alice trusts Bob, she can set
3003 /// him as a designated revoker. This is useful if Alice loses
3004 /// access to her key, and therefore is unable to generate a
3005 /// revocation certificate on her own. In this case, she can
3006 /// still Bob to generate one on her behalf.
3007 ///
3008 /// When getting a certificate's revocation keys, all valid
3009 /// self-signatures should be checked, not only the active
3010 /// self-signature. This prevents an attacker who has gained
3011 /// access to the private key material from invalidating a
3012 /// third-party revocation by publishing a new self signature that
3013 /// doesn't include any revocation keys.
3014 ///
3015 /// Due to the complexity of verifying such signatures, many
3016 /// OpenPGP implementations do not support this feature.
3017 ///
3018 /// [Revocation Key subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.23
3019 ///
3020 /// This returns all instance of the Revocation Key subpacket in
3021 /// the hashed subpacket area.
3022 pub fn revocation_keys(&self)
3023 -> impl Iterator<Item=&RevocationKey> + Send + Sync
3024 {
3025 self.subpackets(SubpacketTag::RevocationKey)
3026 .map(|sb| {
3027 match sb.value {
3028 SubpacketValue::RevocationKey(ref rk) => rk,
3029 _ => unreachable!(),
3030 }
3031 })
3032 }
3033
3034 /// Returns the values of all Issuer subpackets.
3035 ///
3036 /// The [Issuer subpacket] is used when processing a signature to
3037 /// identify which certificate created the signature. Since this
3038 /// information is self-authenticating (the act of validating the
3039 /// signature authenticates the subpacket), it may be stored in the
3040 /// unhashed subpacket area.
3041 ///
3042 /// [Issuer subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
3043 ///
3044 /// This returns all instances of the Issuer subpacket in both the
3045 /// hashed subpacket area and the unhashed subpacket area.
3046 pub fn issuers(&self) -> impl Iterator<Item=&KeyID> + Send + Sync {
3047 // 8-octet Key ID
3048 self.subpackets(SubpacketTag::Issuer)
3049 .map(|sb| {
3050 match sb.value {
3051 SubpacketValue::Issuer(ref keyid) => keyid,
3052 _ => unreachable!(),
3053 }
3054 })
3055 }
3056
3057 /// Returns the values of all Issuer Fingerprint subpackets.
3058 ///
3059 /// The [Issuer Fingerprint subpacket] is used when processing a
3060 /// signature to identify which certificate created the signature.
3061 /// Since this information is self-authenticating (the act of
3062 /// validating the signature authenticates the subpacket), it is
3063 /// normally stored in the unhashed subpacket area.
3064 ///
3065 /// [Issuer Fingerprint subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
3066 ///
3067 /// This returns all instances of the Issuer Fingerprint subpacket
3068 /// in both the hashed subpacket area and the unhashed subpacket
3069 /// area.
3070 pub fn issuer_fingerprints(&self)
3071 -> impl Iterator<Item=&Fingerprint> + Send + Sync
3072 {
3073 // 1 octet key version number, N octets of fingerprint
3074 self.subpackets(SubpacketTag::IssuerFingerprint)
3075 .map(|sb| {
3076 match sb.value {
3077 SubpacketValue::IssuerFingerprint(ref fpr) => fpr,
3078 _ => unreachable!(),
3079 }
3080 })
3081 }
3082
3083 /// Returns all Notation Data subpackets.
3084 ///
3085 /// [Notation Data subpackets] are key-value pairs. They can be
3086 /// used by applications to annotate signatures in a structured
3087 /// way. For instance, they can define additional,
3088 /// application-specific security requirements. Because they are
3089 /// functionally equivalent to subpackets, they can also be used
3090 /// for OpenPGP extensions. This is how the [Intended Recipient
3091 /// subpacket] started life.
3092 ///
3093 /// [Notation Data subpackets]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
3094 /// [Intended Recipient subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-intended-recipient-fingerpr
3095 ///
3096 /// Notation names are structured, and are divided into two
3097 /// namespaces: the user namespace and the IETF namespace. Names
3098 /// in the user namespace have the form `name@example.org` and
3099 /// their meaning is defined by the owner of the domain. The
3100 /// meaning of the notation `name@example.org`, for instance, is
3101 /// defined by whoever controls `example.org`. Names in the IETF
3102 /// namespace do not contain an `@` and are managed by IANA. See
3103 /// [Section 5.2.3.24 of RFC 9580] for details.
3104 ///
3105 /// [Section 5.2.3.24 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
3106 ///
3107 /// This returns all instances of the Notation Data subpacket in
3108 /// the hashed subpacket area.
3109 pub fn notation_data(&self)
3110 -> impl Iterator<Item=&NotationData> + Send + Sync
3111 {
3112 self.subpackets(SubpacketTag::NotationData)
3113 .map(|sb| {
3114 match sb.value {
3115 SubpacketValue::NotationData(ref v) => v,
3116 _ => unreachable!(),
3117 }
3118 })
3119 }
3120
3121 /// Returns the values of all Notation Data subpackets with the
3122 /// given name.
3123 ///
3124 /// [Notation Data subpackets] are key-value pairs. They can be
3125 /// used by applications to annotate signatures in a structured
3126 /// way. For instance, they can define additional,
3127 /// application-specific security requirements. Because they are
3128 /// functionally equivalent to subpackets, they can also be used
3129 /// for OpenPGP extensions. This is how the [Intended Recipient
3130 /// subpacket] started life.
3131 ///
3132 /// [Notation Data subpackets]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
3133 /// [Intended Recipient subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-intended-recipient-fingerpr
3134 ///
3135 /// Notation names are structured, and are divided into two
3136 /// namespaces: the user namespace and the IETF namespace. Names
3137 /// in the user namespace have the form `name@example.org` and
3138 /// their meaning is defined by the owner of the domain. The
3139 /// meaning of the notation `name@example.org`, for instance, is
3140 /// defined by whoever controls `example.org`. Names in the IETF
3141 /// namespace do not contain an `@` and are managed by IANA. See
3142 /// [Section 5.2.3.24 of RFC 9580] for details.
3143 ///
3144 /// [Section 5.2.3.24 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
3145 ///
3146 /// This returns the values of all instances of the Notation Data
3147 /// subpacket with the specified name in the hashed subpacket area.
3148 // name needs 'a, because the closure outlives the function call.
3149 pub fn notation<'a, N>(&'a self, name: N)
3150 -> impl Iterator<Item=&'a [u8]> + Send + Sync
3151 where N: 'a + AsRef<str> + Send + Sync
3152 {
3153 self.notation_data()
3154 .filter_map(move |n| {
3155 if n.name == name.as_ref() {
3156 Some(&n.value[..])
3157 } else {
3158 None
3159 }
3160 })
3161 }
3162
3163 /// Returns the value of the Preferred Symmetric Algorithms
3164 /// subpacket.
3165 ///
3166 /// A [Preferred Symmetric Algorithms subpacket] lists what
3167 /// symmetric algorithms the user prefers. When encrypting a
3168 /// message for a recipient, the OpenPGP implementation should not
3169 /// use an algorithm that is not on this list.
3170 ///
3171 /// [Preferred Symmetric Algorithms subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.14
3172 ///
3173 /// This subpacket is a type of preference. When looking up a
3174 /// preference, an OpenPGP implementation should first look for
3175 /// the subpacket on the binding signature of the User ID or the
3176 /// User Attribute used to locate the certificate (or the primary
3177 /// User ID, if it was addressed by Key ID or fingerprint). If
3178 /// the binding signature doesn't contain the subpacket, then the
3179 /// direct key signature should be checked. See the
3180 /// [`Preferences`] trait for details.
3181 ///
3182 /// Unless addressing different User IDs really should result in
3183 /// different behavior, it is best to only set this preference on
3184 /// the direct key signature. This guarantees that even if some
3185 /// or all User IDs are stripped, the behavior remains consistent.
3186 ///
3187 /// [`Preferences`]: crate::cert::Preferences
3188 ///
3189 /// If the subpacket is not present in the hashed subpacket area,
3190 /// this returns `None`.
3191 ///
3192 /// Note: if the signature contains multiple instances of this
3193 /// subpacket in the hashed subpacket area, the last one is
3194 /// returned.
3195 pub fn preferred_symmetric_algorithms(&self)
3196 -> Option<&[SymmetricAlgorithm]> {
3197 // array of one-octet values
3198 if let Some(sb)
3199 = self.subpacket(
3200 SubpacketTag::PreferredSymmetricAlgorithms) {
3201 if let SubpacketValue::PreferredSymmetricAlgorithms(v)
3202 = &sb.value {
3203 Some(v)
3204 } else {
3205 None
3206 }
3207 } else {
3208 None
3209 }
3210 }
3211
3212 /// Returns the value of the Preferred Hash Algorithms subpacket.
3213 ///
3214 /// A [Preferred Hash Algorithms subpacket] lists what hash
3215 /// algorithms the user prefers. When signing a message that
3216 /// should be verified by a particular recipient, the OpenPGP
3217 /// implementation should not use an algorithm that is not on this
3218 /// list.
3219 ///
3220 /// [Preferred Hash Algorithms subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.16
3221 ///
3222 /// This subpacket is a type of preference. When looking up a
3223 /// preference, an OpenPGP implementation should first look for
3224 /// the subpacket on the binding signature of the User ID or the
3225 /// User Attribute used to locate the certificate (or the primary
3226 /// User ID, if it was addressed by Key ID or fingerprint). If
3227 /// the binding signature doesn't contain the subpacket, then the
3228 /// direct key signature should be checked. See the
3229 /// [`Preferences`] trait for details.
3230 ///
3231 /// Unless addressing different User IDs really should result in
3232 /// different behavior, it is best to only set this preference on
3233 /// the direct key signature. This guarantees that even if some
3234 /// or all User IDs are stripped, the behavior remains consistent.
3235 ///
3236 /// [`Preferences`]: crate::cert::Preferences
3237 ///
3238 /// If the subpacket is not present in the hashed subpacket area,
3239 /// this returns `None`.
3240 ///
3241 /// Note: if the signature contains multiple instances of this
3242 /// subpacket in the hashed subpacket area, the last one is
3243 /// returned.
3244 pub fn preferred_hash_algorithms(&self) -> Option<&[HashAlgorithm]> {
3245 // array of one-octet values
3246 if let Some(sb)
3247 = self.subpacket(
3248 SubpacketTag::PreferredHashAlgorithms) {
3249 if let SubpacketValue::PreferredHashAlgorithms(v) = &sb.value {
3250 Some(v)
3251 } else {
3252 None
3253 }
3254 } else {
3255 None
3256 }
3257 }
3258
3259 /// Returns the value of the Preferred Compression Algorithms
3260 /// subpacket.
3261 ///
3262 /// A [Preferred Compression Algorithms subpacket] lists what
3263 /// compression algorithms the user prefers. When compressing a
3264 /// message for a recipient, the OpenPGP implementation should not
3265 /// use an algorithm that is not on the list.
3266 ///
3267 /// [Preferred Compression Algorithms subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.17
3268 ///
3269 /// This subpacket is a type of preference. When looking up a
3270 /// preference, an OpenPGP implementation should first for the
3271 /// subpacket on the binding signature of the User ID or the User
3272 /// Attribute used to locate the certificate (or the primary User
3273 /// ID, if it was addressed by Key ID or fingerprint). If the
3274 /// binding signature doesn't contain the subpacket, then the
3275 /// direct key signature should be checked. See the
3276 /// [`Preferences`] trait for details.
3277 ///
3278 /// Unless addressing different User IDs really should result in
3279 /// different behavior, it is best to only set this preference on
3280 /// the direct key signature. This guarantees that even if some
3281 /// or all User IDs are stripped, the behavior remains consistent.
3282 ///
3283 /// [`Preferences`]: crate::cert::Preferences
3284 ///
3285 /// If the subpacket is not present in the hashed subpacket area,
3286 /// this returns `None`.
3287 ///
3288 /// Note: if the signature contains multiple instances of this
3289 /// subpacket in the hashed subpacket area, the last one is
3290 /// returned.
3291 pub fn preferred_compression_algorithms(&self)
3292 -> Option<&[CompressionAlgorithm]>
3293 {
3294 // array of one-octet values
3295 if let Some(sb)
3296 = self.subpacket(
3297 SubpacketTag::PreferredCompressionAlgorithms) {
3298 if let SubpacketValue::PreferredCompressionAlgorithms(v)
3299 = &sb.value {
3300 Some(v)
3301 } else {
3302 None
3303 }
3304 } else {
3305 None
3306 }
3307 }
3308
3309 /// Returns the value of the Preferred AEAD Ciphersuites subpacket.
3310 ///
3311 /// The [Preferred AEAD Ciphersuites subpacket] indicates what
3312 /// AEAD ciphersuites (i.e. pairs of symmetric algorithm and AEAD
3313 /// algorithm) the key holder prefers ordered by preference. If
3314 /// this is set, then the SEIPDv2 feature flag should in the
3315 /// [Features subpacket] should also be set.
3316 ///
3317 /// [Preferred AEAD Ciphersuites subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-preferred-aead-ciphersuites
3318 /// [Features subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#features-subpacket
3319 ///
3320 /// This subpacket is a type of preference. When looking up a
3321 /// preference, an OpenPGP implementation should first look for
3322 /// the subpacket on the binding signature of the User ID or the
3323 /// User Attribute used to locate the certificate (or the primary
3324 /// User ID, if it was addressed by Key ID or fingerprint). If
3325 /// the binding signature doesn't contain the subpacket, then the
3326 /// direct key signature should be checked. See the
3327 /// [`Preferences`] trait for details.
3328 ///
3329 /// Unless addressing different User IDs really should result in
3330 /// different behavior, it is best to only set this preference on
3331 /// the direct key signature. This guarantees that even if some
3332 /// or all User IDs are stripped, the behavior remains consistent.
3333 ///
3334 /// [`Preferences`]: crate::cert::Preferences
3335 ///
3336 /// If the subpacket is not present in the hashed subpacket area,
3337 /// this returns `None`.
3338 ///
3339 /// Note: if the signature contains multiple instances of this
3340 /// subpacket in the hashed subpacket area, the last one is
3341 /// returned.
3342 pub fn preferred_aead_ciphersuites(&self)
3343 -> Option<&[(SymmetricAlgorithm, AEADAlgorithm)]>
3344 {
3345 if let Some(sb) = self.subpacket(
3346 SubpacketTag::PreferredAEADCiphersuites)
3347 {
3348 if let SubpacketValue::PreferredAEADCiphersuites(v)
3349 = &sb.value
3350 {
3351 Some(v)
3352 } else {
3353 None
3354 }
3355 } else {
3356 None
3357 }
3358 }
3359
3360 /// Returns the value of the Key Server Preferences subpacket.
3361 ///
3362 /// The [Key Server Preferences subpacket] indicates to key
3363 /// servers how they should handle the certificate.
3364 ///
3365 /// [Key Server Preferences subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.25
3366 ///
3367 /// This subpacket is a type of preference. When looking up a
3368 /// preference, an OpenPGP implementation should first for the
3369 /// subpacket on the binding signature of the User ID or the User
3370 /// Attribute used to locate the certificate (or the primary User
3371 /// ID, if it was addressed by Key ID or fingerprint). If the
3372 /// binding signature doesn't contain the subpacket, then the
3373 /// direct key signature should be checked. See the
3374 /// [`Preferences`] trait for details.
3375 ///
3376 /// Unless addressing different User IDs really should result in
3377 /// different behavior, it is best to only set this preference on
3378 /// the direct key signature. This guarantees that even if some
3379 /// or all User IDs are stripped, the behavior remains consistent.
3380 ///
3381 /// [`Preferences`]: crate::cert::Preferences
3382 ///
3383 /// If the subpacket is not present in the hashed subpacket area,
3384 /// this returns `None`.
3385 ///
3386 /// Note: if the signature contains multiple instances of this
3387 /// subpacket in the hashed subpacket area, the last one is
3388 /// returned.
3389 pub fn key_server_preferences(&self) -> Option<KeyServerPreferences> {
3390 // N octets of flags
3391 if let Some(sb) = self.subpacket(SubpacketTag::KeyServerPreferences) {
3392 if let SubpacketValue::KeyServerPreferences(v) = &sb.value {
3393 Some(v.clone())
3394 } else {
3395 None
3396 }
3397 } else {
3398 None
3399 }
3400 }
3401
3402 /// Returns the value of the Preferred Key Server subpacket.
3403 ///
3404 /// The [Preferred Key Server subpacket] contains a link to a key
3405 /// server where the certificate holder plans to publish updates
3406 /// to their certificate (e.g., extensions to the expiration time,
3407 /// new subkeys, revocation certificates).
3408 ///
3409 /// The Preferred Key Server subpacket should be handled
3410 /// cautiously, because it can be used by a certificate holder to
3411 /// track communication partners.
3412 ///
3413 /// [Preferred Key Server subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.26
3414 ///
3415 /// This subpacket is a type of preference. When looking up a
3416 /// preference, an OpenPGP implementation should first look for
3417 /// the subpacket on the binding signature of the User ID or the
3418 /// User Attribute used to locate the certificate (or the primary
3419 /// User ID, if it was addressed by Key ID or fingerprint). If
3420 /// the binding signature doesn't contain the subpacket, then the
3421 /// direct key signature should be checked. See the
3422 /// [`Preferences`] trait for details.
3423 ///
3424 /// Unless addressing different User IDs really should result in
3425 /// different behavior, it is best to only set this preference on
3426 /// the direct key signature. This guarantees that even if some
3427 /// or all User IDs are stripped, the behavior remains consistent.
3428 ///
3429 /// [`Preferences`]: crate::cert::Preferences
3430 ///
3431 /// If the subpacket is not present in the hashed subpacket area,
3432 /// this returns `None`.
3433 ///
3434 /// Note: if the signature contains multiple instances of this
3435 /// subpacket in the hashed subpacket area, the last one is
3436 /// returned.
3437 pub fn preferred_key_server(&self) -> Option<&[u8]> {
3438 // String
3439 if let Some(sb)
3440 = self.subpacket(SubpacketTag::PreferredKeyServer) {
3441 if let SubpacketValue::PreferredKeyServer(v) = &sb.value {
3442 Some(v)
3443 } else {
3444 None
3445 }
3446 } else {
3447 None
3448 }
3449 }
3450
3451 /// Returns the value of the Policy URI subpacket.
3452 ///
3453 /// The [Policy URI subpacket] contains a link to a policy document,
3454 /// which contains information about the conditions under which
3455 /// the signature was made.
3456 ///
3457 /// [Policy URI subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.28
3458 ///
3459 /// This subpacket is a type of preference. When looking up a
3460 /// preference, an OpenPGP implementation should first look for
3461 /// the subpacket on the binding signature of the User ID or the
3462 /// User Attribute used to locate the certificate (or the primary
3463 /// User ID, if it was addressed by Key ID or fingerprint). If
3464 /// the binding signature doesn't contain the subpacket, then the
3465 /// direct key signature should be checked. See the
3466 /// [`Preferences`] trait for details.
3467 ///
3468 /// Unless addressing different User IDs really should result in
3469 /// different behavior, it is best to only set this preference on
3470 /// the direct key signature. This guarantees that even if some
3471 /// or all User IDs are stripped, the behavior remains consistent.
3472 ///
3473 /// [`Preferences`]: crate::cert::Preferences
3474 ///
3475 /// If the subpacket is not present in the hashed subpacket area,
3476 /// this returns `None`.
3477 ///
3478 /// Note: if the signature contains multiple instances of this
3479 /// subpacket in the hashed subpacket area, the last one is
3480 /// returned.
3481 pub fn policy_uri(&self) -> Option<&[u8]> {
3482 // String
3483 if let Some(sb)
3484 = self.subpacket(SubpacketTag::PolicyURI) {
3485 if let SubpacketValue::PolicyURI(v) = &sb.value {
3486 Some(v)
3487 } else {
3488 None
3489 }
3490 } else {
3491 None
3492 }
3493 }
3494
3495 /// Returns the value of the Primary UserID subpacket.
3496 ///
3497 /// The [Primary User ID subpacket] indicates whether the
3498 /// associated User ID or User Attribute should be considered the
3499 /// primary User ID. It is possible that this is set on multiple
3500 /// User IDs. See the documentation for
3501 /// [`ValidCert::primary_userid`] for an explanation of how
3502 /// Sequoia resolves this ambiguity.
3503 ///
3504 /// [Primary User ID subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.27
3505 /// [`ValidCert::primary_userid`]: crate::cert::ValidCert::primary_userid()
3506 ///
3507 /// If the subpacket is not present in the hashed subpacket area,
3508 /// this returns `None`.
3509 ///
3510 /// Note: if the signature contains multiple instances of this
3511 /// subpacket in the hashed subpacket area, the last one is
3512 /// returned.
3513 pub fn primary_userid(&self) -> Option<bool> {
3514 // 1 octet, Boolean
3515 if let Some(sb)
3516 = self.subpacket(SubpacketTag::PrimaryUserID) {
3517 if let SubpacketValue::PrimaryUserID(v) = sb.value {
3518 Some(v)
3519 } else {
3520 None
3521 }
3522 } else {
3523 None
3524 }
3525 }
3526
3527 /// Returns the value of the Key Flags subpacket.
3528 ///
3529 /// The [Key Flags subpacket] describes a key's capabilities
3530 /// (certification capable, signing capable, etc.). In the case
3531 /// of subkeys, the Key Flags are located on the subkey's binding
3532 /// signature. For primary keys, locating the correct Key Flags
3533 /// subpacket is more complex: First, the primary User ID is
3534 /// consulted. If the primary User ID contains a Key Flags
3535 /// subpacket, that is used. Otherwise, any direct key signature
3536 /// is considered. If that still doesn't contain a Key Flags
3537 /// packet, then the primary key should be assumed to be
3538 /// certification capable.
3539 ///
3540 /// [Key Flags subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.29
3541 ///
3542 /// If the subpacket is not present in the hashed subpacket area,
3543 /// this returns `None`.
3544 ///
3545 /// Note: if the signature contains multiple instances of this
3546 /// subpacket in the hashed subpacket area, the last one is
3547 /// returned.
3548 pub fn key_flags(&self) -> Option<KeyFlags> {
3549 // N octets of flags
3550 if let Some(sb) = self.subpacket(SubpacketTag::KeyFlags) {
3551 if let SubpacketValue::KeyFlags(v) = &sb.value {
3552 Some(v.clone())
3553 } else {
3554 None
3555 }
3556 } else {
3557 None
3558 }
3559 }
3560
3561 /// Returns the value of the Signer's UserID subpacket.
3562 ///
3563 /// The [Signer's User ID subpacket] indicates, which User ID made
3564 /// the signature. This is useful when a key has multiple User
3565 /// IDs, which correspond to different roles. For instance, it is
3566 /// not uncommon to use the same certificate in private as well as
3567 /// for a club.
3568 ///
3569 /// [Signer's User ID subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.30
3570 ///
3571 /// If the subpacket is not present in the hashed subpacket area,
3572 /// this returns `None`.
3573 ///
3574 /// Note: if the signature contains multiple instances of this
3575 /// subpacket in the hashed subpacket area, the last one is
3576 /// returned.
3577 pub fn signers_user_id(&self) -> Option<&[u8]> {
3578 // String
3579 if let Some(sb)
3580 = self.subpacket(SubpacketTag::SignersUserID) {
3581 if let SubpacketValue::SignersUserID(v) = &sb.value {
3582 Some(v)
3583 } else {
3584 None
3585 }
3586 } else {
3587 None
3588 }
3589 }
3590
3591 /// Returns the value of the Reason for Revocation subpacket.
3592 ///
3593 /// The [Reason For Revocation subpacket] indicates why a key,
3594 /// User ID, or User Attribute is being revoked. It includes both
3595 /// a machine-readable code, and a human-readable string. The
3596 /// code is essential as it indicates to the OpenPGP
3597 /// implementation that reads the certificate whether the key was
3598 /// compromised (a hard revocation), or is no longer used (a soft
3599 /// revocation). In the former case, the OpenPGP implementation
3600 /// must conservatively consider all past signatures as suspect
3601 /// whereas in the latter case, past signatures can still be
3602 /// considered valid.
3603 ///
3604 /// [Reason For Revocation subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.31
3605 ///
3606 /// If the subpacket is not present in the hashed subpacket area,
3607 /// this returns `None`.
3608 ///
3609 /// Note: if the signature contains multiple instances of this
3610 /// subpacket in the hashed subpacket area, the last one is
3611 /// returned.
3612 pub fn reason_for_revocation(&self)
3613 -> Option<(ReasonForRevocation, &[u8])> {
3614 // 1 octet of revocation code, N octets of reason string
3615 if let Some(sb) = self.subpacket(SubpacketTag::ReasonForRevocation) {
3616 if let SubpacketValue::ReasonForRevocation {
3617 code, reason,
3618 } = &sb.value {
3619 Some((*code, reason))
3620 } else {
3621 None
3622 }
3623 } else {
3624 None
3625 }
3626 }
3627
3628 /// Returns the value of the Features subpacket.
3629 ///
3630 /// A [Features subpacket] lists what OpenPGP features the user
3631 /// wants to use. When creating a message, features that the
3632 /// intended recipients do not support should not be used.
3633 /// However, because this information is rarely held up to date in
3634 /// practice, this information is only advisory, and
3635 /// implementations are allowed to infer what features the
3636 /// recipients support from contextual clues, e.g., their past
3637 /// behavior.
3638 ///
3639 /// [Features subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.32
3640 /// [features]: crate::types::Features
3641 ///
3642 /// This subpacket is a type of preference. When looking up a
3643 /// preference, an OpenPGP implementation should first look for
3644 /// the subpacket on the binding signature of the User ID or the
3645 /// User Attribute used to locate the certificate (or the primary
3646 /// User ID, if it was addressed by Key ID or fingerprint). If
3647 /// the binding signature doesn't contain the subpacket, then the
3648 /// direct key signature should be checked. See the
3649 /// [`Preferences`] trait for details.
3650 ///
3651 /// Unless addressing different User IDs really should result in
3652 /// different behavior, it is best to only set this preference on
3653 /// the direct key signature. This guarantees that even if some
3654 /// or all User IDs are stripped, the behavior remains consistent.
3655 ///
3656 /// [`Preferences`]: crate::cert::Preferences
3657 ///
3658 /// If the subpacket is not present in the hashed subpacket area,
3659 /// this returns `None`.
3660 ///
3661 /// Note: if the signature contains multiple instances of this
3662 /// subpacket in the hashed subpacket area, the last one is
3663 /// returned.
3664 pub fn features(&self) -> Option<Features> {
3665 // N octets of flags
3666 if let Some(sb) = self.subpacket(SubpacketTag::Features) {
3667 if let SubpacketValue::Features(v) = &sb.value {
3668 Some(v.clone())
3669 } else {
3670 None
3671 }
3672 } else {
3673 None
3674 }
3675 }
3676
3677 /// Returns the value of the Signature Target subpacket.
3678 ///
3679 /// The [Signature Target subpacket] is used to identify the target
3680 /// of a signature. This is used when revoking a signature, and
3681 /// by timestamp signatures. It contains a hash of the target
3682 /// signature.
3683 ///
3684 /// [Signature Target subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.33
3685 ///
3686 /// If the subpacket is not present in the hashed subpacket area,
3687 /// this returns `None`.
3688 ///
3689 /// Note: if the signature contains multiple instances of this
3690 /// subpacket in the hashed subpacket area, the last one is
3691 /// returned.
3692 pub fn signature_target(&self) -> Option<(PublicKeyAlgorithm,
3693 HashAlgorithm,
3694 &[u8])> {
3695 // 1 octet public-key algorithm, 1 octet hash algorithm, N
3696 // octets hash
3697 if let Some(sb) = self.subpacket(SubpacketTag::SignatureTarget) {
3698 if let SubpacketValue::SignatureTarget {
3699 pk_algo, hash_algo, digest,
3700 } = &sb.value {
3701 Some((*pk_algo, *hash_algo, digest))
3702 } else {
3703 None
3704 }
3705 } else {
3706 None
3707 }
3708 }
3709
3710 /// Returns references to all Embedded Signature subpackets.
3711 ///
3712 /// The [Embedded Signature subpacket] is normally used to hold a
3713 /// [Primary Key Binding signature], which binds a
3714 /// signing-capable, authentication-capable, or
3715 /// certification-capable subkey to the primary key. Since this
3716 /// information is self-authenticating, it is usually stored in
3717 /// the unhashed subpacket area.
3718 ///
3719 /// [Embedded Signature subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.34
3720 /// [Primary Key Binding signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
3721 ///
3722 /// If the subpacket is not present in the hashed subpacket area
3723 /// or in the unhashed subpacket area, this returns `None`.
3724 ///
3725 /// Note: if the signature contains multiple instances of this
3726 /// subpacket in the hashed subpacket area, the last one is
3727 /// returned. Otherwise, the last one is returned from the
3728 /// unhashed subpacket area.
3729 pub fn embedded_signatures(&self)
3730 -> impl Iterator<Item = &Signature> + Send + Sync
3731 {
3732 self.subpackets(SubpacketTag::EmbeddedSignature).map(|sb| {
3733 if let SubpacketValue::EmbeddedSignature(v) = &sb.value {
3734 v
3735 } else {
3736 unreachable!(
3737 "subpackets(EmbeddedSignature) returns EmbeddedSignatures"
3738 );
3739 }
3740 })
3741 }
3742
3743 /// Returns mutable references to all Embedded Signature subpackets.
3744 ///
3745 /// The [Embedded Signature subpacket] is normally used to hold a
3746 /// [Primary Key Binding signature], which binds a
3747 /// signing-capable, authentication-capable, or
3748 /// certification-capable subkey to the primary key. Since this
3749 /// information is self-authenticating, it is usually stored in
3750 /// the unhashed subpacket area.
3751 ///
3752 /// [Embedded Signature subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.34
3753 /// [Primary Key Binding signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
3754 ///
3755 /// If the subpacket is not present in the hashed subpacket area
3756 /// or in the unhashed subpacket area, this returns `None`.
3757 ///
3758 /// Note: if the signature contains multiple instances of this
3759 /// subpacket in the hashed subpacket area, the last one is
3760 /// returned. Otherwise, the last one is returned from the
3761 /// unhashed subpacket area.
3762 pub fn embedded_signatures_mut(&mut self)
3763 -> impl Iterator<Item = &mut Signature> + Send + Sync
3764 {
3765 self.subpackets_mut(SubpacketTag::EmbeddedSignature).map(|sb| {
3766 if let SubpacketValue::EmbeddedSignature(v) = &mut sb.value {
3767 v
3768 } else {
3769 unreachable!(
3770 "subpackets_mut(EmbeddedSignature) returns EmbeddedSignatures"
3771 );
3772 }
3773 })
3774 }
3775
3776 /// Returns the intended recipients.
3777 ///
3778 /// The [Intended Recipient subpacket] holds the fingerprint of a
3779 /// certificate.
3780 ///
3781 /// [Intended Recipient subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-intended-recipient-fingerpr
3782 ///
3783 /// When signing a message, the message should include one such
3784 /// subpacket for each intended recipient. Note: not all messages
3785 /// have intended recipients. For instance, when signing an open
3786 /// letter, or a software release, the message is intended for
3787 /// anyone.
3788 ///
3789 /// When processing a signature, the application should ensure
3790 /// that if there are any such subpackets, then one of the
3791 /// subpackets identifies the recipient's certificate (or user
3792 /// signed the message). If this is not the case, then an
3793 /// attacker may have taken the message out of its original
3794 /// context. For instance, if Alice sends a signed email to Bob,
3795 /// with the content: "I agree to the contract", and Bob forwards
3796 /// that message to Carol, then Carol may think that Alice agreed
3797 /// to a contract with her if the signature appears to be valid!
3798 /// By adding an intended recipient, it is possible for Carol's
3799 /// mail client to warn her that although Alice signed the
3800 /// message, the content was intended for Bob and not for her.
3801 ///
3802 /// This returns all instances of the Intended Recipient subpacket
3803 /// in the hashed subpacket area.
3804 pub fn intended_recipients(&self)
3805 -> impl Iterator<Item=&Fingerprint> + Send + Sync
3806 {
3807 self.subpackets(SubpacketTag::IntendedRecipient)
3808 .map(|sb| {
3809 match sb.value() {
3810 SubpacketValue::IntendedRecipient(ref fp) => fp,
3811 _ => unreachable!(),
3812 }
3813 })
3814 }
3815
3816 /// Returns the digests of approved certifications.
3817 ///
3818 /// This feature is [experimental](crate#experimental-features).
3819 ///
3820 /// Allows the certificate holder to attest to third party
3821 /// certifications, allowing them to be distributed with the
3822 /// certificate. This can be used to address certificate flooding
3823 /// concerns.
3824 ///
3825 /// Note: The maximum size of the hashed signature subpacket area
3826 /// constrains the number of attestations that can be stored in a
3827 /// signature. If the certificate holder approved of more
3828 /// certifications, the digests are split across multiple approved
3829 /// certification key signatures with the same creation time.
3830 ///
3831 /// The standard strongly suggests that the digests should be
3832 /// sorted. However, this function returns the digests in the
3833 /// order they are stored in the subpacket, which may not be
3834 /// sorted.
3835 ///
3836 /// To address both issues, collect all digests from all approved
3837 /// key signatures with the most recent creation time into a data
3838 /// structure that allows efficient lookups, such as [`HashSet`]
3839 /// or [`BTreeSet`].
3840 ///
3841 /// See [Section 2.2 of draft-dkg-openpgp-1pa3pc-02] for details.
3842 ///
3843 /// [`HashSet`]: std::collections::HashSet
3844 /// [`BTreeSet`]: std::collections::BTreeSet
3845 /// [Section 2.2 of draft-dkg-openpgp-1pa3pc-02]: https://www.ietf.org/archive/id/draft-dkg-openpgp-1pa3pc-02.html#approved-certifications-subpacket
3846 pub fn approved_certifications(&self)
3847 -> Result<impl Iterator<Item=&[u8]> + Send + Sync>
3848 {
3849 if self.hashed_area()
3850 .subpackets(SubpacketTag::ApprovedCertifications).count() > 1
3851 || self.unhashed_area()
3852 .subpackets(SubpacketTag::ApprovedCertifications).count() != 0
3853 {
3854 return Err(Error::BadSignature(
3855 "Wrong number of approved certifications subpackets".into())
3856 .into());
3857 }
3858
3859 Ok(self.subpackets(SubpacketTag::ApprovedCertifications)
3860 .flat_map(|sb| {
3861 match sb.value() {
3862 SubpacketValue::ApprovedCertifications(digests) =>
3863 digests.iter().map(|d| d.as_ref()),
3864 _ => unreachable!(),
3865 }
3866 }))
3867 }
3868}
3869
3870impl TryFrom<Signature> for Signature4 {
3871 type Error = anyhow::Error;
3872
3873 fn try_from(sig: Signature) -> Result<Self> {
3874 match sig {
3875 Signature::V4(sig) => Ok(sig),
3876 sig => Err(
3877 Error::InvalidArgument(
3878 format!(
3879 "Got a v{}, require a v4 signature",
3880 sig.version()))
3881 .into()),
3882 }
3883 }
3884}
3885
3886impl Deref for Signature4 {
3887 type Target = signature::SignatureFields;
3888
3889 fn deref(&self) -> &Self::Target {
3890 &self.fields
3891 }
3892}
3893
3894impl DerefMut for Signature4 {
3895 fn deref_mut(&mut self) -> &mut Self::Target {
3896 &mut self.fields
3897 }
3898}
3899
3900impl signature::SignatureBuilder {
3901 /// Modifies the unhashed subpacket area.
3902 ///
3903 /// This method provides a builder-style interface for modifying
3904 /// the unhashed subpacket area.
3905 ///
3906 /// Normally, to modify a subpacket area in a non-standard way
3907 /// (that is, when there are no subpacket-specific function like
3908 /// [`SignatureBuilder::set_signature_validity_period`] that
3909 /// implement the required functionality), you need to do
3910 /// something like the following:
3911 ///
3912 /// [`SignatureBuilder::set_signature_validity_period`]: super::SignatureBuilder::set_signature_validity_period()
3913 ///
3914 /// ```
3915 /// # use sequoia_openpgp as openpgp;
3916 /// # use openpgp::types::Curve;
3917 /// # use openpgp::cert::prelude::*;
3918 /// # use openpgp::packet::prelude::*;
3919 /// # use openpgp::packet::signature::subpacket::{
3920 /// # Subpacket,
3921 /// # SubpacketTag,
3922 /// # SubpacketValue,
3923 /// # };
3924 /// # use openpgp::types::SignatureType;
3925 /// #
3926 /// # fn main() -> openpgp::Result<()> {
3927 /// #
3928 /// # let key: Key<key::SecretParts, key::PrimaryRole>
3929 /// # = Key6::generate_ecc(true, Curve::Ed25519)?.into();
3930 /// # let mut signer = key.into_keypair()?;
3931 /// # let msg = b"Hello, World";
3932 /// #
3933 /// let mut builder = SignatureBuilder::new(SignatureType::Binary)
3934 /// // Build up the signature.
3935 /// ;
3936 /// builder.unhashed_area_mut().add(Subpacket::new(
3937 /// SubpacketValue::Unknown {
3938 /// tag: SubpacketTag::Private(61),
3939 /// body: [0x6D, 0x6F, 0x6F].to_vec(),
3940 /// },
3941 /// true)?)?;
3942 /// let sig = builder.sign_message(&mut signer, msg)?;
3943 /// # let mut sig = sig;
3944 /// # sig.verify_message(signer.public(), msg)?;
3945 /// # Ok(()) }
3946 /// ```
3947 ///
3948 /// This is necessary, because modifying the subpacket area
3949 /// doesn't follow the builder pattern like the surrounding code.
3950 /// Using this function, you can instead do:
3951 ///
3952 /// ```
3953 /// # use sequoia_openpgp as openpgp;
3954 /// # use openpgp::cert::prelude::*;
3955 /// # use openpgp::packet::prelude::*;
3956 /// # use openpgp::packet::signature::subpacket::{
3957 /// # Subpacket,
3958 /// # SubpacketTag,
3959 /// # SubpacketValue,
3960 /// # };
3961 /// # use openpgp::types::Curve;
3962 /// # use openpgp::types::SignatureType;
3963 /// #
3964 /// # fn main() -> openpgp::Result<()> {
3965 /// #
3966 /// # let key: Key<key::SecretParts, key::PrimaryRole>
3967 /// # = Key6::generate_ecc(true, Curve::Ed25519)?.into();
3968 /// # let mut signer = key.into_keypair()?;
3969 /// # let msg = b"Hello, World";
3970 /// #
3971 /// let sig = SignatureBuilder::new(SignatureType::Binary)
3972 /// // Call some setters.
3973 /// .modify_unhashed_area(|mut a| {
3974 /// a.add(Subpacket::new(
3975 /// SubpacketValue::Unknown {
3976 /// tag: SubpacketTag::Private(61),
3977 /// body: [0x6D, 0x6F, 0x6F].to_vec(),
3978 /// },
3979 /// true)?);
3980 /// Ok(a)
3981 /// })?
3982 /// .sign_message(&mut signer, msg)?;
3983 /// # let mut sig = sig;
3984 /// # sig.verify_message(signer.public(), msg)?;
3985 /// # Ok(()) }
3986 /// ```
3987 ///
3988 /// If you are only interested in modifying an existing
3989 /// signature's unhashed area, it may be better to simply modify
3990 /// the signature in place using
3991 /// [`SignatureBuilder::modify_unhashed_area`] rather than to create a
3992 /// new signature, because modifying the unhashed area doesn't
3993 /// invalidate any existing signature.
3994 ///
3995 /// [`SignatureBuilder::modify_unhashed_area`]: super::SignatureBuilder::modify_unhashed_area
3996 ///
3997 /// # Examples
3998 ///
3999 /// Create a signature with a custom, non-critical subpacket in
4000 /// the unhashed area:
4001 ///
4002 /// ```
4003 /// use sequoia_openpgp as openpgp;
4004 /// use openpgp::cert::prelude::*;
4005 /// use openpgp::packet::prelude::*;
4006 /// use openpgp::packet::signature::subpacket::{
4007 /// Subpacket,
4008 /// SubpacketTag,
4009 /// SubpacketValue,
4010 /// };
4011 /// use openpgp::types::SignatureType;
4012 /// #
4013 /// # fn main() -> openpgp::Result<()> {
4014 ///
4015 /// let (cert, _) =
4016 /// CertBuilder::general_purpose(Some("alice@example.org"))
4017 /// .generate()?;
4018 /// let mut signer = cert.primary_key().key().clone().parts_into_secret()?.into_keypair()?;
4019 ///
4020 /// let msg = b"Hello, World";
4021 ///
4022 /// let sig = SignatureBuilder::new(SignatureType::Binary)
4023 /// // Call some setters.
4024 /// .modify_unhashed_area(|mut a| {
4025 /// a.add(Subpacket::new(
4026 /// SubpacketValue::Unknown {
4027 /// tag: SubpacketTag::Private(61),
4028 /// body: [0x6D, 0x6F, 0x6F].to_vec(),
4029 /// },
4030 /// true)?);
4031 /// Ok(a)
4032 /// })?
4033 /// .sign_message(&mut signer, msg)?;
4034 /// # let mut sig = sig;
4035 /// # sig.verify_message(signer.public(), msg)?;
4036 /// # Ok(()) }
4037 /// ```
4038 pub fn modify_unhashed_area<F>(mut self, f: F)
4039 -> Result<Self>
4040 where F: FnOnce(SubpacketArea) -> Result<SubpacketArea>
4041 {
4042 self.fields.subpackets.unhashed_area
4043 = f(self.fields.subpackets.unhashed_area)?;
4044 Ok(self)
4045 }
4046
4047 /// Modifies the hashed subpacket area.
4048 ///
4049 /// This method provides a builder-style interface for modifying
4050 /// the hashed subpacket area.
4051 ///
4052 /// Normally, to modify a subpacket area in a non-standard way
4053 /// (that is, when there are no subpacket-specific function like
4054 /// [`SignatureBuilder::set_signature_validity_period`] that
4055 /// implement the required functionality), you need to do
4056 /// something like the following:
4057 ///
4058 /// [`SignatureBuilder::set_signature_validity_period`]: super::SignatureBuilder::set_signature_validity_period()
4059 ///
4060 /// ```
4061 /// # use sequoia_openpgp as openpgp;
4062 /// # use openpgp::types::Curve;
4063 /// # use openpgp::cert::prelude::*;
4064 /// # use openpgp::packet::prelude::*;
4065 /// # use openpgp::packet::signature::subpacket::{
4066 /// # Subpacket,
4067 /// # SubpacketTag,
4068 /// # SubpacketValue,
4069 /// # };
4070 /// # use openpgp::types::SignatureType;
4071 /// #
4072 /// # fn main() -> openpgp::Result<()> {
4073 /// #
4074 /// # let key: Key<key::SecretParts, key::PrimaryRole>
4075 /// # = Key6::generate_ecc(true, Curve::Ed25519)?.into();
4076 /// # let mut signer = key.into_keypair()?;
4077 /// # let msg = b"Hello, World";
4078 /// #
4079 /// let mut builder = SignatureBuilder::new(SignatureType::Binary)
4080 /// // Build up the signature.
4081 /// ;
4082 /// builder.hashed_area_mut().add(Subpacket::new(
4083 /// SubpacketValue::Unknown {
4084 /// tag: SubpacketTag::Private(61),
4085 /// body: [0x6D, 0x6F, 0x6F].to_vec(),
4086 /// },
4087 /// true)?)?;
4088 /// let sig = builder.sign_message(&mut signer, msg)?;
4089 /// # let mut sig = sig;
4090 /// # sig.verify_message(signer.public(), msg)?;
4091 /// # Ok(()) }
4092 /// ```
4093 ///
4094 /// This is necessary, because modifying the subpacket area
4095 /// doesn't follow the builder pattern like the surrounding code.
4096 /// Using this function, you can instead do:
4097 ///
4098 /// ```
4099 /// # use sequoia_openpgp as openpgp;
4100 /// # use openpgp::cert::prelude::*;
4101 /// # use openpgp::packet::prelude::*;
4102 /// # use openpgp::packet::signature::subpacket::{
4103 /// # Subpacket,
4104 /// # SubpacketTag,
4105 /// # SubpacketValue,
4106 /// # };
4107 /// # use openpgp::types::Curve;
4108 /// # use openpgp::types::SignatureType;
4109 /// #
4110 /// # fn main() -> openpgp::Result<()> {
4111 /// #
4112 /// # let key: Key<key::SecretParts, key::PrimaryRole>
4113 /// # = Key6::generate_ecc(true, Curve::Ed25519)?.into();
4114 /// # let mut signer = key.into_keypair()?;
4115 /// # let msg = b"Hello, World";
4116 /// #
4117 /// let sig = SignatureBuilder::new(SignatureType::Binary)
4118 /// // Call some setters.
4119 /// .modify_hashed_area(|mut a| {
4120 /// a.add(Subpacket::new(
4121 /// SubpacketValue::Unknown {
4122 /// tag: SubpacketTag::Private(61),
4123 /// body: [0x6D, 0x6F, 0x6F].to_vec(),
4124 /// },
4125 /// true)?);
4126 /// Ok(a)
4127 /// })?
4128 /// .sign_message(&mut signer, msg)?;
4129 /// # let mut sig = sig;
4130 /// # sig.verify_message(signer.public(), msg)?;
4131 /// # Ok(()) }
4132 /// ```
4133 ///
4134 /// # Examples
4135 ///
4136 /// Add a critical, custom subpacket to a certificate's direct key
4137 /// signature:
4138 ///
4139 /// ```
4140 /// use sequoia_openpgp as openpgp;
4141 /// use openpgp::cert::prelude::*;
4142 /// use openpgp::packet::prelude::*;
4143 /// use openpgp::packet::signature::subpacket::{
4144 /// Subpacket,
4145 /// SubpacketTag,
4146 /// SubpacketValue,
4147 /// };
4148 /// use openpgp::policy::StandardPolicy;
4149 /// use openpgp::types::Features;
4150 ///
4151 /// # fn main() -> openpgp::Result<()> {
4152 /// let p = &StandardPolicy::new();
4153 ///
4154 /// let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
4155 ///
4156 /// // Derive a signer (the primary key is always certification capable).
4157 /// let pk = cert.primary_key().key();
4158 /// let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;
4159 ///
4160 /// let vc = cert.with_policy(p, None)?;
4161 ///
4162 /// let sig = vc.direct_key_signature().expect("direct key signature");
4163 /// let sig = SignatureBuilder::from(sig.clone())
4164 /// .modify_hashed_area(|mut a| {
4165 /// a.add(Subpacket::new(
4166 /// SubpacketValue::Unknown {
4167 /// tag: SubpacketTag::Private(61),
4168 /// body: [0x6D, 0x6F, 0x6F].to_vec(),
4169 /// },
4170 /// true)?)?;
4171 /// Ok(a)
4172 /// })?
4173 /// .sign_direct_key(&mut signer, None)?;
4174 ///
4175 /// // Merge in the new signature.
4176 /// let cert = cert.insert_packets(sig)?.0;
4177 /// # assert_eq!(cert.bad_signatures().count(), 0);
4178 /// # Ok(())
4179 /// # }
4180 /// ```
4181 ///
4182 /// Update a certificate's feature set by updating the `Features`
4183 /// subpacket on any direct key signature, and any User ID binding
4184 /// signatures:
4185 ///
4186 /// ```
4187 /// use sequoia_openpgp as openpgp;
4188 /// use openpgp::cert::prelude::*;
4189 /// use openpgp::packet::prelude::*;
4190 /// use openpgp::packet::signature::subpacket::{Subpacket, SubpacketValue};
4191 /// use openpgp::policy::StandardPolicy;
4192 /// use openpgp::types::Features;
4193 ///
4194 /// # fn main() -> openpgp::Result<()> {
4195 /// let p = &StandardPolicy::new();
4196 ///
4197 /// let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
4198 ///
4199 /// // Derive a signer (the primary key is always certification capable).
4200 /// let pk = cert.primary_key().key();
4201 /// let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;
4202 ///
4203 /// let mut sigs = Vec::new();
4204 ///
4205 /// let vc = cert.with_policy(p, None)?;
4206 ///
4207 /// if let Ok(sig) = vc.direct_key_signature() {
4208 /// sigs.push(SignatureBuilder::from(sig.clone())
4209 /// .modify_hashed_area(|mut a| {
4210 /// a.replace(Subpacket::new(
4211 /// SubpacketValue::Features(Features::sequoia().set(10)),
4212 /// false)?)?;
4213 /// Ok(a)
4214 /// })?
4215 /// // Update the direct key signature.
4216 /// .sign_direct_key(&mut signer, Some(pk))?);
4217 /// }
4218 ///
4219 /// for ua in vc.userids() {
4220 /// sigs.push(SignatureBuilder::from(ua.binding_signature().clone())
4221 /// .modify_hashed_area(|mut a| {
4222 /// a.replace(Subpacket::new(
4223 /// SubpacketValue::Features(Features::sequoia().set(10)),
4224 /// false)?)?;
4225 /// Ok(a)
4226 /// })?
4227 /// // Update the binding signature.
4228 /// .sign_userid_binding(&mut signer, pk, ua.userid())?);
4229 /// }
4230 ///
4231 /// // Merge in the new signatures.
4232 /// let cert = cert.insert_packets(sigs)?.0;
4233 /// # assert_eq!(cert.bad_signatures().count(), 0);
4234 /// # Ok(())
4235 /// # }
4236 /// ```
4237 pub fn modify_hashed_area<F>(mut self, f: F)
4238 -> Result<Self>
4239 where F: FnOnce(SubpacketArea) -> Result<SubpacketArea>
4240 {
4241 self.fields.subpackets.hashed_area
4242 = f(self.fields.subpackets.hashed_area)?;
4243 Ok(self)
4244 }
4245
4246 /// Sets the Signature Creation Time subpacket.
4247 ///
4248 /// Adds a [Signature Creation Time subpacket] to the hashed
4249 /// subpacket area. This function first removes any Signature
4250 /// Creation Time subpacket from the hashed subpacket area.
4251 ///
4252 /// The Signature Creation Time subpacket specifies when the
4253 /// signature was created. According to the standard, all
4254 /// signatures must include a Signature Creation Time subpacket in
4255 /// the signature's hashed area. This doesn't mean that the time
4256 /// stamp is correct: the issuer can always forge it.
4257 ///
4258 /// When creating a signature using a SignatureBuilder or the
4259 /// [streaming `Signer`], it is not necessary to explicitly set
4260 /// this subpacket: those functions automatically set the
4261 /// signature creation time, if it has not been set explicitly.
4262 ///
4263 /// [Signature Creation Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
4264 /// [streaming `Signer`]: crate::serialize::stream::Signer
4265 ///
4266 /// # Examples
4267 ///
4268 /// Create a backdated signature:
4269 ///
4270 /// ```
4271 /// use sequoia_openpgp as openpgp;
4272 /// use openpgp::cert::prelude::*;
4273 /// use openpgp::packet::signature::SignatureBuilder;
4274 /// use openpgp::types::SignatureType;
4275 ///
4276 /// # fn main() -> openpgp::Result<()> {
4277 /// #
4278 /// # let (cert, _) =
4279 /// # CertBuilder::general_purpose(Some("alice@example.org"))
4280 /// # // We also need to backdate the certificate.
4281 /// # .set_creation_time(
4282 /// # std::time::SystemTime::now()
4283 /// # - std::time::Duration::new(2 * 24 * 60 * 60, 0))
4284 /// # .generate()?;
4285 /// # let mut signer = cert.primary_key().key().clone()
4286 /// # .parts_into_secret()?.into_keypair()?;
4287 /// let msg = "hiermit kündige ich den mit Ihnen bestehenden Vertrag fristgerecht.";
4288 ///
4289 /// let mut sig = SignatureBuilder::new(SignatureType::Binary)
4290 /// .set_signature_creation_time(
4291 /// std::time::SystemTime::now()
4292 /// - std::time::Duration::new(24 * 60 * 60, 0))?
4293 /// .sign_message(&mut signer, msg)?;
4294 ///
4295 /// assert!(sig.verify_message(signer.public(), msg).is_ok());
4296 /// # Ok(()) }
4297 /// ```
4298 pub fn set_signature_creation_time<T>(mut self, creation_time: T)
4299 -> Result<Self>
4300 where T: Into<time::SystemTime>
4301 {
4302 self.hashed_area.replace(Subpacket::new(
4303 SubpacketValue::SignatureCreationTime(
4304 creation_time.into().try_into()?),
4305 true)?)?;
4306
4307 self.overrode_creation_time = true;
4308 Ok(self)
4309 }
4310
4311 /// Causes the builder to use an existing signature creation time
4312 /// subpacket.
4313 ///
4314 /// When converting a [`Signature`] to a `SignatureBuilder`, the
4315 /// [Signature Creation Time subpacket] is removed from the hashed
4316 /// area, and saved internally. When creating the signature, a
4317 /// Signature Creation Time subpacket with the current time is
4318 /// normally added to the hashed area. Calling this function
4319 /// instead causes the signature generation code to use the cached
4320 /// `Signature Creation Time` subpacket.
4321 ///
4322 /// [`Signature`]: super::Signature
4323 /// [Signature Creation Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
4324 ///
4325 /// This function returns an error if there is no cached
4326 /// `Signature Creation Time` subpacket.
4327 ///
4328 /// # Examples
4329 ///
4330 /// Alice signs a message. Shortly thereafter, Bob signs the
4331 /// message using a nearly identical Signature packet:
4332 ///
4333 /// ```
4334 /// use sequoia_openpgp as openpgp;
4335 /// # use openpgp::cert::prelude::*;
4336 /// use openpgp::packet::signature::SignatureBuilder;
4337 /// use openpgp::types::SignatureType;
4338 ///
4339 /// # fn main() -> openpgp::Result<()> {
4340 /// #
4341 /// # let (alice, _) =
4342 /// # CertBuilder::general_purpose(Some("alice@example.org"))
4343 /// # .generate()?;
4344 /// # let mut alices_signer = alice.primary_key().key().clone()
4345 /// # .parts_into_secret()?.into_keypair()?;
4346 /// # let (bob, _) =
4347 /// # CertBuilder::general_purpose(Some("bob@example.org"))
4348 /// # .generate()?;
4349 /// # let mut bobs_signer = bob.primary_key().key().clone()
4350 /// # .parts_into_secret()?.into_keypair()?;
4351 /// let msg = "Version 489 of Foo has the SHA256 sum e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
4352 ///
4353 /// let siga = SignatureBuilder::new(SignatureType::Binary)
4354 /// .sign_message(&mut alices_signer, msg)?;
4355 /// let sigb = SignatureBuilder::from(siga.clone())
4356 /// .preserve_signature_creation_time()?
4357 /// .sign_message(&mut bobs_signer, msg)?;
4358 /// #
4359 /// # let mut siga = siga;
4360 /// # let mut sigb = sigb;
4361 /// # assert!(siga.verify_message(alices_signer.public(), msg).is_ok());
4362 /// # assert!(sigb.verify_message(bobs_signer.public(), msg).is_ok());
4363 /// # assert_eq!(siga.signature_creation_time(),
4364 /// # sigb.signature_creation_time());
4365 /// # Ok(()) }
4366 /// ```
4367 pub fn preserve_signature_creation_time(self)
4368 -> Result<Self>
4369 {
4370 if let Some(t) = self.original_creation_time {
4371 self.set_signature_creation_time(t)
4372 } else {
4373 Err(Error::InvalidOperation(
4374 "Signature does not contain a Signature Creation Time subpacket".into())
4375 .into())
4376 }
4377 }
4378
4379 /// Causes the builder to not output a Signature Creation Time
4380 /// subpacket.
4381 ///
4382 /// When creating a signature, a [Signature Creation Time
4383 /// subpacket] is added to the hashed area if one hasn't been
4384 /// added already. This function suppresses that behavior.
4385 ///
4386 /// [Signature Creation Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
4387 ///
4388 /// [Section 5.2.3.11 of RFC 9580] says that the `Signature
4389 /// Creation Time` subpacket must be present in the hashed area.
4390 /// This function clears any `Signature Creation Time` subpackets
4391 /// from both the hashed area and the unhashed area, and causes
4392 /// the various `SignatureBuilder` finalizers to not emit a
4393 /// `Signature Creation Time` subpacket. This function should
4394 /// only be used for generating test data.
4395 ///
4396 /// [Section 5.2.3.11 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
4397 ///
4398 /// # Examples
4399 ///
4400 /// Create a signature without a Signature Creation Time
4401 /// subpacket. As per the specification, Sequoia considers such
4402 /// signatures to be invalid:
4403 ///
4404 /// ```
4405 /// use sequoia_openpgp as openpgp;
4406 /// use openpgp::cert::prelude::*;
4407 /// use openpgp::packet::signature::SignatureBuilder;
4408 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
4409 /// use openpgp::types::SignatureType;
4410 ///
4411 /// # fn main() -> openpgp::Result<()> {
4412 /// #
4413 /// # let (cert, _) =
4414 /// # CertBuilder::general_purpose(Some("alice@example.org"))
4415 /// # .generate()?;
4416 /// # let mut signer = cert.primary_key().key().clone()
4417 /// # .parts_into_secret()?.into_keypair()?;
4418 /// let msg = "Some things are timeless.";
4419 ///
4420 /// let mut sig = SignatureBuilder::new(SignatureType::Binary)
4421 /// .suppress_signature_creation_time()?
4422 /// .sign_message(&mut signer, msg)?;
4423 ///
4424 /// assert!(sig.verify_message(signer.public(), msg).is_err());
4425 /// # assert_eq!(sig
4426 /// # .hashed_area()
4427 /// # .iter()
4428 /// # .filter(|sp| sp.tag() == SubpacketTag::SignatureCreationTime)
4429 /// # .count(),
4430 /// # 0);
4431 /// # Ok(()) }
4432 /// ```
4433 pub fn suppress_signature_creation_time(mut self)
4434 -> Result<Self>
4435 {
4436 self.hashed_area.remove_all(SubpacketTag::SignatureCreationTime);
4437 self.unhashed_area.remove_all(SubpacketTag::SignatureCreationTime);
4438
4439 self.overrode_creation_time = true;
4440 Ok(self)
4441 }
4442
4443 /// Returns the value of the Signature Expiration Time subpacket
4444 /// as an absolute time.
4445 ///
4446 /// A [Signature Expiration Time subpacket] specifies when the
4447 /// signature expires. The value stored is not an absolute time,
4448 /// but a duration, which is relative to the Signature's creation
4449 /// time. To better reflect the subpacket's name, this method
4450 /// returns the absolute expiry time, and the
4451 /// [`SubpacketAreas::signature_validity_period`] method returns
4452 /// the subpacket's raw value.
4453 ///
4454 /// [Signature Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.18
4455 /// [`SubpacketAreas::signature_validity_period`]: SubpacketAreas::signature_validity_period()
4456 ///
4457 /// The Signature Expiration Time subpacket is different from the
4458 /// [Key Expiration Time subpacket], which is accessed using
4459 /// [`SubpacketAreas::key_validity_period`], and used specifies
4460 /// when an associated key expires. The difference is that in the
4461 /// former case, the signature itself expires, but in the latter
4462 /// case, only the associated key expires. This difference is
4463 /// critical: if a binding signature expires, then an OpenPGP
4464 /// implementation will still consider the associated key to be
4465 /// valid if there is another valid binding signature, even if it
4466 /// is older than the expired signature; if the active binding
4467 /// signature indicates that the key has expired, then OpenPGP
4468 /// implementations will not fall back to an older binding
4469 /// signature.
4470 ///
4471 /// [Key Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
4472 /// [`SubpacketAreas::key_validity_period`]: SubpacketAreas::key_validity_period()
4473 ///
4474 /// There are several cases where having a signature expire is
4475 /// useful. Say Alice certifies Bob's certificate for
4476 /// `bob@example.org`. She can limit the lifetime of the
4477 /// certification to force her to reevaluate the certification
4478 /// shortly before it expires. For instance, is Bob still
4479 /// associated with `example.org`? Does she have reason to
4480 /// believe that his key has been compromised? Using an
4481 /// expiration is common in the X.509 ecosystem. For instance,
4482 /// [Let's Encrypt] issues certificates with 90-day lifetimes.
4483 ///
4484 /// [Let's Encrypt]: https://letsencrypt.org/2015/11/09/why-90-days.html
4485 ///
4486 /// Having signatures expire can also be useful when deploying
4487 /// software. For instance, you might have a service that
4488 /// installs an update if it has been signed by a trusted
4489 /// certificate. To prevent an adversary from coercing the
4490 /// service to install an older version, you could limit the
4491 /// signature's lifetime to just a few minutes.
4492 ///
4493 /// If the subpacket is not present in the hashed subpacket area,
4494 /// this returns `None`. If this function returns `None`, the
4495 /// signature does not expire.
4496 ///
4497 /// Note: if the signature contains multiple instances of this
4498 /// subpacket in the hashed subpacket area, the last one is
4499 /// returned.
4500 // Note: This shadows SubpacketAreas::signature_expiration_time
4501 // (SignatureBuilder derefs to SubpacketAreas), because we need to
4502 // take SignatureBuilder::reference_time into account.
4503 //
4504 // If you update this function, also update
4505 // SubpacketAreas::signature_expiration_time.
4506 pub fn signature_expiration_time(&self) -> Option<time::SystemTime> {
4507 match (self.effective_signature_creation_time(),
4508 // This ^ is the difference to
4509 // SubpacketAreas::signature_expiration_time.
4510 self.signature_validity_period())
4511 {
4512 (Ok(Some(ct)), Some(vp)) if vp.as_secs() > 0 => Some(ct + vp),
4513 _ => None,
4514 }
4515 }
4516
4517 /// Sets the Signature Expiration Time subpacket.
4518 ///
4519 /// Adds a [Signature Expiration Time subpacket] to the hashed
4520 /// subpacket area. This function first removes any Signature
4521 /// Expiration Time subpacket from the hashed subpacket area.
4522 ///
4523 /// [Signature Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.18
4524 ///
4525 /// This function is called `set_signature_validity_period` and
4526 /// not `set_signature_expiration_time`, which would be more
4527 /// consistent with the subpacket's name, because the latter
4528 /// suggests an absolute time, but the time is actually relative
4529 /// to the signature's creation time, which is stored in the
4530 /// signature's [Signature Creation Time subpacket] and set using
4531 /// [`SignatureBuilder::set_signature_creation_time`].
4532 ///
4533 /// [Signature Creation Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.11
4534 /// [`SignatureBuilder::set_signature_creation_time`]: super::SignatureBuilder::set_signature_creation_time()
4535 ///
4536 /// A Signature Expiration Time subpacket specifies when the
4537 /// signature expires. This is different from the [Key Expiration
4538 /// Time subpacket], which is set using
4539 /// [`SignatureBuilder::set_key_validity_period`], and used to
4540 /// specify when an associated key expires. The difference is
4541 /// that in the former case, the signature itself expires, but in
4542 /// the latter case, only the associated key expires. This
4543 /// difference is critical: if a binding signature expires, then
4544 /// an OpenPGP implementation will still consider the associated
4545 /// key to be valid if there is another valid binding signature,
4546 /// even if it is older than the expired signature; if the active
4547 /// binding signature indicates that the key has expired, then
4548 /// OpenPGP implementations will not fall back to an older binding
4549 /// signature.
4550 ///
4551 /// [Key Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
4552 /// [`SignatureBuilder::set_key_validity_period`]: super::SignatureBuilder::set_key_validity_period()
4553 ///
4554 /// There are several cases where having a signature expire is
4555 /// useful. Say Alice certifies Bob's certificate for
4556 /// `bob@example.org`. She can limit the lifetime of the
4557 /// certification to force her to reevaluate the certification
4558 /// shortly before it expires. For instance, is Bob still
4559 /// associated with `example.org`? Does she have reason to
4560 /// believe that his key has been compromised? Using an
4561 /// expiration is common in the X.509 ecosystem. For instance,
4562 /// [Let's Encrypt] issues certificates with 90-day lifetimes.
4563 ///
4564 /// [Let's Encrypt]: https://letsencrypt.org/2015/11/09/why-90-days.html
4565 ///
4566 /// Having signatures expire can also be useful when deploying
4567 /// software. For instance, you might have a service that
4568 /// installs an update if it has been signed by a trusted
4569 /// certificate. To prevent an adversary from coercing the
4570 /// service to install an older version, you could limit the
4571 /// signature's lifetime to just a few minutes.
4572 ///
4573 /// # Examples
4574 ///
4575 /// Create a signature that expires in 10 minutes:
4576 ///
4577 /// ```
4578 /// use sequoia_openpgp as openpgp;
4579 /// use openpgp::cert::prelude::*;
4580 /// use openpgp::packet::signature::SignatureBuilder;
4581 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
4582 /// use openpgp::types::SignatureType;
4583 ///
4584 /// # fn main() -> openpgp::Result<()> {
4585 /// #
4586 /// let (cert, _) =
4587 /// CertBuilder::general_purpose(Some("alice@example.org"))
4588 /// .generate()?;
4589 /// let mut signer = cert.primary_key().key().clone()
4590 /// .parts_into_secret()?.into_keypair()?;
4591 ///
4592 /// let msg = "install e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
4593 ///
4594 /// let mut sig = SignatureBuilder::new(SignatureType::Binary)
4595 /// .set_signature_validity_period(
4596 /// std::time::Duration::new(10 * 60, 0))?
4597 /// .sign_message(&mut signer, msg)?;
4598 ///
4599 /// assert!(sig.verify_message(signer.public(), msg).is_ok());
4600 /// # assert_eq!(sig
4601 /// # .hashed_area()
4602 /// # .iter()
4603 /// # .filter(|sp| sp.tag() == SubpacketTag::SignatureExpirationTime)
4604 /// # .count(),
4605 /// # 1);
4606 /// # Ok(()) }
4607 /// ```
4608 ///
4609 /// Create a certification that expires at the end of the year
4610 /// (give or take a few seconds) unless the new year is in a
4611 /// month, then have it expire at the end of the following year:
4612 ///
4613 /// ```
4614 /// use std::time::{SystemTime, UNIX_EPOCH, Duration};
4615 /// use sequoia_openpgp as openpgp;
4616 /// use openpgp::cert::prelude::*;
4617 /// use openpgp::packet::signature::SignatureBuilder;
4618 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
4619 /// use openpgp::types::SignatureType;
4620 ///
4621 /// # fn main() -> openpgp::Result<()> {
4622 /// let (cert, _) =
4623 /// CertBuilder::general_purpose(Some("alice@example.org"))
4624 /// .generate()?;
4625 /// let mut signer = cert.primary_key().key().clone()
4626 /// .parts_into_secret()?.into_keypair()?;
4627 ///
4628 /// let msg = "message.";
4629 ///
4630 /// // Average number of seconds in a year. See:
4631 /// // https://en.wikipedia.org/wiki/Year .
4632 /// const SECONDS_IN_YEAR: u64 = (365.2425 * 24. * 60. * 60.) as u64;
4633 ///
4634 /// let now = SystemTime::now();
4635 /// let since_epoch = now.duration_since(UNIX_EPOCH)?.as_secs();
4636 /// let next_year
4637 /// = (since_epoch + SECONDS_IN_YEAR) - (since_epoch % SECONDS_IN_YEAR);
4638 /// // Make sure the expiration is at least a month in the future.
4639 /// let next_year = if next_year - since_epoch < SECONDS_IN_YEAR / 12 {
4640 /// next_year + SECONDS_IN_YEAR
4641 /// } else {
4642 /// next_year
4643 /// };
4644 /// let next_year = UNIX_EPOCH + Duration::new(next_year, 0);
4645 /// let next_year = next_year.duration_since(now)?;
4646 ///
4647 /// let sig = SignatureBuilder::new(SignatureType::Binary)
4648 /// .set_signature_creation_time(now)?
4649 /// .set_signature_validity_period(next_year)?
4650 /// .sign_message(&mut signer, msg)?;
4651 /// #
4652 /// # let mut sig = sig;
4653 /// # assert!(sig.verify_message(signer.public(), msg).is_ok());
4654 /// # assert_eq!(sig
4655 /// # .hashed_area()
4656 /// # .iter()
4657 /// # .filter(|sp| sp.tag() == SubpacketTag::SignatureExpirationTime)
4658 /// # .count(),
4659 /// # 1);
4660 /// # Ok(()) }
4661 /// ```
4662 pub fn set_signature_validity_period<D>(mut self, expires_in: D)
4663 -> Result<Self>
4664 where D: Into<time::Duration>
4665 {
4666 self.hashed_area.replace(Subpacket::new(
4667 SubpacketValue::SignatureExpirationTime(
4668 Duration::try_from(expires_in.into())?),
4669 true)?)?;
4670
4671 Ok(self)
4672 }
4673
4674 /// Sets the Exportable Certification subpacket.
4675 ///
4676 /// Adds an [Exportable Certification subpacket] to the hashed
4677 /// subpacket area. This function first removes any Exportable
4678 /// Certification subpacket from the hashed subpacket area.
4679 ///
4680 /// [Exportable Certification subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.19
4681 ///
4682 /// The Exportable Certification subpacket indicates whether the
4683 /// signature should be exported (e.g., published on a public key
4684 /// server) or not. When using [`Serialize::export`] to export a
4685 /// certificate, signatures that have this subpacket present and
4686 /// set to false are not serialized.
4687 ///
4688 /// [`Serialize::export`]: https://docs.sequoia-pgp.org/sequoia_openpgp/serialize/trait.Serialize.html#method.export
4689 ///
4690 /// # Examples
4691 ///
4692 /// Alice certificates Bob's certificate, but because she doesn't
4693 /// want to publish it, she creates a so-called local signature by
4694 /// adding an Exportable Certification subpacket set to `false` to
4695 /// the signature:
4696 ///
4697 /// ```
4698 /// use sequoia_openpgp as openpgp;
4699 /// use openpgp::cert::prelude::*;
4700 /// use openpgp::packet::prelude::*;
4701 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
4702 /// use openpgp::policy::StandardPolicy;
4703 /// use openpgp::types::SignatureType;
4704 ///
4705 /// # fn main() -> openpgp::Result<()> {
4706 /// #
4707 /// let p = &StandardPolicy::new();
4708 ///
4709 /// let (alice, _)
4710 /// = CertBuilder::general_purpose(Some("alice@example.org"))
4711 /// .generate()?;
4712 /// let mut alices_signer = alice.primary_key().key().clone()
4713 /// .parts_into_secret()?.into_keypair()?;
4714 ///
4715 /// let (bob, _)
4716 /// = CertBuilder::general_purpose(Some("bob@example.org"))
4717 /// .generate()?;
4718 /// let bobs_userid
4719 /// = bob.with_policy(p, None)?.userids().nth(0).expect("Added a User ID").userid();
4720 ///
4721 /// let certification = SignatureBuilder::new(SignatureType::GenericCertification)
4722 /// .set_exportable_certification(false)?
4723 /// .sign_userid_binding(
4724 /// &mut alices_signer, bob.primary_key().key(), bobs_userid)?;
4725 /// # assert_eq!(certification
4726 /// # .hashed_area()
4727 /// # .iter()
4728 /// # .filter(|sp| sp.tag() == SubpacketTag::ExportableCertification)
4729 /// # .count(),
4730 /// # 1);
4731 ///
4732 /// // Merge in the new signature.
4733 /// let bob = bob.insert_packets(certification)?.0;
4734 /// # assert_eq!(bob.bad_signatures().count(), 0);
4735 /// # assert_eq!(bob.userids().nth(0).unwrap().certifications().count(), 1);
4736 /// # Ok(()) }
4737 /// ```
4738 pub fn set_exportable_certification(mut self, exportable: bool)
4739 -> Result<Self> {
4740 self.hashed_area.replace(Subpacket::new(
4741 SubpacketValue::ExportableCertification(exportable),
4742 true)?)?;
4743
4744 Ok(self)
4745 }
4746
4747 /// Sets the Trust Signature subpacket.
4748 ///
4749 /// Adds a [Trust Signature subpacket] to the hashed subpacket
4750 /// area. This function first removes any Trust Signature
4751 /// subpacket from the hashed subpacket area.
4752 ///
4753 /// [Trust Signature subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.21
4754 ///
4755 /// The Trust Signature subpacket indicates the degree to which a
4756 /// certificate holder is trusted to certify other keys.
4757 ///
4758 /// A level of 0 means that the certificate holder is not trusted
4759 /// to certificate other keys, a level of 1 means that the
4760 /// certificate holder is a trusted introducer (a [certificate
4761 /// authority]) and any certifications that they make should be
4762 /// considered valid. A level of 2 means the certificate holder
4763 /// can designate level 1 trusted introducers, etc.
4764 ///
4765 /// [certificate authority]: https://en.wikipedia.org/wiki/Certificate_authority
4766 ///
4767 /// The trust indicates the degree of confidence. A value of 120
4768 /// means that a certification should be considered valid. A
4769 /// value of 60 means that a certification should only be
4770 /// considered partially valid. In the latter case, typically
4771 /// three such certifications are required for a binding to be
4772 /// considered authenticated.
4773 ///
4774 /// # Examples
4775 ///
4776 /// Alice designates Bob as a fully trusted, trusted introducer:
4777 ///
4778 /// ```
4779 /// use sequoia_openpgp as openpgp;
4780 /// use openpgp::cert::prelude::*;
4781 /// use openpgp::packet::prelude::*;
4782 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
4783 /// use openpgp::policy::StandardPolicy;
4784 /// use openpgp::types::SignatureType;
4785 ///
4786 /// # fn main() -> openpgp::Result<()> {
4787 /// #
4788 /// let p = &StandardPolicy::new();
4789 ///
4790 /// let (alice, _)
4791 /// = CertBuilder::general_purpose(Some("alice@example.org"))
4792 /// .generate()?;
4793 /// let mut alices_signer = alice.primary_key().key().clone()
4794 /// .parts_into_secret()?.into_keypair()?;
4795 ///
4796 /// let (bob, _)
4797 /// = CertBuilder::general_purpose(Some("bob@example.org"))
4798 /// .generate()?;
4799 /// let bobs_userid
4800 /// = bob.with_policy(p, None)?.userids().nth(0).expect("Added a User ID").userid();
4801 ///
4802 /// let certification = SignatureBuilder::new(SignatureType::GenericCertification)
4803 /// .set_trust_signature(1, 120)?
4804 /// .sign_userid_binding(
4805 /// &mut alices_signer, bob.primary_key().component(), bobs_userid)?;
4806 /// # assert_eq!(certification
4807 /// # .hashed_area()
4808 /// # .iter()
4809 /// # .filter(|sp| sp.tag() == SubpacketTag::TrustSignature)
4810 /// # .count(),
4811 /// # 1);
4812 ///
4813 /// // Merge in the new signature.
4814 /// let bob = bob.insert_packets(certification)?.0;
4815 /// # assert_eq!(bob.bad_signatures().count(), 0);
4816 /// # assert_eq!(bob.userids().nth(0).unwrap().certifications().count(), 1);
4817 /// # Ok(()) }
4818 /// ```
4819 pub fn set_trust_signature(mut self, level: u8, trust: u8)
4820 -> Result<Self> {
4821 self.hashed_area.replace(Subpacket::new(
4822 SubpacketValue::TrustSignature {
4823 level,
4824 trust,
4825 },
4826 true)?)?;
4827
4828 Ok(self)
4829 }
4830
4831 /// Sets the Regular Expression subpacket.
4832 ///
4833 /// Adds a [Regular Expression subpacket] to the hashed subpacket
4834 /// area. This function first removes any Regular Expression
4835 /// subpacket from the hashed subpacket area.
4836 ///
4837 /// [Regular Expression subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.22
4838 ///
4839 /// The Regular Expression subpacket is used in conjunction with a
4840 /// [Trust Signature subpacket], which is set using
4841 /// [`SignatureBuilder::set_trust_signature`], to limit the scope
4842 /// of a trusted introducer. This is useful, for instance, when a
4843 /// company has a CA and you only want to trust them to certify
4844 /// their own employees.
4845 ///
4846 /// [Trust Signature subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.21
4847 /// [`SignatureBuilder::set_trust_signature`]: super::SignatureBuilder::set_trust_signature()
4848 ///
4849 /// GnuPG only supports [a limited form of regular expressions].
4850 ///
4851 /// [a limited form of regular expressions]: https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=g10/trustdb.c;h=c4b996a9685486b2095608f6685727022120505f;hb=refs/heads/master#l1537
4852 ///
4853 /// Note: The serialized form includes a trailing `NUL` byte.
4854 /// Sequoia adds this `NUL` when serializing the signature.
4855 /// Adding it yourself will result in two trailing NUL bytes.
4856 ///
4857 /// # Examples
4858 ///
4859 /// Alice designates ``openpgp-ca@example.com`` as a fully
4860 /// trusted, trusted introducer, but only for users from the
4861 /// ``example.com`` domain:
4862 ///
4863 /// ```
4864 /// use sequoia_openpgp as openpgp;
4865 /// use openpgp::cert::prelude::*;
4866 /// use openpgp::packet::prelude::*;
4867 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
4868 /// use openpgp::policy::StandardPolicy;
4869 /// use openpgp::types::SignatureType;
4870 ///
4871 /// # fn main() -> openpgp::Result<()> {
4872 /// #
4873 /// let p = &StandardPolicy::new();
4874 ///
4875 /// let (alice, _)
4876 /// = CertBuilder::general_purpose(Some("Alice <alice@example.org>"))
4877 /// .generate()?;
4878 /// let mut alices_signer = alice.primary_key().key().clone()
4879 /// .parts_into_secret()?.into_keypair()?;
4880 ///
4881 /// let (example_com, _)
4882 /// = CertBuilder::general_purpose(Some("OpenPGP CA <openpgp-ca@example.com>"))
4883 /// .generate()?;
4884 /// let example_com_userid = example_com.with_policy(p, None)?
4885 /// .userids().nth(0).expect("Added a User ID").userid();
4886 ///
4887 /// let certification = SignatureBuilder::new(SignatureType::GenericCertification)
4888 /// .set_trust_signature(1, 120)?
4889 /// .set_regular_expression("<[^>]+[@.]example\\.com>$")?
4890 /// .sign_userid_binding(
4891 /// &mut alices_signer,
4892 /// example_com.primary_key().component(),
4893 /// example_com_userid)?;
4894 /// # assert_eq!(certification
4895 /// # .hashed_area()
4896 /// # .iter()
4897 /// # .filter(|sp| sp.tag() == SubpacketTag::TrustSignature)
4898 /// # .count(),
4899 /// # 1);
4900 /// # assert_eq!(certification
4901 /// # .hashed_area()
4902 /// # .iter()
4903 /// # .filter(|sp| sp.tag() == SubpacketTag::RegularExpression)
4904 /// # .count(),
4905 /// # 1);
4906 ///
4907 /// // Merge in the new signature.
4908 /// let example_com = example_com.insert_packets(certification)?.0;
4909 /// # assert_eq!(example_com.bad_signatures().count(), 0);
4910 /// # assert_eq!(example_com.userids().nth(0).unwrap().certifications().count(), 1);
4911 /// # Ok(()) }
4912 /// ```
4913 pub fn set_regular_expression<R>(mut self, re: R) -> Result<Self>
4914 where R: AsRef<[u8]>
4915 {
4916 self.hashed_area.replace(Subpacket::new(
4917 SubpacketValue::RegularExpression(re.as_ref().to_vec()),
4918 true)?)?;
4919
4920 Ok(self)
4921 }
4922
4923 /// Sets a Regular Expression subpacket.
4924 ///
4925 /// Adds a [Regular Expression subpacket] to the hashed subpacket
4926 /// area. Unlike [`SignatureBuilder::set_regular_expression`],
4927 /// this function does not first remove any Regular Expression
4928 /// subpacket from the hashed subpacket area, but adds an
4929 /// additional Regular Expression subpacket to the hashed
4930 /// subpacket area.
4931 ///
4932 /// [`SignatureBuilder::set_regular_expression`]: super::SignatureBuilder::set_regular_expression()
4933 /// [Regular Expression subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.22
4934 ///
4935 /// The Regular Expression subpacket is used in conjunction with a
4936 /// [Trust Signature subpacket], which is set using
4937 /// [`SignatureBuilder::set_trust_signature`], to limit the scope
4938 /// of a trusted introducer. This is useful, for instance, when a
4939 /// company has a CA and you only want to trust them to certify
4940 /// their own employees.
4941 ///
4942 /// [Trust Signature subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.21
4943 /// [`SignatureBuilder::set_trust_signature`]: super::SignatureBuilder::set_trust_signature()
4944 ///
4945 /// GnuPG only supports [a limited form of regular expressions].
4946 ///
4947 /// [a limited form of regular expressions]: https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=g10/trustdb.c;h=c4b996a9685486b2095608f6685727022120505f;hb=refs/heads/master#l1537
4948 ///
4949 /// Note: The serialized form includes a trailing `NUL` byte.
4950 /// Sequoia adds this `NUL` when serializing the signature.
4951 /// Adding it yourself will result in two trailing NUL bytes.
4952 ///
4953 /// # Examples
4954 ///
4955 /// Alice designates ``openpgp-ca@example.com`` as a fully
4956 /// trusted, trusted introducer, but only for users from the
4957 /// ``example.com`` and ``example.net`` domains:
4958 ///
4959 /// ```
4960 /// use sequoia_openpgp as openpgp;
4961 /// use openpgp::cert::prelude::*;
4962 /// use openpgp::packet::prelude::*;
4963 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
4964 /// use openpgp::policy::StandardPolicy;
4965 /// use openpgp::types::SignatureType;
4966 ///
4967 /// # fn main() -> openpgp::Result<()> {
4968 /// #
4969 /// let p = &StandardPolicy::new();
4970 ///
4971 /// let (alice, _)
4972 /// = CertBuilder::general_purpose(Some("Alice <alice@example.org>"))
4973 /// .generate()?;
4974 /// let mut alices_signer = alice.primary_key().key().clone()
4975 /// .parts_into_secret()?.into_keypair()?;
4976 ///
4977 /// let (example_com, _)
4978 /// = CertBuilder::general_purpose(Some("OpenPGP CA <openpgp-ca@example.com>"))
4979 /// .generate()?;
4980 /// let example_com_userid = example_com.with_policy(p, None)?
4981 /// .userids().nth(0).expect("Added a User ID").userid();
4982 ///
4983 /// let certification = SignatureBuilder::new(SignatureType::GenericCertification)
4984 /// .set_trust_signature(1, 120)?
4985 /// .set_regular_expression("<[^>]+[@.]example\\.com>$")?
4986 /// .add_regular_expression("<[^>]+[@.]example\\.net>$")?
4987 /// .sign_userid_binding(
4988 /// &mut alices_signer,
4989 /// example_com.primary_key().component(),
4990 /// example_com_userid)?;
4991 /// # assert_eq!(certification
4992 /// # .hashed_area()
4993 /// # .iter()
4994 /// # .filter(|sp| sp.tag() == SubpacketTag::TrustSignature)
4995 /// # .count(),
4996 /// # 1);
4997 /// # assert_eq!(certification
4998 /// # .hashed_area()
4999 /// # .iter()
5000 /// # .filter(|sp| sp.tag() == SubpacketTag::RegularExpression)
5001 /// # .count(),
5002 /// # 2);
5003 ///
5004 /// // Merge in the new signature.
5005 /// let example_com = example_com.insert_packets(certification)?.0;
5006 /// # assert_eq!(example_com.bad_signatures().count(), 0);
5007 /// # assert_eq!(example_com.userids().nth(0).unwrap().certifications().count(), 1);
5008 /// # Ok(()) }
5009 /// ```
5010 pub fn add_regular_expression<R>(mut self, re: R) -> Result<Self>
5011 where R: AsRef<[u8]>
5012 {
5013 self.hashed_area.add(Subpacket::new(
5014 SubpacketValue::RegularExpression(re.as_ref().to_vec()),
5015 true)?)?;
5016
5017 Ok(self)
5018 }
5019
5020 /// Sets the Revocable subpacket.
5021 ///
5022 /// Adds a [Revocable subpacket] to the hashed subpacket area.
5023 /// This function first removes any Revocable subpacket from the
5024 /// hashed subpacket area.
5025 ///
5026 /// [Revocable subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.20
5027 ///
5028 /// The Revocable subpacket indicates whether a certification may
5029 /// be later revoked by creating a [Certification revocation
5030 /// signature] (0x30) that targets the signature using the
5031 /// [Signature Target subpacket] (set using the
5032 /// [`SignatureBuilder::set_signature_target`] method).
5033 ///
5034 /// [Certification revocation signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
5035 /// [Signature Target subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.33
5036 /// [`SignatureBuilder::set_signature_target`]: super::SignatureBuilder::set_signature_target()
5037 ///
5038 /// # Examples
5039 ///
5040 /// Alice certifies Bob's key and marks the certification as
5041 /// irrevocable. Since she can't revoke the signature, she limits
5042 /// the scope of misuse by setting the signature to expire in a
5043 /// year:
5044 ///
5045 /// ```
5046 /// use sequoia_openpgp as openpgp;
5047 /// use openpgp::cert::prelude::*;
5048 /// use openpgp::packet::prelude::*;
5049 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
5050 /// use openpgp::policy::StandardPolicy;
5051 /// use openpgp::types::SignatureType;
5052 ///
5053 /// # fn main() -> openpgp::Result<()> {
5054 /// #
5055 /// let p = &StandardPolicy::new();
5056 ///
5057 /// let (alice, _)
5058 /// = CertBuilder::general_purpose(Some("alice@example.org"))
5059 /// .generate()?;
5060 /// let mut alices_signer = alice.primary_key().key().clone()
5061 /// .parts_into_secret()?.into_keypair()?;
5062 ///
5063 /// let (bob, _)
5064 /// = CertBuilder::general_purpose(Some("bob@example.org"))
5065 /// .generate()?;
5066 /// let bobs_userid
5067 /// = bob.with_policy(p, None)?.userids().nth(0).expect("Added a User ID").userid();
5068 ///
5069 /// // Average number of seconds in a year. See:
5070 /// // https://en.wikipedia.org/wiki/Year .
5071 /// const SECONDS_IN_YEAR: u64 = (365.2425 * 24. * 60. * 60.) as u64;
5072 ///
5073 /// let certification = SignatureBuilder::new(SignatureType::GenericCertification)
5074 /// .set_revocable(false)?
5075 /// .set_signature_validity_period(
5076 /// std::time::Duration::new(SECONDS_IN_YEAR, 0))?
5077 /// .sign_userid_binding(
5078 /// &mut alices_signer, bob.primary_key().component(), bobs_userid)?;
5079 /// # assert_eq!(certification
5080 /// # .hashed_area()
5081 /// # .iter()
5082 /// # .filter(|sp| sp.tag() == SubpacketTag::Revocable)
5083 /// # .count(),
5084 /// # 1);
5085 ///
5086 /// // Merge in the new signature.
5087 /// let bob = bob.insert_packets(certification)?.0;
5088 /// # assert_eq!(bob.bad_signatures().count(), 0);
5089 /// # assert_eq!(bob.userids().nth(0).unwrap().certifications().count(), 1);
5090 /// # Ok(()) }
5091 /// ```
5092 pub fn set_revocable(mut self, revocable: bool) -> Result<Self> {
5093 self.hashed_area.replace(Subpacket::new(
5094 SubpacketValue::Revocable(revocable),
5095 true)?)?;
5096
5097 Ok(self)
5098 }
5099
5100 /// Sets the Key Expiration Time subpacket.
5101 ///
5102 /// Adds a [Key Expiration Time subpacket] to the hashed subpacket
5103 /// area. This function first removes any Key Expiration Time
5104 /// subpacket from the hashed subpacket area.
5105 ///
5106 /// If `None` is given, any expiration subpacket is removed.
5107 ///
5108 /// [Key Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
5109 ///
5110 /// This function is called `set_key_validity_period` and not
5111 /// `set_key_expiration_time`, which would be more consistent with
5112 /// the subpacket's name, because the latter suggests an absolute
5113 /// time, but the time is actually relative to the associated
5114 /// key's (*not* the signature's) creation time, which is stored
5115 /// in the [Key].
5116 ///
5117 /// [Key]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.5.2
5118 ///
5119 /// There is a more convenient function
5120 /// [`SignatureBuilder::set_key_expiration_time`] that takes an
5121 /// absolute expiration time.
5122 ///
5123 /// [`SignatureBuilder::set_key_expiration_time`]: super::SignatureBuilder::set_key_expiration_time()
5124 ///
5125 /// A Key Expiration Time subpacket specifies when the associated
5126 /// key expires. This is different from the [Signature Expiration
5127 /// Time subpacket] (set using
5128 /// [`SignatureBuilder::set_signature_validity_period`]), which is
5129 /// used to specify when the signature expires. That is, in the
5130 /// former case, the associated key expires, but in the latter
5131 /// case, the signature itself expires. This difference is
5132 /// critical: if a binding signature expires, then an OpenPGP
5133 /// implementation will still consider the associated key to be
5134 /// valid if there is another valid binding signature, even if it
5135 /// is older than the expired signature; if the active binding
5136 /// signature indicates that the key has expired, then OpenPGP
5137 /// implementations will not fall back to an older binding
5138 /// signature.
5139 ///
5140 /// [Signature Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
5141 /// [`SignatureBuilder::set_signature_validity_period`]: super::SignatureBuilder::set_signature_validity_period()
5142 ///
5143 /// # Examples
5144 ///
5145 /// Change all subkeys to expire 10 minutes after their (not the
5146 /// new binding signature's) creation time.
5147 ///
5148 /// ```
5149 /// use sequoia_openpgp as openpgp;
5150 /// use openpgp::cert::prelude::*;
5151 /// use openpgp::packet::prelude::*;
5152 /// use openpgp::policy::StandardPolicy;
5153 /// use openpgp::types::SignatureType;
5154 ///
5155 /// # fn main() -> openpgp::Result<()> {
5156 /// #
5157 /// let p = &StandardPolicy::new();
5158 ///
5159 /// let (cert, _) =
5160 /// CertBuilder::general_purpose(Some("alice@example.org"))
5161 /// .generate()?;
5162 /// let pk = cert.primary_key().key();
5163 /// let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;
5164 ///
5165 /// // Create the binding signatures.
5166 /// let mut sigs = Vec::new();
5167 ///
5168 /// for ka in cert.with_policy(p, None)?.keys().subkeys() {
5169 /// // This reuses any existing backsignature.
5170 /// let sig = SignatureBuilder::from(ka.binding_signature().clone())
5171 /// .set_key_validity_period(std::time::Duration::new(10 * 60, 0))?
5172 /// .sign_subkey_binding(&mut signer, None, ka.key())?;
5173 /// sigs.push(sig);
5174 /// }
5175 ///
5176 /// let cert = cert.insert_packets(sigs)?.0;
5177 /// # assert_eq!(cert.bad_signatures().count(), 0);
5178 /// #
5179 /// # // "Before"
5180 /// # for key in cert.with_policy(p, None)?.keys().subkeys() {
5181 /// # assert_eq!(key.bundle().self_signatures().count(), 2);
5182 /// # assert!(key.alive().is_ok());
5183 /// # }
5184 /// #
5185 /// # // "After"
5186 /// # for key in cert
5187 /// # .with_policy(p, std::time::SystemTime::now()
5188 /// # + std::time::Duration::new(20 * 60, 0))?
5189 /// # .keys().subkeys()
5190 /// # {
5191 /// # assert!(key.alive().is_err());
5192 /// # }
5193 /// # Ok(()) }
5194 /// ```
5195 pub fn set_key_validity_period<D>(mut self, expires_in: D)
5196 -> Result<Self>
5197 where D: Into<Option<time::Duration>>
5198 {
5199 if let Some(e) = expires_in.into() {
5200 self.hashed_area.replace(Subpacket::new(
5201 SubpacketValue::KeyExpirationTime(e.try_into()?),
5202 true)?)?;
5203 } else {
5204 self.hashed_area.remove_all(SubpacketTag::KeyExpirationTime);
5205 }
5206
5207 Ok(self)
5208 }
5209
5210 /// Sets the Key Expiration Time subpacket.
5211 ///
5212 /// Adds a [Key Expiration Time subpacket] to the hashed subpacket
5213 /// area. This function first removes any Key Expiration Time
5214 /// subpacket from the hashed subpacket area.
5215 ///
5216 /// If `None` is given, any expiration subpacket is removed.
5217 ///
5218 /// [Key Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
5219 ///
5220 /// This function is called `set_key_expiration_time` similar to
5221 /// the subpacket's name, but it takes an absolute time, whereas
5222 /// the subpacket stores a time relative to the associated key's
5223 /// (*not* the signature's) creation time, which is stored in the
5224 /// [Key].
5225 ///
5226 /// [Key]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.5.2
5227 ///
5228 /// This is a more convenient function than
5229 /// [`SignatureBuilder::set_key_validity_period`] that takes a
5230 /// relative expiration time.
5231 ///
5232 /// [`SignatureBuilder::set_key_validity_period`]: super::SignatureBuilder::set_key_validity_period()
5233 ///
5234 /// A Key Expiration Time subpacket specifies when the associated
5235 /// key expires. This is different from the [Signature Expiration
5236 /// Time subpacket] (set using
5237 /// [`SignatureBuilder::set_signature_validity_period`]), which is
5238 /// used to specify when the signature expires. That is, in the
5239 /// former case, the associated key expires, but in the latter
5240 /// case, the signature itself expires. This difference is
5241 /// critical: if a binding signature expires, then an OpenPGP
5242 /// implementation will still consider the associated key to be
5243 /// valid if there is another valid binding signature, even if it
5244 /// is older than the expired signature; if the active binding
5245 /// signature indicates that the key has expired, then OpenPGP
5246 /// implementations will not fall back to an older binding
5247 /// signature.
5248 ///
5249 /// [Signature Expiration Time subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.13
5250 /// [`SignatureBuilder::set_signature_validity_period`]: super::SignatureBuilder::set_signature_validity_period()
5251 ///
5252 /// # Examples
5253 ///
5254 /// Change all subkeys to expire 10 minutes after their (not the
5255 /// new binding signature's) creation time.
5256 ///
5257 /// ```
5258 /// use std::time;
5259 /// use sequoia_openpgp as openpgp;
5260 /// use openpgp::cert::prelude::*;
5261 /// use openpgp::packet::prelude::*;
5262 /// use openpgp::policy::StandardPolicy;
5263 /// use openpgp::types::SignatureType;
5264 ///
5265 /// # fn main() -> openpgp::Result<()> {
5266 /// #
5267 /// let p = &StandardPolicy::new();
5268 ///
5269 /// let (cert, _) =
5270 /// CertBuilder::general_purpose(Some("alice@example.org"))
5271 /// .generate()?;
5272 /// let pk = cert.primary_key().key();
5273 /// let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;
5274 ///
5275 /// // Create the binding signatures.
5276 /// let mut sigs = Vec::new();
5277 ///
5278 /// for ka in cert.with_policy(p, None)?.keys().subkeys() {
5279 /// // This reuses any existing backsignature.
5280 /// let sig = SignatureBuilder::from(ka.binding_signature().clone())
5281 /// .set_key_expiration_time(ka.key(),
5282 /// time::SystemTime::now()
5283 /// + time::Duration::new(10 * 60, 0))?
5284 /// .sign_subkey_binding(&mut signer, None, ka.key())?;
5285 /// sigs.push(sig);
5286 /// }
5287 ///
5288 /// let cert = cert.insert_packets(sigs)?.0;
5289 /// # assert_eq!(cert.bad_signatures().count(), 0);
5290 /// #
5291 /// # // "Before"
5292 /// # for key in cert.with_policy(p, None)?.keys().subkeys() {
5293 /// # assert_eq!(key.bundle().self_signatures().count(), 2);
5294 /// # assert!(key.alive().is_ok());
5295 /// # }
5296 /// #
5297 /// # // "After"
5298 /// # for key in cert.with_policy(p, time::SystemTime::now()
5299 /// # + time::Duration::new(20 * 60, 0))?
5300 /// # .keys().subkeys()
5301 /// # {
5302 /// # assert!(key.alive().is_err());
5303 /// # }
5304 /// # Ok(()) }
5305 /// ```
5306 pub fn set_key_expiration_time<P, R, E>(
5307 self,
5308 key: &Key<P, R>,
5309 expiration: E)
5310 -> Result<Self>
5311 where P: key::KeyParts,
5312 R: key::KeyRole,
5313 E: Into<Option<time::SystemTime>>,
5314 {
5315 if let Some(e) = expiration.into()
5316 .map(crate::types::normalize_systemtime)
5317 {
5318 let ct = key.creation_time();
5319 let vp = match e.duration_since(ct) {
5320 Ok(v) => v,
5321 Err(_) => return Err(Error::InvalidArgument(
5322 format!("Expiration time {:?} predates creation time \
5323 {:?}", e, ct)).into()),
5324 };
5325
5326 self.set_key_validity_period(Some(vp))
5327 } else {
5328 self.set_key_validity_period(None)
5329 }
5330 }
5331
5332 /// Sets the Preferred Symmetric Algorithms subpacket.
5333 ///
5334 /// Replaces any [Preferred Symmetric Algorithms subpacket] in the
5335 /// hashed subpacket area with a new subpacket containing the
5336 /// specified value. That is, this function first removes any
5337 /// Preferred Symmetric Algorithms subpacket from the hashed
5338 /// subpacket area, and then adds a new one.
5339 ///
5340 /// A Preferred Symmetric Algorithms subpacket lists what
5341 /// symmetric algorithms the user prefers. When encrypting a
5342 /// message for a recipient, the OpenPGP implementation should not
5343 /// use an algorithm that is not on this list.
5344 ///
5345 /// [Preferred Symmetric Algorithms subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.14
5346 ///
5347 /// This subpacket is a type of preference. When looking up a
5348 /// preference, an OpenPGP implementation should first look for
5349 /// the subpacket on the binding signature of the User ID or the
5350 /// User Attribute used to locate the certificate (or the primary
5351 /// User ID, if it was addressed by Key ID or fingerprint). If
5352 /// the binding signature doesn't contain the subpacket, then the
5353 /// direct key signature should be checked. See the
5354 /// [`Preferences`] trait for details.
5355 ///
5356 /// Unless addressing different User IDs really should result in
5357 /// different behavior, it is best to only set this preference on
5358 /// the direct key signature. This guarantees that even if some
5359 /// or all User IDs are stripped, the behavior remains consistent.
5360 ///
5361 /// [`Preferences`]: crate::cert::Preferences
5362 ///
5363 /// # Examples
5364 ///
5365 /// ```
5366 /// use sequoia_openpgp as openpgp;
5367 /// use openpgp::cert::prelude::*;
5368 /// use openpgp::packet::prelude::*;
5369 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
5370 /// use openpgp::policy::StandardPolicy;
5371 /// use openpgp::types::SymmetricAlgorithm;
5372 ///
5373 /// # fn main() -> openpgp::Result<()> {
5374 /// let p = &StandardPolicy::new();
5375 ///
5376 /// let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
5377 /// let mut signer = cert.primary_key().key()
5378 /// .clone().parts_into_secret()?.into_keypair()?;
5379 ///
5380 /// let vc = cert.with_policy(p, None)?;
5381 ///
5382 /// let template = vc.direct_key_signature()
5383 /// .expect("CertBuilder always includes a direct key signature");
5384 /// let sig = SignatureBuilder::from(template.clone())
5385 /// .set_preferred_symmetric_algorithms(
5386 /// vec![ SymmetricAlgorithm::AES256,
5387 /// SymmetricAlgorithm::AES128,
5388 /// ])?
5389 /// .sign_direct_key(&mut signer, None)?;
5390 /// # assert_eq!(sig
5391 /// # .hashed_area()
5392 /// # .iter()
5393 /// # .filter(|sp| sp.tag() == SubpacketTag::PreferredSymmetricAlgorithms)
5394 /// # .count(),
5395 /// # 1);
5396 ///
5397 /// // Merge in the new signature.
5398 /// let cert = cert.insert_packets(sig)?.0;
5399 /// # assert_eq!(cert.bad_signatures().count(), 0);
5400 /// # Ok(()) }
5401 /// ```
5402 pub fn set_preferred_symmetric_algorithms(mut self,
5403 preferences: Vec<SymmetricAlgorithm>)
5404 -> Result<Self> {
5405 self.hashed_area.replace(Subpacket::new(
5406 SubpacketValue::PreferredSymmetricAlgorithms(preferences),
5407 false)?)?;
5408
5409 Ok(self)
5410 }
5411
5412 /// Sets the Revocation Key subpacket.
5413 ///
5414 /// Replaces any [Revocation Key subpacket] in the hashed
5415 /// subpacket area with one new subpacket for each of the
5416 /// specified values. That is, unlike
5417 /// [`super::SignatureBuilder::add_revocation_key`], this function
5418 /// first removes any Revocation Key subpackets from the hashed
5419 /// subpacket area, and then adds new ones.
5420 ///
5421 /// [Revocation Key subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.23
5422 ///
5423 /// A Revocation Key subpacket indicates certificates (so-called
5424 /// designated revokers) that are allowed to revoke the signer's
5425 /// certificate. For instance, if Alice trusts Bob, she can set
5426 /// him as a designated revoker. This is useful if Alice loses
5427 /// access to her key, and therefore is unable to generate a
5428 /// revocation certificate on her own. In this case, she can
5429 /// still Bob to generate one on her behalf.
5430 ///
5431 /// Due to the complexity of verifying such signatures, many
5432 /// OpenPGP implementations do not support this feature.
5433 ///
5434 /// # Examples
5435 ///
5436 /// ```
5437 /// use sequoia_openpgp as openpgp;
5438 /// use openpgp::cert::prelude::*;
5439 /// use openpgp::packet::prelude::*;
5440 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
5441 /// use openpgp::policy::StandardPolicy;
5442 /// use openpgp::types::RevocationKey;
5443 ///
5444 /// # fn main() -> openpgp::Result<()> {
5445 /// let p = &StandardPolicy::new();
5446 ///
5447 /// let (alice, _) = CertBuilder::new().add_userid("Alice").generate()?;
5448 /// let mut alices_signer = alice.primary_key().key()
5449 /// .clone().parts_into_secret()?.into_keypair()?;
5450 ///
5451 /// let (bob, _) = CertBuilder::new().add_userid("Bob").generate()?;
5452 ///
5453 /// let template = alice.with_policy(p, None)?.direct_key_signature()
5454 /// .expect("CertBuilder always includes a direct key signature");
5455 /// let sig = SignatureBuilder::from(template.clone())
5456 /// // Replace any revocation keys inherited from template.
5457 /// .set_revocation_key(
5458 /// RevocationKey::new(bob.primary_key().key().pk_algo(), bob.fingerprint(), false),
5459 /// )?
5460 /// .sign_direct_key(&mut alices_signer, None)?;
5461 /// # assert_eq!(sig
5462 /// # .hashed_area()
5463 /// # .iter()
5464 /// # .filter(|sp| sp.tag() == SubpacketTag::RevocationKey)
5465 /// # .count(),
5466 /// # 1);
5467 ///
5468 /// // Merge in the new signature.
5469 /// let alice = alice.insert_packets(sig)?.0;
5470 /// # assert_eq!(alice.bad_signatures().count(), 0);
5471 /// # assert_eq!(alice.primary_key().self_signatures().count(), 2);
5472 /// # Ok(()) }
5473 /// ```
5474 pub fn set_revocation_key(mut self, rk: RevocationKey) -> Result<Self> {
5475 self.hashed_area.remove_all(SubpacketTag::RevocationKey);
5476 self.add_revocation_key(rk)
5477 }
5478
5479 /// Adds a Revocation Key subpacket.
5480 ///
5481 /// Adds a [Revocation Key subpacket] to the hashed subpacket
5482 /// area. Unlike [`super::SignatureBuilder::set_revocation_key`],
5483 /// this function does not first remove any Revocation Key
5484 /// subpackets from the hashed subpacket area.
5485 ///
5486 /// [Revocation Key subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.23
5487 ///
5488 /// A Revocation Key subpacket indicates certificates (so-called
5489 /// designated revokers) that are allowed to revoke the signer's
5490 /// certificate. For instance, if Alice trusts Bob, she can set
5491 /// him as a designated revoker. This is useful if Alice loses
5492 /// access to her key, and therefore is unable to generate a
5493 /// revocation certificate on her own. In this case, she can
5494 /// still Bob to generate one on her behalf.
5495 ///
5496 /// Due to the complexity of verifying such signatures, many
5497 /// OpenPGP implementations do not support this feature.
5498 ///
5499 /// # Examples
5500 ///
5501 /// ```
5502 /// use sequoia_openpgp as openpgp;
5503 /// use openpgp::cert::prelude::*;
5504 /// use openpgp::packet::prelude::*;
5505 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
5506 /// use openpgp::policy::StandardPolicy;
5507 /// use openpgp::types::RevocationKey;
5508 ///
5509 /// # fn main() -> openpgp::Result<()> {
5510 /// let p = &StandardPolicy::new();
5511 ///
5512 /// let (alice, _) = CertBuilder::new().add_userid("Alice").generate()?;
5513 /// let mut alices_signer = alice.primary_key().key()
5514 /// .clone().parts_into_secret()?.into_keypair()?;
5515 ///
5516 /// let (bob, _) = CertBuilder::new().add_userid("Bob").generate()?;
5517 ///
5518 /// let template = alice.with_policy(p, None)?.direct_key_signature()
5519 /// .expect("CertBuilder always includes a direct key signature");
5520 /// let sig = SignatureBuilder::from(template.clone())
5521 /// // Add to any revocation keys inherited from template.
5522 /// .add_revocation_key(
5523 /// RevocationKey::new(bob.primary_key().key().pk_algo(), bob.fingerprint(), false),
5524 /// )?
5525 /// .sign_direct_key(&mut alices_signer, None)?;
5526 /// # assert_eq!(sig
5527 /// # .hashed_area()
5528 /// # .iter()
5529 /// # .filter(|sp| sp.tag() == SubpacketTag::RevocationKey)
5530 /// # .count(),
5531 /// # 1);
5532 ///
5533 /// // Merge in the new signature.
5534 /// let alice = alice.insert_packets(sig)?.0;
5535 /// # assert_eq!(alice.bad_signatures().count(), 0);
5536 /// # assert_eq!(alice.primary_key().self_signatures().count(), 2);
5537 /// # Ok(()) }
5538 /// ```
5539 pub fn add_revocation_key(mut self, rk: RevocationKey) -> Result<Self> {
5540 self.hashed_area.add(Subpacket::new(
5541 SubpacketValue::RevocationKey(rk),
5542 true)?)?;
5543
5544 Ok(self)
5545 }
5546
5547 /// Sets the Issuer subpacket.
5548 ///
5549 /// Adds an [Issuer subpacket] to the hashed subpacket area.
5550 /// Unlike [`add_issuer`], this function first removes any
5551 /// existing Issuer subpackets from the hashed and unhashed
5552 /// subpacket area.
5553 ///
5554 /// [Issuer subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
5555 /// [`add_issuer`]: super::SignatureBuilder::add_issuer()
5556 ///
5557 /// The Issuer subpacket is used when processing a signature to
5558 /// identify which certificate created the signature. Even though this
5559 /// information is self-authenticating (the act of validating the
5560 /// signature authenticates the subpacket), it is stored in the
5561 /// hashed subpacket area. This has the advantage that the signer
5562 /// authenticates the set of issuers. Furthermore, it makes
5563 /// handling of the resulting signatures more robust: If there are
5564 /// two signatures that are equal modulo the contents of the
5565 /// unhashed area, there is the question of how to merge the
5566 /// information in the unhashed areas. Storing issuer information
5567 /// in the hashed area avoids this problem.
5568 ///
5569 /// When creating a signature using a SignatureBuilder or the
5570 /// [streaming `Signer`], it is not necessary to explicitly set
5571 /// this subpacket: those functions automatically set both the
5572 /// [Issuer Fingerprint subpacket] (set using
5573 /// [`SignatureBuilder::set_issuer_fingerprint`]) and the Issuer
5574 /// subpacket, if they have not been set explicitly.
5575 ///
5576 /// [streaming `Signer`]: crate::serialize::stream::Signer
5577 /// [Issuer Fingerprint subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
5578 /// [`SignatureBuilder::set_issuer_fingerprint`]: super::SignatureBuilder::set_issuer_fingerprint()
5579 ///
5580 /// # Examples
5581 ///
5582 /// It is possible to use the same key material with different
5583 /// OpenPGP keys. This is useful when the OpenPGP format is
5584 /// upgraded, but not all deployed implementations support the new
5585 /// format. Here, Alice signs a message, and adds the fingerprint
5586 /// of her v4 key and her v5 key indicating that the recipient can
5587 /// use either key to verify the message:
5588 ///
5589 /// ```
5590 /// use sequoia_openpgp as openpgp;
5591 /// # use openpgp::cert::prelude::*;
5592 /// use openpgp::packet::prelude::*;
5593 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
5594 /// use openpgp::types::SignatureType;
5595 ///
5596 /// # fn main() -> openpgp::Result<()> {
5597 /// #
5598 /// # let (alicev4, _) =
5599 /// # CertBuilder::general_purpose(Some("alice@example.org"))
5600 /// # .generate()?;
5601 /// # let mut alices_signer = alicev4.primary_key().key().clone().parts_into_secret()?.into_keypair()?;
5602 /// # let (alicev5, _) =
5603 /// # CertBuilder::general_purpose(Some("alice@example.org"))
5604 /// # .generate()?;
5605 /// #
5606 /// let msg = b"Hi!";
5607 ///
5608 /// let sig = SignatureBuilder::new(SignatureType::Binary)
5609 /// .set_issuer(alicev4.keyid())?
5610 /// .add_issuer(alicev5.keyid())?
5611 /// .sign_message(&mut alices_signer, msg)?;
5612 /// # let mut sig = sig;
5613 /// # assert!(sig.verify_message(alices_signer.public(), msg).is_ok());
5614 /// # assert_eq!(sig
5615 /// # .hashed_area()
5616 /// # .iter()
5617 /// # .filter(|sp| sp.tag() == SubpacketTag::Issuer)
5618 /// # .count(),
5619 /// # 2);
5620 /// # assert_eq!(sig
5621 /// # .hashed_area()
5622 /// # .iter()
5623 /// # .filter(|sp| sp.tag() == SubpacketTag::IssuerFingerprint)
5624 /// # .count(),
5625 /// # 0);
5626 /// # Ok(()) }
5627 /// ```
5628 pub fn set_issuer(mut self, id: KeyID) -> Result<Self> {
5629 self.hashed_area.replace(Subpacket::new(
5630 SubpacketValue::Issuer(id),
5631 false)?)?;
5632 self.unhashed_area.remove_all(SubpacketTag::Issuer);
5633
5634 Ok(self)
5635 }
5636
5637 /// Adds an Issuer subpacket.
5638 ///
5639 /// Adds an [Issuer subpacket] to the hashed subpacket area.
5640 /// Unlike [`set_issuer`], this function does not first remove any
5641 /// existing Issuer subpacket from neither the hashed nor the
5642 /// unhashed subpacket area.
5643 ///
5644 /// [Issuer subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
5645 /// [`set_issuer`]: super::SignatureBuilder::set_issuer()
5646 ///
5647 /// The Issuer subpacket is used when processing a signature to
5648 /// identify which certificate created the signature. Even though this
5649 /// information is self-authenticating (the act of validating the
5650 /// signature authenticates the subpacket), it is stored in the
5651 /// hashed subpacket area. This has the advantage that the signer
5652 /// authenticates the set of issuers. Furthermore, it makes
5653 /// handling of the resulting signatures more robust: If there are
5654 /// two signatures that are equal modulo the contents of the
5655 /// unhashed area, there is the question of how to merge the
5656 /// information in the unhashed areas. Storing issuer information
5657 /// in the hashed area avoids this problem.
5658 ///
5659 /// When creating a signature using a SignatureBuilder or the
5660 /// [streaming `Signer`], it is not necessary to explicitly set
5661 /// this subpacket: those functions automatically set both the
5662 /// [Issuer Fingerprint subpacket] (set using
5663 /// [`SignatureBuilder::set_issuer_fingerprint`]) and the Issuer
5664 /// subpacket, if they have not been set explicitly.
5665 ///
5666 /// [streaming `Signer`]: crate::serialize::stream::Signer
5667 /// [Issuer Fingerprint subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
5668 /// [`SignatureBuilder::set_issuer_fingerprint`]: super::SignatureBuilder::set_issuer_fingerprint()
5669 ///
5670 /// # Examples
5671 ///
5672 /// It is possible to use the same key material with different
5673 /// OpenPGP keys. This is useful when the OpenPGP format is
5674 /// upgraded, but not all deployed implementations support the new
5675 /// format. Here, Alice signs a message, and adds the fingerprint
5676 /// of her v4 key and her v5 key indicating that the recipient can
5677 /// use either key to verify the message:
5678 ///
5679 /// ```
5680 /// use sequoia_openpgp as openpgp;
5681 /// # use openpgp::cert::prelude::*;
5682 /// use openpgp::packet::prelude::*;
5683 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
5684 /// use openpgp::types::SignatureType;
5685 ///
5686 /// # fn main() -> openpgp::Result<()> {
5687 /// #
5688 /// # let (alicev4, _) =
5689 /// # CertBuilder::general_purpose(Some("alice@example.org"))
5690 /// # .generate()?;
5691 /// # let mut alices_signer = alicev4.primary_key().key().clone().parts_into_secret()?.into_keypair()?;
5692 /// # let (alicev5, _) =
5693 /// # CertBuilder::general_purpose(Some("alice@example.org"))
5694 /// # .generate()?;
5695 /// #
5696 /// let msg = b"Hi!";
5697 ///
5698 /// let sig = SignatureBuilder::new(SignatureType::Binary)
5699 /// .set_issuer(alicev4.keyid())?
5700 /// .add_issuer(alicev5.keyid())?
5701 /// .sign_message(&mut alices_signer, msg)?;
5702 /// # let mut sig = sig;
5703 /// # assert!(sig.verify_message(alices_signer.public(), msg).is_ok());
5704 /// # assert_eq!(sig
5705 /// # .hashed_area()
5706 /// # .iter()
5707 /// # .filter(|sp| sp.tag() == SubpacketTag::Issuer)
5708 /// # .count(),
5709 /// # 2);
5710 /// # assert_eq!(sig
5711 /// # .hashed_area()
5712 /// # .iter()
5713 /// # .filter(|sp| sp.tag() == SubpacketTag::IssuerFingerprint)
5714 /// # .count(),
5715 /// # 0);
5716 /// # Ok(()) }
5717 /// ```
5718 pub fn add_issuer(mut self, id: KeyID) -> Result<Self> {
5719 self.hashed_area.add(Subpacket::new(
5720 SubpacketValue::Issuer(id),
5721 false)?)?;
5722
5723 Ok(self)
5724 }
5725
5726 /// Sets a Notation Data subpacket.
5727 ///
5728 /// Adds a [Notation Data subpacket] to the hashed subpacket area.
5729 /// Unlike the [`SignatureBuilder::add_notation`] method, this
5730 /// function first removes any existing Notation Data subpacket
5731 /// with the specified name from the hashed subpacket area.
5732 ///
5733 /// [Notation Data subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
5734 /// [`SignatureBuilder::add_notation`]: super::SignatureBuilder::add_notation()
5735 ///
5736 /// Notations are key-value pairs. They can be used by
5737 /// applications to annotate signatures in a structured way. For
5738 /// instance, they can define additional, application-specific
5739 /// security requirements. Because they are functionally
5740 /// equivalent to subpackets, they can also be used for OpenPGP
5741 /// extensions. This is how the [Intended Recipient subpacket]
5742 /// started life.
5743 ///
5744 /// [Intended Recipient subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-intended-recipient-fingerpr
5745 ///
5746 /// Notation names are structured, and are divided into two
5747 /// namespaces: the user namespace and the IETF namespace. Names
5748 /// in the user namespace have the form `name@example.org` and
5749 /// their meaning is defined by the owner of the domain. The
5750 /// meaning of the notation `name@example.org`, for instance, is
5751 /// defined by whoever controls `example.org`. Names in the IETF
5752 /// namespace do not contain an `@` and are managed by IANA. See
5753 /// [Section 5.2.3.24 of RFC 9580] for details.
5754 ///
5755 /// [Section 5.2.3.24 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
5756 ///
5757 /// # Examples
5758 ///
5759 /// Adds two [social proofs] to a certificate's primary User ID.
5760 /// This first clears any social proofs.
5761 ///
5762 /// [social proofs]: https://metacode.biz/openpgp/proofs
5763 ///
5764 /// ```
5765 /// use sequoia_openpgp as openpgp;
5766 /// use openpgp::cert::prelude::*;
5767 /// use openpgp::packet::prelude::*;
5768 /// use openpgp::packet::signature::subpacket::NotationDataFlags;
5769 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
5770 /// use openpgp::policy::StandardPolicy;
5771 ///
5772 /// # fn main() -> openpgp::Result<()> {
5773 /// let p = &StandardPolicy::new();
5774 ///
5775 /// let (cert, _) = CertBuilder::new().add_userid("Wiktor").generate()?;
5776 /// let mut signer = cert.primary_key().key()
5777 /// .clone().parts_into_secret()?.into_keypair()?;
5778 ///
5779 /// let vc = cert.with_policy(p, None)?;
5780 /// let ua = vc.primary_userid().expect("Added a User ID");
5781 ///
5782 /// let template = ua.binding_signature();
5783 /// let sig = SignatureBuilder::from(template.clone())
5784 /// .set_notation("proof@metacode.biz", "https://metacode.biz/@wiktor",
5785 /// NotationDataFlags::empty().set_human_readable(), false)?
5786 /// .add_notation("proof@metacode.biz", "https://news.ycombinator.com/user?id=wiktor-k",
5787 /// NotationDataFlags::empty().set_human_readable(), false)?
5788 /// .sign_userid_binding(&mut signer, None, ua.userid())?;
5789 /// # assert_eq!(sig
5790 /// # .hashed_area()
5791 /// # .iter()
5792 /// # .filter(|sp| sp.tag() == SubpacketTag::NotationData)
5793 /// # .count(),
5794 /// # 3);
5795 ///
5796 /// // Merge in the new signature.
5797 /// let cert = cert.insert_packets(sig)?.0;
5798 /// # assert_eq!(cert.bad_signatures().count(), 0);
5799 /// # Ok(()) }
5800 /// ```
5801 pub fn set_notation<N, V, F>(mut self, name: N, value: V, flags: F,
5802 critical: bool)
5803 -> Result<Self>
5804 where N: AsRef<str>,
5805 V: AsRef<[u8]>,
5806 F: Into<Option<NotationDataFlags>>,
5807 {
5808 self.hashed_area.packets.retain(|s| {
5809 ! matches!(
5810 s.value,
5811 SubpacketValue::NotationData(ref v) if v.name == name.as_ref())
5812 });
5813 self.add_notation(name.as_ref(), value.as_ref(),
5814 flags.into().unwrap_or_else(NotationDataFlags::empty),
5815 critical)
5816 }
5817
5818 /// Adds a Notation Data subpacket.
5819 ///
5820 /// Adds a [Notation Data subpacket] to the hashed subpacket area.
5821 /// Unlike the [`SignatureBuilder::set_notation`] method, this
5822 /// function does not first remove any existing Notation Data
5823 /// subpacket with the specified name from the hashed subpacket
5824 /// area.
5825 ///
5826 /// [Notation Data subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
5827 /// [`SignatureBuilder::set_notation`]: super::SignatureBuilder::set_notation()
5828 ///
5829 /// Notations are key-value pairs. They can be used by
5830 /// applications to annotate signatures in a structured way. For
5831 /// instance, they can define additional, application-specific
5832 /// security requirements. Because they are functionally
5833 /// equivalent to subpackets, they can also be used for OpenPGP
5834 /// extensions. This is how the [Intended Recipient subpacket]
5835 /// started life.
5836 ///
5837 /// [Intended Recipient subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-intended-recipient-fingerpr
5838 ///
5839 /// Notation names are structured, and are divided into two
5840 /// namespaces: the user namespace and the IETF namespace. Names
5841 /// in the user namespace have the form `name@example.org` and
5842 /// their meaning is defined by the owner of the domain. The
5843 /// meaning of the notation `name@example.org`, for instance, is
5844 /// defined by whoever controls `example.org`. Names in the IETF
5845 /// namespace do not contain an `@` and are managed by IANA. See
5846 /// [Section 5.2.3.24 of RFC 9580] for details.
5847 ///
5848 /// [Section 5.2.3.24 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.24
5849 ///
5850 /// # Examples
5851 ///
5852 /// Adds two new [social proofs] to a certificate's primary User
5853 /// ID. A more sophisticated program will check that the new
5854 /// notations aren't already present.
5855 ///
5856 /// [social proofs]: https://metacode.biz/openpgp/proofs
5857 ///
5858 /// ```
5859 /// use sequoia_openpgp as openpgp;
5860 /// use openpgp::cert::prelude::*;
5861 /// use openpgp::packet::prelude::*;
5862 /// use openpgp::packet::signature::subpacket::NotationDataFlags;
5863 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
5864 /// use openpgp::policy::StandardPolicy;
5865 ///
5866 /// # fn main() -> openpgp::Result<()> {
5867 /// let p = &StandardPolicy::new();
5868 ///
5869 /// let (cert, _) = CertBuilder::new().add_userid("Wiktor").generate()?;
5870 /// let mut signer = cert.primary_key().key()
5871 /// .clone().parts_into_secret()?.into_keypair()?;
5872 ///
5873 /// let vc = cert.with_policy(p, None)?;
5874 /// let ua = vc.primary_userid().expect("Added a User ID");
5875 ///
5876 /// let template = ua.binding_signature();
5877 /// let sig = SignatureBuilder::from(template.clone())
5878 /// .add_notation("proof@metacode.biz", "https://metacode.biz/@wiktor",
5879 /// NotationDataFlags::empty().set_human_readable(), false)?
5880 /// .add_notation("proof@metacode.biz", "https://news.ycombinator.com/user?id=wiktor-k",
5881 /// NotationDataFlags::empty().set_human_readable(), false)?
5882 /// .sign_userid_binding(&mut signer, None, ua.userid())?;
5883 /// # assert_eq!(sig
5884 /// # .hashed_area()
5885 /// # .iter()
5886 /// # .filter(|sp| sp.tag() == SubpacketTag::NotationData)
5887 /// # .count(),
5888 /// # 3);
5889 ///
5890 /// // Merge in the new signature.
5891 /// let cert = cert.insert_packets(sig)?.0;
5892 /// # assert_eq!(cert.bad_signatures().count(), 0);
5893 /// # Ok(()) }
5894 /// ```
5895 pub fn add_notation<N, V, F>(mut self, name: N, value: V, flags: F,
5896 critical: bool)
5897 -> Result<Self>
5898 where N: AsRef<str>,
5899 V: AsRef<[u8]>,
5900 F: Into<Option<NotationDataFlags>>,
5901 {
5902 self.hashed_area.add(Subpacket::new(SubpacketValue::NotationData(
5903 NotationData::new(name.as_ref(), value.as_ref(),
5904 flags.into().unwrap_or_else(NotationDataFlags::empty))),
5905 critical)?)?;
5906 Ok(self)
5907 }
5908
5909 /// Sets the Preferred Hash Algorithms subpacket.
5910 ///
5911 /// Replaces any [Preferred Hash Algorithms subpacket] in the
5912 /// hashed subpacket area with a new subpacket containing the
5913 /// specified value. That is, this function first removes any
5914 /// Preferred Hash Algorithms subpacket from the hashed subpacket
5915 /// area, and then adds a new one.
5916 ///
5917 /// A Preferred Hash Algorithms subpacket lists what hash
5918 /// algorithms the user prefers. When signing a message that
5919 /// should be verified by a particular recipient, the OpenPGP
5920 /// implementation should not use an algorithm that is not on this
5921 /// list.
5922 ///
5923 /// [Preferred Hash Algorithms subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.16
5924 ///
5925 /// This subpacket is a type of preference. When looking up a
5926 /// preference, an OpenPGP implementation should first look for
5927 /// the subpacket on the binding signature of the User ID or the
5928 /// User Attribute used to locate the certificate (or the primary
5929 /// User ID, if it was addressed by Key ID or fingerprint). If
5930 /// the binding signature doesn't contain the subpacket, then the
5931 /// direct key signature should be checked. See the
5932 /// [`Preferences`] trait for details.
5933 ///
5934 /// Unless addressing different User IDs really should result in
5935 /// different behavior, it is best to only set this preference on
5936 /// the direct key signature. This guarantees that even if some
5937 /// or all User IDs are stripped, the behavior remains consistent.
5938 ///
5939 /// [`Preferences`]: crate::cert::Preferences
5940 ///
5941 /// # Examples
5942 ///
5943 /// ```
5944 /// use sequoia_openpgp as openpgp;
5945 /// use openpgp::cert::prelude::*;
5946 /// use openpgp::packet::prelude::*;
5947 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
5948 /// use openpgp::policy::StandardPolicy;
5949 /// use openpgp::types::HashAlgorithm;
5950 ///
5951 /// # fn main() -> openpgp::Result<()> {
5952 /// let p = &StandardPolicy::new();
5953 ///
5954 /// let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
5955 /// let mut signer = cert.primary_key().key()
5956 /// .clone().parts_into_secret()?.into_keypair()?;
5957 ///
5958 /// let vc = cert.with_policy(p, None)?;
5959 ///
5960 /// let template = vc.direct_key_signature()
5961 /// .expect("CertBuilder always includes a direct key signature");
5962 /// let sig = SignatureBuilder::from(template.clone())
5963 /// .set_preferred_hash_algorithms(
5964 /// vec![ HashAlgorithm::SHA512,
5965 /// HashAlgorithm::SHA256,
5966 /// ])?
5967 /// .sign_direct_key(&mut signer, None)?;
5968 /// # assert_eq!(sig
5969 /// # .hashed_area()
5970 /// # .iter()
5971 /// # .filter(|sp| sp.tag() == SubpacketTag::PreferredHashAlgorithms)
5972 /// # .count(),
5973 /// # 1);
5974 ///
5975 /// // Merge in the new signature.
5976 /// let cert = cert.insert_packets(sig)?.0;
5977 /// # assert_eq!(cert.bad_signatures().count(), 0);
5978 /// # Ok(()) }
5979 /// ```
5980 pub fn set_preferred_hash_algorithms(mut self,
5981 preferences: Vec<HashAlgorithm>)
5982 -> Result<Self> {
5983 self.hashed_area.replace(Subpacket::new(
5984 SubpacketValue::PreferredHashAlgorithms(preferences),
5985 false)?)?;
5986
5987 Ok(self)
5988 }
5989
5990 /// Sets the Preferred Compression Algorithms subpacket.
5991 ///
5992 /// Replaces any [Preferred Compression Algorithms subpacket] in
5993 /// the hashed subpacket area with a new subpacket containing the
5994 /// specified value. That is, this function first removes any
5995 /// Preferred Compression Algorithms subpacket from the hashed
5996 /// subpacket area, and then adds a new one.
5997 ///
5998 /// A Preferred Compression Algorithms subpacket lists what
5999 /// compression algorithms the user prefers. When compressing a
6000 /// message for a recipient, the OpenPGP implementation should not
6001 /// use an algorithm that is not on the list.
6002 ///
6003 /// [Preferred Compression Algorithms subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.17
6004 ///
6005 /// This subpacket is a type of preference. When looking up a
6006 /// preference, an OpenPGP implementation should first look for
6007 /// the subpacket on the binding signature of the User ID or the
6008 /// User Attribute used to locate the certificate (or the primary
6009 /// User ID, if it was addressed by Key ID or fingerprint). If
6010 /// the binding signature doesn't contain the subpacket, then the
6011 /// direct key signature should be checked. See the
6012 /// [`Preferences`] trait for details.
6013 ///
6014 /// Unless addressing different User IDs really should result in
6015 /// different behavior, it is best to only set this preference on
6016 /// the direct key signature. This guarantees that even if some
6017 /// or all User IDs are stripped, the behavior remains consistent.
6018 ///
6019 /// [`Preferences`]: crate::cert::Preferences
6020 ///
6021 /// # Examples
6022 ///
6023 /// ```
6024 /// use sequoia_openpgp as openpgp;
6025 /// use openpgp::cert::prelude::*;
6026 /// use openpgp::packet::prelude::*;
6027 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
6028 /// use openpgp::policy::StandardPolicy;
6029 /// use openpgp::types::CompressionAlgorithm;
6030 ///
6031 /// # fn main() -> openpgp::Result<()> {
6032 /// let p = &StandardPolicy::new();
6033 ///
6034 /// let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
6035 /// let mut signer = cert.primary_key().key()
6036 /// .clone().parts_into_secret()?.into_keypair()?;
6037 ///
6038 /// let vc = cert.with_policy(p, None)?;
6039 ///
6040 /// let template = vc.direct_key_signature()
6041 /// .expect("CertBuilder always includes a direct key signature");
6042 /// let sig = SignatureBuilder::from(template.clone())
6043 /// .set_preferred_compression_algorithms(
6044 /// vec![ CompressionAlgorithm::Zlib,
6045 /// CompressionAlgorithm::Zip,
6046 /// CompressionAlgorithm::BZip2,
6047 /// ])?
6048 /// .sign_direct_key(&mut signer, None)?;
6049 /// # assert_eq!(sig
6050 /// # .hashed_area()
6051 /// # .iter()
6052 /// # .filter(|sp| sp.tag() == SubpacketTag::PreferredCompressionAlgorithms)
6053 /// # .count(),
6054 /// # 1);
6055 ///
6056 /// // Merge in the new signature.
6057 /// let cert = cert.insert_packets(sig)?.0;
6058 /// # assert_eq!(cert.bad_signatures().count(), 0);
6059 /// # Ok(()) }
6060 /// ```
6061 pub fn set_preferred_compression_algorithms(mut self,
6062 preferences: Vec<CompressionAlgorithm>)
6063 -> Result<Self> {
6064 self.hashed_area.replace(Subpacket::new(
6065 SubpacketValue::PreferredCompressionAlgorithms(preferences),
6066 false)?)?;
6067
6068 Ok(self)
6069 }
6070
6071 /// Sets the Key Server Preferences subpacket.
6072 ///
6073 /// Replaces any [Key Server Preferences subpacket] in the hashed
6074 /// subpacket area with a new subpacket containing the specified
6075 /// value. That is, this function first removes any Key Server
6076 /// Preferences subpacket from the hashed subpacket area, and then
6077 /// adds a new one.
6078 ///
6079 /// The Key Server Preferences subpacket indicates to key servers
6080 /// how they should handle the certificate.
6081 ///
6082 /// [Key Server Preferences subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.25
6083 ///
6084 /// This subpacket is a type of preference. When looking up a
6085 /// preference, an OpenPGP implementation should first look for
6086 /// the subpacket on the binding signature of the User ID or the
6087 /// User Attribute used to locate the certificate (or the primary
6088 /// User ID, if it was addressed by Key ID or fingerprint). If
6089 /// the binding signature doesn't contain the subpacket, then the
6090 /// direct key signature should be checked. See the
6091 /// [`Preferences`] trait for details.
6092 ///
6093 /// Unless addressing different User IDs really should result in
6094 /// different behavior, it is best to only set this preference on
6095 /// the direct key signature. This guarantees that even if some
6096 /// or all User IDs are stripped, the behavior remains consistent.
6097 ///
6098 /// [`Preferences`]: crate::cert::Preferences
6099 ///
6100 /// # Examples
6101 ///
6102 /// ```
6103 /// use sequoia_openpgp as openpgp;
6104 /// use openpgp::cert::prelude::*;
6105 /// use openpgp::packet::prelude::*;
6106 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
6107 /// use openpgp::policy::StandardPolicy;
6108 /// use openpgp::types::KeyServerPreferences;
6109 ///
6110 /// # fn main() -> openpgp::Result<()> {
6111 /// let p = &StandardPolicy::new();
6112 ///
6113 /// let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
6114 /// let mut signer = cert.primary_key().key()
6115 /// .clone().parts_into_secret()?.into_keypair()?;
6116 ///
6117 /// let vc = cert.with_policy(p, None)?;
6118 ///
6119 /// let sig = vc.direct_key_signature()
6120 /// .expect("CertBuilder always includes a direct key signature");
6121 /// let sig =
6122 /// SignatureBuilder::from(sig.clone())
6123 /// .set_key_server_preferences(
6124 /// KeyServerPreferences::empty().set_no_modify())?
6125 /// .sign_direct_key(&mut signer, None)?;
6126 /// # assert_eq!(sig
6127 /// # .hashed_area()
6128 /// # .iter()
6129 /// # .filter(|sp| sp.tag() == SubpacketTag::KeyServerPreferences)
6130 /// # .count(),
6131 /// # 1);
6132 ///
6133 /// // Merge in the new signature.
6134 /// let cert = cert.insert_packets(sig)?.0;
6135 /// # assert_eq!(cert.bad_signatures().count(), 0);
6136 /// # Ok(()) }
6137 /// ```
6138 pub fn set_key_server_preferences(mut self,
6139 preferences: KeyServerPreferences)
6140 -> Result<Self> {
6141 self.hashed_area.replace(Subpacket::new(
6142 SubpacketValue::KeyServerPreferences(preferences),
6143 false)?)?;
6144
6145 Ok(self)
6146 }
6147
6148 /// Sets the Preferred Key Server subpacket.
6149 ///
6150 /// Adds a [Preferred Key Server subpacket] to the hashed
6151 /// subpacket area. This function first removes any Preferred Key
6152 /// Server subpacket from the hashed subpacket area.
6153 ///
6154 /// [Preferred Key Server subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.26
6155 ///
6156 /// The Preferred Key Server subpacket contains a link to a key
6157 /// server where the certificate holder plans to publish updates
6158 /// to their certificate (e.g., extensions to the expiration time,
6159 /// new subkeys, revocation certificates).
6160 ///
6161 /// The Preferred Key Server subpacket should be handled
6162 /// cautiously, because it can be used by a certificate holder to
6163 /// track communication partners.
6164 ///
6165 /// This subpacket is a type of preference. When looking up a
6166 /// preference, an OpenPGP implementation should first look for
6167 /// the subpacket on the binding signature of the User ID or the
6168 /// User Attribute used to locate the certificate (or the primary
6169 /// User ID, if it was addressed by Key ID or fingerprint). If
6170 /// the binding signature doesn't contain the subpacket, then the
6171 /// direct key signature should be checked. See the
6172 /// [`Preferences`] trait for details.
6173 ///
6174 /// Unless addressing different User IDs really should result in
6175 /// different behavior, it is best to only set this preference on
6176 /// the direct key signature. This guarantees that even if some
6177 /// or all User IDs are stripped, the behavior remains consistent.
6178 ///
6179 /// [`Preferences`]: crate::cert::Preferences
6180 ///
6181 /// # Examples
6182 ///
6183 /// ```
6184 /// use sequoia_openpgp as openpgp;
6185 /// use openpgp::cert::prelude::*;
6186 /// use openpgp::packet::prelude::*;
6187 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
6188 /// use openpgp::policy::StandardPolicy;
6189 ///
6190 /// # fn main() -> openpgp::Result<()> {
6191 /// let p = &StandardPolicy::new();
6192 ///
6193 /// let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
6194 /// let mut signer = cert.primary_key().key()
6195 /// .clone().parts_into_secret()?.into_keypair()?;
6196 ///
6197 /// let vc = cert.with_policy(p, None)?;
6198 ///
6199 /// let sig = vc.direct_key_signature()
6200 /// .expect("CertBuilder always includes a direct key signature");
6201 /// let sig =
6202 /// SignatureBuilder::from(sig.clone())
6203 /// .set_preferred_key_server(&"https://keys.openpgp.org")?
6204 /// .sign_direct_key(&mut signer, None)?;
6205 /// # assert_eq!(sig
6206 /// # .hashed_area()
6207 /// # .iter()
6208 /// # .filter(|sp| sp.tag() == SubpacketTag::PreferredKeyServer)
6209 /// # .count(),
6210 /// # 1);
6211 ///
6212 /// // Merge in the new signature.
6213 /// let cert = cert.insert_packets(sig)?.0;
6214 /// # assert_eq!(cert.bad_signatures().count(), 0);
6215 /// # Ok(()) }
6216 /// ```
6217 pub fn set_preferred_key_server<U>(mut self, uri: U)
6218 -> Result<Self>
6219 where U: AsRef<[u8]>,
6220 {
6221 self.hashed_area.replace(Subpacket::new(
6222 SubpacketValue::PreferredKeyServer(uri.as_ref().to_vec()),
6223 false)?)?;
6224
6225 Ok(self)
6226 }
6227
6228 /// Sets the Primary User ID subpacket.
6229 ///
6230 /// Adds a [Primary User ID subpacket] to the hashed subpacket
6231 /// area. This function first removes any Primary User ID
6232 /// subpacket from the hashed subpacket area.
6233 ///
6234 /// [Primary User ID subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.27
6235 ///
6236 /// The Primary User ID subpacket indicates whether the associated
6237 /// User ID or User Attribute should be considered the primary
6238 /// User ID. It is possible that this is set on multiple User
6239 /// IDs. See the documentation for [`ValidCert::primary_userid`] for
6240 /// an explanation of how Sequoia resolves this ambiguity.
6241 ///
6242 /// [`ValidCert::primary_userid`]: crate::cert::ValidCert::primary_userid()
6243 ///
6244 /// # Examples
6245 ///
6246 /// Change the primary User ID:
6247 ///
6248 /// ```
6249 /// use sequoia_openpgp as openpgp;
6250 /// use openpgp::cert::prelude::*;
6251 /// use openpgp::packet::prelude::*;
6252 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
6253 /// use openpgp::policy::StandardPolicy;
6254 ///
6255 /// # fn main() -> openpgp::Result<()> {
6256 /// let p = &StandardPolicy::new();
6257 ///
6258 /// let club = "Alice <alice@club.org>";
6259 /// let home = "Alice <alice@home.org>";
6260 ///
6261 /// // CertBuilder makes the first User ID (club) the primary User ID.
6262 /// let (cert, _) = CertBuilder::new()
6263 /// # // Create it in the past.
6264 /// # .set_creation_time(std::time::SystemTime::now()
6265 /// # - std::time::Duration::new(10, 0))
6266 /// .add_userid(club)
6267 /// .add_userid(home)
6268 /// .generate()?;
6269 /// # assert_eq!(cert.userids().count(), 2);
6270 /// assert_eq!(cert.with_policy(p, None)?.primary_userid().unwrap().userid(),
6271 /// &UserID::from(club));
6272 ///
6273 /// // Make the `home` User ID the primary User ID.
6274 ///
6275 /// // Derive a signer.
6276 /// let pk = cert.primary_key().key();
6277 /// let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;
6278 ///
6279 /// let mut sig = None;
6280 /// for ua in cert.with_policy(p, None)?.userids() {
6281 /// if ua.userid() == &UserID::from(home) {
6282 /// sig = Some(SignatureBuilder::from(ua.binding_signature().clone())
6283 /// .set_primary_userid(true)?
6284 /// .sign_userid_binding(&mut signer, pk, ua.userid())?);
6285 /// # assert_eq!(sig.as_ref().unwrap()
6286 /// # .hashed_area()
6287 /// # .iter()
6288 /// # .filter(|sp| sp.tag() == SubpacketTag::PrimaryUserID)
6289 /// # .count(),
6290 /// # 1);
6291 /// break;
6292 /// }
6293 /// }
6294 /// assert!(sig.is_some());
6295 ///
6296 /// let cert = cert.insert_packets(sig)?.0;
6297 ///
6298 /// assert_eq!(cert.with_policy(p, None)?.primary_userid().unwrap().userid(),
6299 /// &UserID::from(home));
6300 /// # Ok(())
6301 /// # }
6302 /// ```
6303 pub fn set_primary_userid(mut self, primary: bool) -> Result<Self> {
6304 self.hashed_area.replace(Subpacket::new(
6305 SubpacketValue::PrimaryUserID(primary),
6306 true)?)?;
6307
6308 Ok(self)
6309 }
6310
6311 /// Sets the Policy URI subpacket.
6312 ///
6313 /// Adds a [Policy URI subpacket] to the hashed subpacket area.
6314 /// This function first removes any Policy URI subpacket from the
6315 /// hashed subpacket area.
6316 ///
6317 /// [Policy URI subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.28
6318 ///
6319 /// The Policy URI subpacket contains a link to a policy document,
6320 /// which contains information about the conditions under which
6321 /// the signature was made.
6322 ///
6323 /// This subpacket is a type of preference. When looking up a
6324 /// preference, an OpenPGP implementation should first look for
6325 /// the subpacket on the binding signature of the User ID or the
6326 /// User Attribute used to locate the certificate (or the primary
6327 /// User ID, if it was addressed by Key ID or fingerprint). If
6328 /// the binding signature doesn't contain the subpacket, then the
6329 /// direct key signature should be checked. See the
6330 /// [`Preferences`] trait for details.
6331 ///
6332 /// Unless addressing different User IDs really should result in
6333 /// different behavior, it is best to only set this preference on
6334 /// the direct key signature. This guarantees that even if some
6335 /// or all User IDs are stripped, the behavior remains consistent.
6336 ///
6337 /// [`Preferences`]: crate::cert::Preferences
6338 ///
6339 /// # Examples
6340 ///
6341 /// Alice updates her direct key signature to include a Policy URI
6342 /// subpacket:
6343 ///
6344 /// ```
6345 /// use sequoia_openpgp as openpgp;
6346 /// use openpgp::cert::prelude::*;
6347 /// use openpgp::packet::prelude::*;
6348 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
6349 /// use openpgp::policy::StandardPolicy;
6350 ///
6351 /// # fn main() -> openpgp::Result<()> {
6352 /// let p = &StandardPolicy::new();
6353 ///
6354 /// let (alice, _) = CertBuilder::new().add_userid("Alice").generate()?;
6355 /// let pk = alice.primary_key().key();
6356 /// let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;
6357 ///
6358 /// let sig = SignatureBuilder::from(
6359 /// alice
6360 /// .with_policy(p, None)?
6361 /// .direct_key_signature().expect("Direct key signature")
6362 /// .clone()
6363 /// )
6364 /// .set_policy_uri("https://example.org/~alice/signing-policy.txt")?
6365 /// .sign_direct_key(&mut signer, None)?;
6366 /// # let mut sig = sig;
6367 /// # sig.verify_direct_key(signer.public(), pk)?;
6368 /// # assert_eq!(sig
6369 /// # .hashed_area()
6370 /// # .iter()
6371 /// # .filter(|sp| sp.tag() == SubpacketTag::PolicyURI)
6372 /// # .count(),
6373 /// # 1);
6374 ///
6375 /// // Merge it into the certificate.
6376 /// let alice = alice.insert_packets(sig)?.0;
6377 /// #
6378 /// # assert_eq!(alice.bad_signatures().count(), 0);
6379 /// # Ok(())
6380 /// # }
6381 /// ```
6382 pub fn set_policy_uri<U>(mut self, uri: U) -> Result<Self>
6383 where U: AsRef<[u8]>,
6384 {
6385 self.hashed_area.replace(Subpacket::new(
6386 SubpacketValue::PolicyURI(uri.as_ref().to_vec()),
6387 false)?)?;
6388
6389 Ok(self)
6390 }
6391
6392 /// Sets the Key Flags subpacket.
6393 ///
6394 /// Adds a [Key Flags subpacket] to the hashed subpacket area.
6395 /// This function first removes any Key Flags subpacket from the
6396 /// hashed subpacket area.
6397 ///
6398 /// [Key Flags subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.29
6399 ///
6400 /// The Key Flags subpacket describes a key's capabilities
6401 /// (certification capable, signing capable, etc.). In the case
6402 /// of subkeys, the Key Flags are located on the subkey's binding
6403 /// signature. For primary keys, locating the correct Key Flags
6404 /// subpacket is more complex: First, the primary User ID is
6405 /// consulted. If the primary User ID contains a Key Flags
6406 /// subpacket, that is used. Otherwise, any direct key signature
6407 /// is considered. If that still doesn't contain a Key Flags
6408 /// packet, then the primary key should be assumed to be
6409 /// certification capable.
6410 ///
6411 /// # Examples
6412 ///
6413 /// Adds a new subkey, which is intended for encrypting data at
6414 /// rest, to a certificate:
6415 ///
6416 /// ```
6417 /// use sequoia_openpgp as openpgp;
6418 /// use openpgp::cert::prelude::*;
6419 /// use openpgp::packet::prelude::*;
6420 /// use openpgp::policy::StandardPolicy;
6421 /// use openpgp::types::{
6422 /// Curve,
6423 /// KeyFlags,
6424 /// SignatureType
6425 /// };
6426 ///
6427 /// # fn main() -> openpgp::Result<()> {
6428 /// let p = &StandardPolicy::new();
6429 ///
6430 /// // Generate a Cert, and create a keypair from the primary key.
6431 /// let (cert, _) = CertBuilder::new().generate()?;
6432 /// # assert_eq!(cert.keys().with_policy(p, None).alive().revoked(false)
6433 /// # .key_flags(&KeyFlags::empty().set_storage_encryption()).count(),
6434 /// # 0);
6435 /// let mut signer = cert.primary_key().key().clone()
6436 /// .parts_into_secret()?.into_keypair()?;
6437 ///
6438 /// // Generate a subkey and a binding signature.
6439 /// let subkey: Key<_, key::SubordinateRole>
6440 /// = Key6::generate_ecc(false, Curve::Cv25519)?
6441 /// .into();
6442 /// let builder = signature::SignatureBuilder::new(SignatureType::SubkeyBinding)
6443 /// .set_key_flags(KeyFlags::empty().set_storage_encryption())?;
6444 /// let binding = subkey.bind(&mut signer, &cert, builder)?;
6445 ///
6446 /// // Now merge the key and binding signature into the Cert.
6447 /// let cert = cert.insert_packets(vec![Packet::from(subkey),
6448 /// binding.into()])?.0;
6449 ///
6450 /// # assert_eq!(cert.keys().with_policy(p, None).alive().revoked(false)
6451 /// # .key_flags(&KeyFlags::empty().set_storage_encryption()).count(),
6452 /// # 1);
6453 /// # Ok(()) }
6454 /// ```
6455 pub fn set_key_flags(mut self, flags: KeyFlags) -> Result<Self> {
6456 self.hashed_area.replace(Subpacket::new(
6457 SubpacketValue::KeyFlags(flags),
6458 true)?)?;
6459
6460 Ok(self)
6461 }
6462
6463 /// Sets the Signer's User ID subpacket.
6464 ///
6465 /// Adds a [Signer's User ID subpacket] to the hashed subpacket
6466 /// area. This function first removes any Signer's User ID
6467 /// subpacket from the hashed subpacket area.
6468 ///
6469 /// [Signer's User ID subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.30
6470 ///
6471 /// The Signer's User ID subpacket indicates, which User ID made
6472 /// the signature. This is useful when a key has multiple User
6473 /// IDs, which correspond to different roles. For instance, it is
6474 /// not uncommon to use the same certificate in private as well as
6475 /// for a club.
6476 ///
6477 /// # Examples
6478 ///
6479 /// Sign a message being careful to set the Signer's User ID
6480 /// subpacket to the user's private identity and not their club
6481 /// identity:
6482 ///
6483 /// ```rust
6484 /// use sequoia_openpgp as openpgp;
6485 /// use openpgp::cert::prelude::*;
6486 /// use openpgp::packet::prelude::*;
6487 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
6488 /// use openpgp::types::SignatureType;
6489 ///
6490 /// # fn main() -> openpgp::Result<()> {
6491 /// let (cert, _) = CertBuilder::new()
6492 /// .add_userid("Alice <alice@home.org>")
6493 /// .add_userid("Alice (President) <alice@club.org>")
6494 /// .generate()?;
6495 /// let mut signer = cert.primary_key().key().clone()
6496 /// .parts_into_secret()?.into_keypair()?;
6497 ///
6498 /// let msg = "Speaking for myself, I agree.";
6499 ///
6500 /// let sig = SignatureBuilder::new(SignatureType::Binary)
6501 /// .set_signers_user_id(&b"Alice <alice@home.org>"[..])?
6502 /// .sign_message(&mut signer, msg)?;
6503 /// # let mut sig = sig;
6504 /// # assert!(sig.verify_message(signer.public(), msg).is_ok());
6505 /// # assert_eq!(sig
6506 /// # .hashed_area()
6507 /// # .iter()
6508 /// # .filter(|sp| sp.tag() == SubpacketTag::SignersUserID)
6509 /// # .count(),
6510 /// # 1);
6511 /// # Ok(()) }
6512 /// ```
6513 pub fn set_signers_user_id<U>(mut self, uid: U) -> Result<Self>
6514 where U: AsRef<[u8]>,
6515 {
6516 self.hashed_area.replace(Subpacket::new(
6517 SubpacketValue::SignersUserID(uid.as_ref().to_vec()),
6518 false)?)?;
6519
6520 Ok(self)
6521 }
6522
6523 /// Sets the value of the Reason for Revocation subpacket.
6524 ///
6525 /// Adds a [Reason For Revocation subpacket] to the hashed
6526 /// subpacket area. This function first removes any Reason For
6527 /// Revocation subpacket from the hashed subpacket
6528 /// area.
6529 ///
6530 /// [Reason For Revocation subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.31
6531 ///
6532 /// The Reason For Revocation subpacket indicates why a key, User
6533 /// ID, or User Attribute is being revoked. It includes both a
6534 /// machine-readable code, and a human-readable string. The code
6535 /// is essential as it indicates to the OpenPGP implementation
6536 /// that reads the certificate whether the key was compromised (a
6537 /// hard revocation), or is no longer used (a soft revocation).
6538 /// In the former case, the OpenPGP implementation must
6539 /// conservatively consider all past signatures as suspect whereas
6540 /// in the latter case, past signatures can still be considered
6541 /// valid.
6542 ///
6543 /// # Examples
6544 ///
6545 /// Revoke a certificate whose private key material has been
6546 /// compromised:
6547 ///
6548 /// ```rust
6549 /// use sequoia_openpgp as openpgp;
6550 /// use openpgp::cert::prelude::*;
6551 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
6552 /// use openpgp::policy::StandardPolicy;
6553 /// use openpgp::types::ReasonForRevocation;
6554 /// use openpgp::types::RevocationStatus;
6555 ///
6556 /// # fn main() -> openpgp::Result<()> {
6557 /// let p = &StandardPolicy::new();
6558 ///
6559 /// let (cert, _) = CertBuilder::new().generate()?;
6560 /// assert_eq!(RevocationStatus::NotAsFarAsWeKnow,
6561 /// cert.revocation_status(p, None));
6562 ///
6563 /// // Create and sign a revocation certificate.
6564 /// let mut signer = cert.primary_key().key().clone()
6565 /// .parts_into_secret()?.into_keypair()?;
6566 /// let sig = CertRevocationBuilder::new()
6567 /// .set_reason_for_revocation(ReasonForRevocation::KeyCompromised,
6568 /// b"It was the maid :/")?
6569 /// .build(&mut signer, &cert, None)?;
6570 ///
6571 /// // Merge it into the certificate.
6572 /// let cert = cert.insert_packets(sig.clone())?.0;
6573 ///
6574 /// // Now it's revoked.
6575 /// assert_eq!(RevocationStatus::Revoked(vec![ &sig ]),
6576 /// cert.revocation_status(p, None));
6577 /// # assert_eq!(sig
6578 /// # .hashed_area()
6579 /// # .iter()
6580 /// # .filter(|sp| sp.tag() == SubpacketTag::ReasonForRevocation)
6581 /// # .count(),
6582 /// # 1);
6583 /// # Ok(())
6584 /// # }
6585 /// ```
6586 pub fn set_reason_for_revocation<R>(mut self, code: ReasonForRevocation,
6587 reason: R)
6588 -> Result<Self>
6589 where R: AsRef<[u8]>,
6590 {
6591 self.hashed_area.replace(Subpacket::new(
6592 SubpacketValue::ReasonForRevocation {
6593 code,
6594 reason: reason.as_ref().to_vec(),
6595 },
6596 false)?)?;
6597
6598 Ok(self)
6599 }
6600
6601 /// Sets the Features subpacket.
6602 ///
6603 /// Adds a [Feature subpacket] to the hashed subpacket area. This
6604 /// function first removes any Feature subpacket from the hashed
6605 /// subpacket area.
6606 ///
6607 /// A Feature subpacket lists what OpenPGP features the user wants
6608 /// to use. When creating a message, features that the intended
6609 /// recipients do not support should not be used. However,
6610 /// because this information is rarely held up to date in
6611 /// practice, this information is only advisory, and
6612 /// implementations are allowed to infer what features the
6613 /// recipients support from contextual clues, e.g., their past
6614 /// behavior.
6615 ///
6616 /// [Feature subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.32
6617 /// [features]: crate::types::Features
6618 ///
6619 /// This subpacket is a type of preference. When looking up a
6620 /// preference, an OpenPGP implementation should first look for
6621 /// the subpacket on the binding signature of the User ID or the
6622 /// User Attribute used to locate the certificate (or the primary
6623 /// User ID, if it was addressed by Key ID or fingerprint). If
6624 /// the binding signature doesn't contain the subpacket, then the
6625 /// direct key signature should be checked. See the
6626 /// [`Preferences`] trait for details.
6627 ///
6628 /// Unless addressing different User IDs really should result in
6629 /// different behavior, it is best to only set this preference on
6630 /// the direct key signature. This guarantees that even if some
6631 /// or all User IDs are stripped, the behavior remains consistent.
6632 ///
6633 /// [`Preferences`]: crate::cert::Preferences
6634 ///
6635 /// # Examples
6636 ///
6637 /// Update a certificate's binding signatures to indicate support for AEAD:
6638 ///
6639 /// ```
6640 /// use sequoia_openpgp as openpgp;
6641 /// use openpgp::cert::prelude::*;
6642 /// use openpgp::packet::prelude::*;
6643 /// use openpgp::policy::StandardPolicy;
6644 /// use openpgp::types::{AEADAlgorithm, Features};
6645 ///
6646 /// # fn main() -> openpgp::Result<()> {
6647 /// use sequoia_openpgp::types::SymmetricAlgorithm;
6648 /// let p = &StandardPolicy::new();
6649 ///
6650 /// let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
6651 ///
6652 /// // Derive a signer (the primary key is always certification capable).
6653 /// let pk = cert.primary_key().key();
6654 /// let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;
6655 ///
6656 /// let mut sigs = Vec::new();
6657 ///
6658 /// let vc = cert.with_policy(p, None)?;
6659 ///
6660 /// if let Ok(sig) = vc.direct_key_signature() {
6661 /// sigs.push(
6662 /// SignatureBuilder::from(sig.clone())
6663 /// .set_preferred_aead_ciphersuites(vec![(SymmetricAlgorithm::AES256, AEADAlgorithm::EAX) ])?
6664 /// .set_features(
6665 /// sig.features().unwrap_or_else(Features::sequoia)
6666 /// .set_seipdv2())?
6667 /// .sign_direct_key(&mut signer, None)?);
6668 /// }
6669 ///
6670 /// for ua in vc.userids() {
6671 /// let sig = ua.binding_signature();
6672 /// sigs.push(
6673 /// SignatureBuilder::from(sig.clone())
6674 /// .set_preferred_aead_ciphersuites(vec![(SymmetricAlgorithm::AES256, AEADAlgorithm::EAX) ])?
6675 /// .set_features(
6676 /// sig.features().unwrap_or_else(Features::sequoia)
6677 /// .set_seipdv2())?
6678 /// .sign_userid_binding(&mut signer, pk, ua.userid())?);
6679 /// }
6680 ///
6681 /// // Merge in the new signatures.
6682 /// let cert = cert.insert_packets(sigs)?.0;
6683 /// # assert_eq!(cert.bad_signatures().count(), 0);
6684 /// # Ok(())
6685 /// # }
6686 /// ```
6687 pub fn set_features(mut self, features: Features) -> Result<Self> {
6688 self.hashed_area.replace(Subpacket::new(
6689 SubpacketValue::Features(features),
6690 false)?)?;
6691
6692 Ok(self)
6693 }
6694
6695 /// Sets the Signature Target subpacket.
6696 ///
6697 /// Adds a [Signature Target subpacket] to the hashed subpacket
6698 /// area. This function first removes any Signature Target
6699 /// subpacket from the hashed subpacket area.
6700 ///
6701 /// The Signature Target subpacket is used to identify the target
6702 /// of a signature. This is used when revoking a signature, and
6703 /// by timestamp signatures. It contains a hash of the target
6704 /// signature.
6705 ///
6706 /// [Signature Target subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.33
6707 pub fn set_signature_target<D>(mut self,
6708 pk_algo: PublicKeyAlgorithm,
6709 hash_algo: HashAlgorithm,
6710 digest: D)
6711 -> Result<Self>
6712 where D: AsRef<[u8]>,
6713 {
6714 self.hashed_area.replace(Subpacket::new(
6715 SubpacketValue::SignatureTarget {
6716 pk_algo,
6717 hash_algo,
6718 digest: digest.as_ref().to_vec(),
6719 },
6720 true)?)?;
6721
6722 Ok(self)
6723 }
6724
6725 /// Sets the value of the Embedded Signature subpacket.
6726 ///
6727 /// Adds an [Embedded Signature subpacket] to the hashed
6728 /// subpacket area. This function first removes any Embedded
6729 /// Signature subpacket from both the hashed and the unhashed
6730 /// subpacket area.
6731 ///
6732 /// [Embedded Signature subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.34
6733 ///
6734 /// The Embedded Signature subpacket is normally used to hold a
6735 /// [Primary Key Binding signature], which binds a
6736 /// signing-capable, authentication-capable, or
6737 /// certification-capable subkey to the primary key. Since this
6738 /// information is self-authenticating, it is usually stored in the
6739 /// unhashed subpacket area.
6740 ///
6741 /// [Primary Key Binding signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
6742 ///
6743 /// # Examples
6744 ///
6745 /// Add a new signing-capable subkey to a certificate:
6746 ///
6747 /// ```
6748 /// use sequoia_openpgp as openpgp;
6749 /// use openpgp::cert::prelude::*;
6750 /// use openpgp::packet::prelude::*;
6751 /// use openpgp::policy::StandardPolicy;
6752 /// use openpgp::types::KeyFlags;
6753 /// use openpgp::types::SignatureType;
6754 ///
6755 /// # fn main() -> openpgp::Result<()> {
6756 /// let p = &StandardPolicy::new();
6757 ///
6758 /// let (cert, _) = CertBuilder::new().generate()?;
6759 /// # assert_eq!(cert.keys().count(), 1);
6760 ///
6761 /// let pk = cert.primary_key().key().clone().parts_into_secret()?;
6762 /// // Derive a signer.
6763 /// let mut pk_signer = pk.clone().into_keypair()?;
6764 ///
6765 /// // Generate a new signing subkey.
6766 /// let mut subkey: Key<_, _> = Key4::generate_rsa(3072)?.into();
6767 /// // Derive a signer.
6768 /// let mut sk_signer = subkey.clone().into_keypair()?;
6769 ///
6770 /// // Create the binding signature.
6771 /// let sig = SignatureBuilder::new(SignatureType::SubkeyBinding)
6772 /// .set_key_flags(KeyFlags::empty().set_signing())?
6773 /// // And, the backsig. This is essential for subkeys that create signatures!
6774 /// .set_embedded_signature(
6775 /// SignatureBuilder::new(SignatureType::PrimaryKeyBinding)
6776 /// .sign_primary_key_binding(&mut sk_signer, &pk, &subkey)?)?
6777 /// .sign_subkey_binding(&mut pk_signer, None, &subkey)?;
6778 ///
6779 /// let cert = cert.insert_packets(vec![Packet::SecretSubkey(subkey),
6780 /// sig.into()])?.0;
6781 ///
6782 /// assert_eq!(cert.keys().count(), 2);
6783 /// # Ok(())
6784 /// # }
6785 /// ```
6786 pub fn set_embedded_signature(mut self, signature: Signature)
6787 -> Result<Self> {
6788 self.hashed_area.replace(Subpacket::new(
6789 SubpacketValue::EmbeddedSignature(signature),
6790 true)?)?;
6791 self.unhashed_area.remove_all(SubpacketTag::EmbeddedSignature);
6792
6793 Ok(self)
6794 }
6795
6796 /// Sets the Issuer Fingerprint subpacket.
6797 ///
6798 /// Adds an [Issuer Fingerprint subpacket] to the hashed
6799 /// subpacket area. Unlike [`add_issuer_fingerprint`], this
6800 /// function first removes any existing Issuer Fingerprint
6801 /// subpackets from the hashed and unhashed subpacket area.
6802 ///
6803 /// [Issuer Fingerprint subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
6804 /// [`add_issuer_fingerprint`]: super::SignatureBuilder::add_issuer_fingerprint()
6805 ///
6806 /// The Issuer Fingerprint subpacket is used when processing a
6807 /// signature to identify which certificate created the signature.
6808 /// Even though this information is self-authenticating (the act of
6809 /// validating the signature authenticates the subpacket), it is
6810 /// stored in the hashed subpacket area. This has the advantage
6811 /// that the signer authenticates the set of issuers.
6812 /// Furthermore, it makes handling of the resulting signatures
6813 /// more robust: If there are two signatures that are equal
6814 /// modulo the contents of the unhashed area, there is the
6815 /// question of how to merge the information in the unhashed
6816 /// areas. Storing issuer information in the hashed area avoids
6817 /// this problem.
6818 ///
6819 /// When creating a signature using a SignatureBuilder or the
6820 /// [streaming `Signer`], it is not necessary to explicitly set
6821 /// this subpacket: those functions automatically set both the
6822 /// Issuer Fingerprint subpacket, and the [Issuer subpacket] (set
6823 /// using [`SignatureBuilder::set_issuer`]), if they have not been
6824 /// set explicitly.
6825 ///
6826 /// [streaming `Signer`]: crate::serialize::stream::Signer
6827 /// [Issuer subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
6828 /// [`SignatureBuilder::set_issuer`]: super::SignatureBuilder::set_issuer()
6829 ///
6830 /// # Examples
6831 ///
6832 /// It is possible to use the same key material with different
6833 /// OpenPGP keys. This is useful when the OpenPGP format is
6834 /// upgraded, but not all deployed implementations support the new
6835 /// format. Here, Alice signs a message, and adds the fingerprint
6836 /// of her v4 key and her v5 key indicating that the recipient can
6837 /// use either key to verify the message:
6838 ///
6839 /// ```
6840 /// use sequoia_openpgp as openpgp;
6841 /// # use openpgp::cert::prelude::*;
6842 /// use openpgp::packet::prelude::*;
6843 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
6844 /// use openpgp::types::SignatureType;
6845 ///
6846 /// # fn main() -> openpgp::Result<()> {
6847 /// #
6848 /// # let (alicev4, _) =
6849 /// # CertBuilder::general_purpose(Some("alice@example.org"))
6850 /// # .generate()?;
6851 /// # let mut alices_signer = alicev4.primary_key().key().clone().parts_into_secret()?.into_keypair()?;
6852 /// # let (alicev5, _) =
6853 /// # CertBuilder::general_purpose(Some("alice@example.org"))
6854 /// # .generate()?;
6855 /// #
6856 /// let msg = b"Hi!";
6857 ///
6858 /// let sig = SignatureBuilder::new(SignatureType::Binary)
6859 /// .set_issuer_fingerprint(alicev4.fingerprint())?
6860 /// .add_issuer_fingerprint(alicev5.fingerprint())?
6861 /// .sign_message(&mut alices_signer, msg)?;
6862 /// # let mut sig = sig;
6863 /// # assert!(sig.verify_message(alices_signer.public(), msg).is_ok());
6864 /// # assert_eq!(sig
6865 /// # .hashed_area()
6866 /// # .iter()
6867 /// # .filter(|sp| sp.tag() == SubpacketTag::Issuer)
6868 /// # .count(),
6869 /// # 0);
6870 /// # assert_eq!(sig
6871 /// # .hashed_area()
6872 /// # .iter()
6873 /// # .filter(|sp| sp.tag() == SubpacketTag::IssuerFingerprint)
6874 /// # .count(),
6875 /// # 2);
6876 /// # Ok(()) }
6877 /// ```
6878 pub fn set_issuer_fingerprint(mut self, fp: Fingerprint) -> Result<Self> {
6879 self.hashed_area.replace(Subpacket::new(
6880 SubpacketValue::IssuerFingerprint(fp),
6881 false)?)?;
6882 self.unhashed_area.remove_all(SubpacketTag::IssuerFingerprint);
6883
6884 Ok(self)
6885 }
6886
6887 /// Adds an Issuer Fingerprint subpacket.
6888 ///
6889 /// Adds an [Issuer Fingerprint subpacket] to the hashed
6890 /// subpacket area. Unlike [`set_issuer_fingerprint`], this
6891 /// function does not first remove any existing Issuer Fingerprint
6892 /// subpacket from neither the hashed nor the unhashed subpacket
6893 /// area.
6894 ///
6895 /// [Issuer Fingerprint subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-issuer-fingerprint
6896 /// [`set_issuer_fingerprint`]: super::SignatureBuilder::set_issuer_fingerprint()
6897 ///
6898 /// The Issuer Fingerprint subpacket is used when processing a
6899 /// signature to identify which certificate created the signature.
6900 /// Even though this information is self-authenticating (the act of
6901 /// validating the signature authenticates the subpacket), it is
6902 /// stored in the hashed subpacket area. This has the advantage
6903 /// that the signer authenticates the set of issuers.
6904 /// Furthermore, it makes handling of the resulting signatures
6905 /// more robust: If there are two signatures that are equal
6906 /// modulo the contents of the unhashed area, there is the
6907 /// question of how to merge the information in the unhashed
6908 /// areas. Storing issuer information in the hashed area avoids
6909 /// this problem.
6910 ///
6911 /// When creating a signature using a SignatureBuilder or the
6912 /// [streaming `Signer`], it is not necessary to explicitly set
6913 /// this subpacket: those functions automatically set both the
6914 /// Issuer Fingerprint subpacket, and the [Issuer subpacket] (set
6915 /// using [`SignatureBuilder::set_issuer`]), if they have not been
6916 /// set explicitly.
6917 ///
6918 /// [streaming `Signer`]: crate::serialize::stream::Signer
6919 /// [Issuer subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.12
6920 /// [`SignatureBuilder::set_issuer`]: super::SignatureBuilder::set_issuer()
6921 ///
6922 /// # Examples
6923 ///
6924 /// It is possible to use the same key material with different
6925 /// OpenPGP keys. This is useful when the OpenPGP format is
6926 /// upgraded, but not all deployed implementations support the new
6927 /// format. Here, Alice signs a message, and adds the fingerprint
6928 /// of her v4 key and her v5 key indicating that the recipient can
6929 /// use either key to verify the message:
6930 ///
6931 /// ```
6932 /// use sequoia_openpgp as openpgp;
6933 /// # use openpgp::cert::prelude::*;
6934 /// use openpgp::packet::prelude::*;
6935 /// # use openpgp::packet::signature::subpacket::SubpacketTag;
6936 /// use openpgp::types::SignatureType;
6937 ///
6938 /// # fn main() -> openpgp::Result<()> {
6939 /// #
6940 /// # let (alicev4, _) =
6941 /// # CertBuilder::general_purpose(Some("alice@example.org"))
6942 /// # .generate()?;
6943 /// # let mut alices_signer = alicev4.primary_key().key().clone().parts_into_secret()?.into_keypair()?;
6944 /// # let (alicev5, _) =
6945 /// # CertBuilder::general_purpose(Some("alice@example.org"))
6946 /// # .generate()?;
6947 /// #
6948 /// let msg = b"Hi!";
6949 ///
6950 /// let sig = SignatureBuilder::new(SignatureType::Binary)
6951 /// .set_issuer_fingerprint(alicev4.fingerprint())?
6952 /// .add_issuer_fingerprint(alicev5.fingerprint())?
6953 /// .sign_message(&mut alices_signer, msg)?;
6954 /// # let mut sig = sig;
6955 /// # assert!(sig.verify_message(alices_signer.public(), msg).is_ok());
6956 /// # assert_eq!(sig
6957 /// # .hashed_area()
6958 /// # .iter()
6959 /// # .filter(|sp| sp.tag() == SubpacketTag::Issuer)
6960 /// # .count(),
6961 /// # 0);
6962 /// # assert_eq!(sig
6963 /// # .hashed_area()
6964 /// # .iter()
6965 /// # .filter(|sp| sp.tag() == SubpacketTag::IssuerFingerprint)
6966 /// # .count(),
6967 /// # 2);
6968 /// # Ok(()) }
6969 /// ```
6970 pub fn add_issuer_fingerprint(mut self, fp: Fingerprint) -> Result<Self> {
6971 self.hashed_area.add(Subpacket::new(
6972 SubpacketValue::IssuerFingerprint(fp),
6973 false)?)?;
6974
6975 Ok(self)
6976 }
6977
6978 /// Sets the Preferred AEAD Ciphersuites subpacket.
6979 ///
6980 /// Replaces any [Preferred AEAD Ciphersuites subpacket] in the
6981 /// hashed subpacket area with a new subpacket containing the
6982 /// specified value. That is, this function first removes any
6983 /// Preferred AEAD Ciphersuites subpacket from the hashed
6984 /// subpacket area, and then adds a Preferred AEAD Ciphersuites
6985 /// subpacket.
6986 ///
6987 /// [Preferred AEAD Ciphersuites subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-preferred-aead-ciphersuites
6988 ///
6989 /// The Preferred AEAD Ciphersuites subpacket indicates what AEAD
6990 /// ciphersuites the key holder prefers ordered by preference. If
6991 /// this is set, then the `Version 2 Symmetrically Encrypted and
6992 /// Integrity Protected Data packet` feature flag should in the
6993 /// [Features subpacket] should also be set.
6994 ///
6995 /// [Features subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-features
6996 ///
6997 /// This subpacket is a type of preference. When looking up a
6998 /// preference, an OpenPGP implementation should first look for
6999 /// the subpacket on the binding signature of the User ID or the
7000 /// User Attribute used to locate the certificate (or the primary
7001 /// User ID, if it was addressed by Key ID or fingerprint). If
7002 /// the binding signature doesn't contain the subpacket, then the
7003 /// direct key signature should be checked. See the
7004 /// [`Preferences`] trait for details.
7005 ///
7006 /// Unless addressing different User IDs really should result in
7007 /// different behavior, it is best to only set this preference on
7008 /// the direct key signature. This guarantees that even if some
7009 /// or all User IDs are stripped, the behavior remains consistent.
7010 ///
7011 /// [`Preferences`]: crate::cert::Preferences
7012 ///
7013 /// # Examples
7014 ///
7015 /// Update a certificate's binding signatures to indicate support for AEAD:
7016 ///
7017 /// ```
7018 /// use sequoia_openpgp as openpgp;
7019 /// use openpgp::cert::prelude::*;
7020 /// use openpgp::packet::prelude::*;
7021 /// use openpgp::policy::StandardPolicy;
7022 /// use openpgp::types::{AEADAlgorithm, Features, SymmetricAlgorithm};
7023 ///
7024 /// # fn main() -> openpgp::Result<()> {
7025 /// let p = &StandardPolicy::new();
7026 ///
7027 /// let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
7028 ///
7029 /// // Derive a signer (the primary key is always certification capable).
7030 /// let pk = cert.primary_key().key();
7031 /// let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;
7032 ///
7033 /// // Update the cert to advocate support for SEIPDv2 with a
7034 /// // preferred AEAD cipher suite.
7035 /// let symm = SymmetricAlgorithm::default();
7036 /// let aead = AEADAlgorithm::default();
7037 ///
7038 /// let mut sigs = Vec::new();
7039 ///
7040 /// let vc = cert.with_policy(p, None)?;
7041 ///
7042 /// // Update the direct key signature.
7043 /// if let Ok(sig) = vc.direct_key_signature() {
7044 /// sigs.push(
7045 /// SignatureBuilder::from(sig.clone())
7046 /// .set_preferred_aead_ciphersuites(vec![(symm, aead)])?
7047 /// .set_features(
7048 /// sig.features().unwrap_or_else(Features::sequoia)
7049 /// .set_seipdv2())?
7050 /// .sign_direct_key(&mut signer, None)?);
7051 /// }
7052 ///
7053 /// // Update the user ID binding signatures.
7054 /// for ua in vc.userids() {
7055 /// let sig = ua.binding_signature();
7056 /// sigs.push(
7057 /// SignatureBuilder::from(sig.clone())
7058 /// .set_preferred_aead_ciphersuites(vec![(symm, aead)])?
7059 /// .set_features(
7060 /// sig.features().unwrap_or_else(Features::sequoia)
7061 /// .set_seipdv2())?
7062 /// .sign_userid_binding(&mut signer, pk, ua.userid())?);
7063 /// }
7064 ///
7065 /// // Merge in the new signatures.
7066 /// let cert = cert.insert_packets(sigs)?.0;
7067 /// # assert_eq!(cert.bad_signatures().count(), 0);
7068 /// # Ok(())
7069 /// # }
7070 /// ```
7071 pub fn set_preferred_aead_ciphersuites(
7072 mut self,
7073 preferences: Vec<(SymmetricAlgorithm, AEADAlgorithm)>)
7074 -> Result<Self>
7075 {
7076 self.hashed_area.replace(Subpacket::new(
7077 SubpacketValue::PreferredAEADCiphersuites(preferences),
7078 false)?)?;
7079
7080 Ok(self)
7081 }
7082
7083 /// Sets the Intended Recipient subpacket.
7084 ///
7085 /// Replaces any [Intended Recipient subpacket] in the hashed
7086 /// subpacket area with one new subpacket for each of the
7087 /// specified values. That is, unlike
7088 /// [`SignatureBuilder::add_intended_recipient`], this function
7089 /// first removes any Intended Recipient subpackets from the
7090 /// hashed subpacket area, and then adds new ones.
7091 ///
7092 /// [Intended Recipient subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-intended-recipient-fingerpr
7093 /// [`SignatureBuilder::add_intended_recipient`]: super::SignatureBuilder::add_intended_recipient()
7094 ///
7095 /// The Intended Recipient subpacket holds the fingerprint of a
7096 /// certificate.
7097 ///
7098 /// When signing a message, the message should include one such
7099 /// subpacket for each intended recipient. Note: not all messages
7100 /// have intended recipients. For instance, when signing an open
7101 /// letter, or a software release, the message is intended for
7102 /// anyone.
7103 ///
7104 /// When processing a signature, the application should ensure
7105 /// that if there are any such subpackets, then one of the
7106 /// subpackets identifies the recipient's certificate (or user
7107 /// signed the message). If this is not the case, then an
7108 /// attacker may have taken the message out of its original
7109 /// context. For instance, if Alice sends a signed email to Bob,
7110 /// with the content: "I agree to the contract", and Bob forwards
7111 /// that message to Carol, then Carol may think that Alice agreed
7112 /// to a contract with her if the signature appears to be valid!
7113 /// By adding an intended recipient, it is possible for Carol's
7114 /// mail client to warn her that although Alice signed the
7115 /// message, the content was intended for Bob and not for her.
7116 ///
7117 /// # Examples
7118 ///
7119 /// To create a signed message intended for both Bob and Carol,
7120 /// Alice adds an intended recipient subpacket for each of their
7121 /// certificates. Because this function first removes any
7122 /// existing Intended Recipient subpackets both recipients must be
7123 /// added at once (cf. [`SignatureBuilder::add_intended_recipient`]):
7124 ///
7125 /// ```
7126 /// use sequoia_openpgp as openpgp;
7127 /// use openpgp::cert::prelude::*;
7128 /// use openpgp::packet::signature::SignatureBuilder;
7129 /// use openpgp::types::SignatureType;
7130 ///
7131 /// # fn main() -> openpgp::Result<()> {
7132 /// #
7133 /// # let (alice, _) =
7134 /// # CertBuilder::general_purpose(Some("alice@example.org"))
7135 /// # .generate()?;
7136 /// # let mut alices_signer = alice.primary_key().key().clone().parts_into_secret()?.into_keypair()?;
7137 /// # let (bob, _) =
7138 /// # CertBuilder::general_purpose(Some("bob@example.org"))
7139 /// # .generate()?;
7140 /// # let (carol, _) =
7141 /// # CertBuilder::general_purpose(Some("carol@example.org"))
7142 /// # .generate()?;
7143 /// #
7144 /// let msg = b"Let's do it!";
7145 ///
7146 /// let sig = SignatureBuilder::new(SignatureType::Binary)
7147 /// .set_intended_recipients(&[ bob.fingerprint(), carol.fingerprint() ])?
7148 /// .sign_message(&mut alices_signer, msg)?;
7149 /// # let mut sig = sig;
7150 /// # assert!(sig.verify_message(alices_signer.public(), msg).is_ok());
7151 /// # assert_eq!(sig.intended_recipients().count(), 2);
7152 /// # Ok(()) }
7153 /// ```
7154 pub fn set_intended_recipients<T>(mut self, recipients: T)
7155 -> Result<Self>
7156 where T: AsRef<[Fingerprint]>
7157 {
7158 self.hashed_area.remove_all(SubpacketTag::IntendedRecipient);
7159 for fp in recipients.as_ref().iter() {
7160 self.hashed_area.add(
7161 Subpacket::new(SubpacketValue::IntendedRecipient(fp.clone()), false)?)?;
7162 }
7163
7164 Ok(self)
7165 }
7166
7167 /// Adds an Intended Recipient subpacket.
7168 ///
7169 /// Adds an [Intended Recipient subpacket] to the hashed subpacket
7170 /// area. Unlike [`SignatureBuilder::set_intended_recipients`], this function does
7171 /// not first remove any Intended Recipient subpackets from the
7172 /// hashed subpacket area.
7173 ///
7174 /// [Intended Recipient subpacket]: https://www.rfc-editor.org/rfc/rfc9580.html#name-intended-recipient-fingerpr
7175 /// [`SignatureBuilder::set_intended_recipients`]: super::SignatureBuilder::set_intended_recipients()
7176 ///
7177 /// The Intended Recipient subpacket holds the fingerprint of a
7178 /// certificate.
7179 ///
7180 /// When signing a message, the message should include one such
7181 /// subpacket for each intended recipient. Note: not all messages
7182 /// have intended recipients. For instance, when signing an open
7183 /// letter, or a software release, the message is intended for
7184 /// anyone.
7185 ///
7186 /// When processing a signature, the application should ensure
7187 /// that if there are any such subpackets, then one of the
7188 /// subpackets identifies the recipient's certificate (or user
7189 /// signed the message). If this is not the case, then an
7190 /// attacker may have taken the message out of its original
7191 /// context. For instance, if Alice sends a signed email to Bob,
7192 /// with the content: "I agree to the contract", and Bob forwards
7193 /// that message to Carol, then Carol may think that Alice agreed
7194 /// to a contract with her if the signature appears to be valid!
7195 /// By adding an intended recipient, it is possible for Carol's
7196 /// mail client to warn her that although Alice signed the
7197 /// message, the content was intended for Bob and not for her.
7198 ///
7199 /// # Examples
7200 ///
7201 /// To create a signed message intended for both Bob and Carol,
7202 /// Alice adds an Intended Recipient subpacket for each of their
7203 /// certificates. Unlike
7204 /// [`SignatureBuilder::set_intended_recipients`], which first
7205 /// removes any existing Intended Recipient subpackets, with this
7206 /// function we can add one recipient after the other:
7207 ///
7208 /// [`SignatureBuilder::set_intended_recipients`]: NotationDataFlags::set_intended_recipients()
7209 ///
7210 /// ```
7211 /// use sequoia_openpgp as openpgp;
7212 /// use openpgp::cert::prelude::*;
7213 /// use openpgp::packet::signature::SignatureBuilder;
7214 /// use openpgp::types::SignatureType;
7215 ///
7216 /// # fn main() -> openpgp::Result<()> {
7217 /// #
7218 /// # let (alice, _) =
7219 /// # CertBuilder::general_purpose(Some("alice@example.org"))
7220 /// # .generate()?;
7221 /// # let mut alices_signer = alice.primary_key().key().clone().parts_into_secret()?.into_keypair()?;
7222 /// # let (bob, _) =
7223 /// # CertBuilder::general_purpose(Some("bob@example.org"))
7224 /// # .generate()?;
7225 /// # let (carol, _) =
7226 /// # CertBuilder::general_purpose(Some("carol@example.org"))
7227 /// # .generate()?;
7228 /// #
7229 /// let msg = b"Let's do it!";
7230 ///
7231 /// let sig = SignatureBuilder::new(SignatureType::Binary)
7232 /// .add_intended_recipient(bob.fingerprint())?
7233 /// .add_intended_recipient(carol.fingerprint())?
7234 /// .sign_message(&mut alices_signer, msg)?;
7235 /// # let mut sig = sig;
7236 /// # assert!(sig.verify_message(alices_signer.public(), msg).is_ok());
7237 /// # assert_eq!(sig.intended_recipients().count(), 2);
7238 /// # Ok(()) }
7239 /// ```
7240 pub fn add_intended_recipient(mut self, recipient: Fingerprint)
7241 -> Result<Self>
7242 {
7243 self.hashed_area.add(
7244 Subpacket::new(SubpacketValue::IntendedRecipient(recipient),
7245 false)?)?;
7246
7247 Ok(self)
7248 }
7249
7250 /// Adds an approved certifications subpacket.
7251 ///
7252 /// This feature is [experimental](crate#experimental-features).
7253 ///
7254 /// Allows the certificate holder to attest to third party
7255 /// certifications, allowing them to be distributed with the
7256 /// certificate. This can be used to address certificate flooding
7257 /// concerns.
7258 ///
7259 /// Sorts the digests and adds an [Approved Certification
7260 /// subpacket] to the hashed subpacket area. The digests must be
7261 /// calculated using the same hash algorithm that is used in the
7262 /// resulting signature. To attest a signature, hash it with
7263 /// [`super::Signature::hash_for_confirmation`].
7264 ///
7265 /// Note: The maximum size of the hashed signature subpacket area
7266 /// constrains the number of attestations that can be stored in a
7267 /// signature. If you need to attest to more certifications,
7268 /// split the digests into chunks and create multiple approved key
7269 /// signatures with the same creation time.
7270 ///
7271 /// See [Approved Certification subpacket] for details.
7272 ///
7273 /// [Approved Certification subpacket]: https://www.ietf.org/archive/id/draft-dkg-openpgp-1pa3pc-02.html#approved-certifications-subpacket
7274 pub fn set_approved_certifications<A, C>(mut self, certifications: C)
7275 -> Result<Self>
7276 where C: IntoIterator<Item = A>,
7277 A: AsRef<[u8]>,
7278 {
7279 let mut digests: Vec<_> = certifications.into_iter()
7280 .map(|d| d.as_ref().to_vec().into_boxed_slice())
7281 .collect();
7282
7283 if let Some(first) = digests.get(0) {
7284 if digests.iter().any(|d| d.len() != first.len()) {
7285 return Err(Error::InvalidOperation(
7286 "Inconsistent digest algorithm used".into()).into());
7287 }
7288 }
7289
7290 // Hashes SHOULD be sorted. This optimizes lookups for the
7291 // consumer and provides a canonical form.
7292 digests.sort_unstable();
7293
7294 self.hashed_area_mut().replace(
7295 Subpacket::new(
7296 SubpacketValue::ApprovedCertifications(digests),
7297 true)?)?;
7298
7299 Ok(self)
7300 }
7301}
7302
7303#[test]
7304fn accessors() {
7305 use crate::types::Curve;
7306
7307 let pk_algo = PublicKeyAlgorithm::EdDSA;
7308 let hash_algo = HashAlgorithm::SHA512;
7309 let mut sig = signature::SignatureBuilder::new(crate::types::SignatureType::Binary);
7310 let mut key: crate::packet::key::SecretKey =
7311 crate::packet::key::Key6::generate_ecc(true, Curve::Ed25519).unwrap().into();
7312 let mut keypair = key.clone().into_keypair().unwrap();
7313 let hash = hash_algo.context().unwrap().for_signature(key.version());
7314
7315 // Cook up a timestamp without ns resolution.
7316 use std::convert::TryFrom;
7317 let now: time::SystemTime =
7318 Timestamp::try_from(crate::now()).unwrap().into();
7319
7320 sig = sig.set_signature_creation_time(now).unwrap();
7321 let sig_ =
7322 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7323 assert_eq!(sig_.signature_creation_time(), Some(now));
7324
7325 let zero_s = time::Duration::new(0, 0);
7326 let minute = time::Duration::new(60, 0);
7327 let five_minutes = 5 * minute;
7328 let ten_minutes = 10 * minute;
7329 sig = sig.set_signature_validity_period(five_minutes).unwrap();
7330 let sig_ =
7331 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7332 assert_eq!(sig_.signature_validity_period(), Some(five_minutes));
7333
7334 assert!(sig_.signature_alive(None, zero_s).is_ok());
7335 assert!(sig_.signature_alive(now, zero_s).is_ok());
7336 assert!(!sig_.signature_alive(now - five_minutes, zero_s).is_ok());
7337 assert!(!sig_.signature_alive(now + ten_minutes, zero_s).is_ok());
7338
7339 sig = sig.modify_hashed_area(|mut a| {
7340 a.remove_all(SubpacketTag::SignatureExpirationTime);
7341 Ok(a)
7342 }).unwrap();
7343 let sig_ =
7344 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7345 assert_eq!(sig_.signature_validity_period(), None);
7346
7347 assert!(sig_.signature_alive(None, zero_s).is_ok());
7348 assert!(sig_.signature_alive(now, zero_s).is_ok());
7349 assert!(!sig_.signature_alive(now - five_minutes, zero_s).is_ok());
7350 assert!(sig_.signature_alive(now + ten_minutes, zero_s).is_ok());
7351
7352 sig = sig.set_exportable_certification(true).unwrap();
7353 let sig_ =
7354 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7355 assert_eq!(sig_.exportable_certification(), Some(true));
7356 sig = sig.set_exportable_certification(false).unwrap();
7357 let sig_ =
7358 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7359 assert_eq!(sig_.exportable_certification(), Some(false));
7360
7361 sig = sig.set_trust_signature(2, 3).unwrap();
7362 let sig_ =
7363 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7364 assert_eq!(sig_.trust_signature(), Some((2, 3)));
7365
7366 sig = sig.set_regular_expression(b"foobar").unwrap();
7367 let sig_ =
7368 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7369 assert_eq!(sig_.regular_expressions().collect::<Vec<&[u8]>>(),
7370 vec![ &b"foobar"[..] ]);
7371
7372 sig = sig.set_revocable(true).unwrap();
7373 let sig_ =
7374 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7375 assert_eq!(sig_.revocable(), Some(true));
7376 sig = sig.set_revocable(false).unwrap();
7377 let sig_ =
7378 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7379 assert_eq!(sig_.revocable(), Some(false));
7380
7381 key.set_creation_time(now).unwrap();
7382 sig = sig.set_key_validity_period(Some(five_minutes)).unwrap();
7383 let sig_ =
7384 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7385 assert_eq!(sig_.key_validity_period(), Some(five_minutes));
7386
7387 assert!(sig_.key_alive(&key, None).is_ok());
7388 assert!(sig_.key_alive(&key, now).is_ok());
7389 assert!(!sig_.key_alive(&key, now - five_minutes).is_ok());
7390 assert!(!sig_.key_alive(&key, now + ten_minutes).is_ok());
7391
7392 sig = sig.set_key_validity_period(None).unwrap();
7393 let sig_ =
7394 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7395 assert_eq!(sig_.key_validity_period(), None);
7396
7397 assert!(sig_.key_alive(&key, None).is_ok());
7398 assert!(sig_.key_alive(&key, now).is_ok());
7399 assert!(!sig_.key_alive(&key, now - five_minutes).is_ok());
7400 assert!(sig_.key_alive(&key, now + ten_minutes).is_ok());
7401
7402 let pref = vec![SymmetricAlgorithm::AES256,
7403 SymmetricAlgorithm::AES192,
7404 SymmetricAlgorithm::AES128];
7405 sig = sig.set_preferred_symmetric_algorithms(pref.clone()).unwrap();
7406 let sig_ =
7407 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7408 assert_eq!(sig_.preferred_symmetric_algorithms(), Some(&pref[..]));
7409
7410 let fp = Fingerprint::from_bytes(4, b"bbbbbbbbbbbbbbbbbbbb").unwrap();
7411 let rk = RevocationKey::new(pk_algo, fp.clone(), true);
7412 sig = sig.set_revocation_key(rk.clone()).unwrap();
7413 sig = sig.set_revocation_key(rk.clone()).unwrap();
7414 let sig_ =
7415 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7416 assert_eq!(sig_.revocation_keys().next().unwrap(), &rk);
7417 assert_eq!(sig_.revocation_keys().count(), 1);
7418
7419 sig = sig.add_revocation_key(rk.clone()).unwrap();
7420 sig = sig.add_revocation_key(rk.clone()).unwrap();
7421 let sig_ =
7422 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7423 assert_eq!(sig_.revocation_keys().count(), 3);
7424
7425 sig = sig.set_issuer(fp.clone().into()).unwrap();
7426 let sig_ =
7427 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7428 assert_eq!(sig_.issuers().collect::<Vec<_>>(),
7429 vec![ &fp.clone().into() ]);
7430
7431 let pref = vec![HashAlgorithm::SHA512,
7432 HashAlgorithm::SHA384,
7433 HashAlgorithm::SHA256];
7434 sig = sig.set_preferred_hash_algorithms(pref.clone()).unwrap();
7435 let sig_ =
7436 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7437 assert_eq!(sig_.preferred_hash_algorithms(), Some(&pref[..]));
7438
7439 let pref = vec![CompressionAlgorithm::BZip2,
7440 CompressionAlgorithm::Zlib,
7441 CompressionAlgorithm::Zip];
7442 sig = sig.set_preferred_compression_algorithms(pref.clone()).unwrap();
7443 let sig_ =
7444 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7445 assert_eq!(sig_.preferred_compression_algorithms(), Some(&pref[..]));
7446
7447 let pref = KeyServerPreferences::empty()
7448 .set_no_modify();
7449 sig = sig.set_key_server_preferences(pref.clone()).unwrap();
7450 let sig_ =
7451 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7452 assert_eq!(sig_.key_server_preferences().unwrap(), pref);
7453
7454 sig = sig.set_primary_userid(true).unwrap();
7455 let sig_ =
7456 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7457 assert_eq!(sig_.primary_userid(), Some(true));
7458 sig = sig.set_primary_userid(false).unwrap();
7459 let sig_ =
7460 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7461 assert_eq!(sig_.primary_userid(), Some(false));
7462
7463 sig = sig.set_policy_uri(b"foobar").unwrap();
7464 let sig_ =
7465 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7466 assert_eq!(sig_.policy_uri(), Some(&b"foobar"[..]));
7467
7468 let key_flags = KeyFlags::empty()
7469 .set_certification()
7470 .set_signing();
7471 sig = sig.set_key_flags(key_flags.clone()).unwrap();
7472 let sig_ =
7473 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7474 assert_eq!(sig_.key_flags().unwrap(), key_flags);
7475
7476 sig = sig.set_signers_user_id(b"foobar").unwrap();
7477 let sig_ =
7478 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7479 assert_eq!(sig_.signers_user_id(), Some(&b"foobar"[..]));
7480
7481 sig = sig.set_reason_for_revocation(ReasonForRevocation::KeyRetired,
7482 b"foobar").unwrap();
7483 let sig_ =
7484 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7485 assert_eq!(sig_.reason_for_revocation(),
7486 Some((ReasonForRevocation::KeyRetired, &b"foobar"[..])));
7487
7488 let feats = Features::empty().set_seipdv1();
7489 sig = sig.set_features(feats.clone()).unwrap();
7490 let sig_ =
7491 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7492 assert_eq!(sig_.features().unwrap(), feats);
7493
7494 let feats = Features::empty().set_seipdv2();
7495 sig = sig.set_features(feats.clone()).unwrap();
7496 let sig_ =
7497 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7498 assert_eq!(sig_.features().unwrap(), feats);
7499
7500 let digest = vec![0; hash_algo.digest_size().unwrap()];
7501 sig = sig.set_signature_target(pk_algo, hash_algo, &digest).unwrap();
7502 let sig_ =
7503 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7504 assert_eq!(sig_.signature_target(), Some((pk_algo,
7505 hash_algo,
7506 &digest[..])));
7507
7508 let embedded_sig = sig_.clone();
7509 sig = sig.set_embedded_signature(embedded_sig.clone()).unwrap();
7510 let sig_ =
7511 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7512 assert_eq!(sig_.embedded_signatures().next(), Some(&embedded_sig));
7513
7514 sig = sig.set_issuer_fingerprint(fp.clone()).unwrap();
7515 let sig_ =
7516 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7517 assert_eq!(sig_.issuer_fingerprints().collect::<Vec<_>>(),
7518 vec![ &fp ]);
7519
7520 let pref = vec![(SymmetricAlgorithm::AES128, AEADAlgorithm::EAX),
7521 (SymmetricAlgorithm::AES128, AEADAlgorithm::OCB)];
7522 sig = sig.set_preferred_aead_ciphersuites(pref.clone()).unwrap();
7523 let sig_ =
7524 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7525 assert_eq!(sig_.preferred_aead_ciphersuites(), Some(&pref[..]));
7526
7527 let fps = vec![
7528 Fingerprint::from_bytes(4, b"aaaaaaaaaaaaaaaaaaaa").unwrap(),
7529 Fingerprint::from_bytes(4, b"bbbbbbbbbbbbbbbbbbbb").unwrap(),
7530 ];
7531 sig = sig.set_intended_recipients(fps.clone()).unwrap();
7532 let sig_ =
7533 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7534 assert_eq!(sig_.intended_recipients().collect::<Vec<&Fingerprint>>(),
7535 fps.iter().collect::<Vec<&Fingerprint>>());
7536
7537 sig = sig.set_notation("test@example.org", &[0, 1, 2], None, false)
7538 .unwrap();
7539 let sig_ =
7540 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7541 assert_eq!(sig_.notation("test@example.org").collect::<Vec<&[u8]>>(),
7542 vec![&[0, 1, 2]]);
7543
7544 sig = sig.add_notation("test@example.org", &[3, 4, 5], None, false)
7545 .unwrap();
7546 let sig_ =
7547 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7548 assert_eq!(sig_.notation("test@example.org").collect::<Vec<&[u8]>>(),
7549 vec![&[0, 1, 2], &[3, 4, 5]]);
7550
7551 sig = sig.set_notation("test@example.org", &[6, 7, 8], None, false)
7552 .unwrap();
7553 let sig_ =
7554 sig.clone().sign_hash(&mut keypair, hash.clone()).unwrap();
7555 assert_eq!(sig_.notation("test@example.org").collect::<Vec<&[u8]>>(),
7556 vec![&[6, 7, 8]]);
7557}
7558
7559#[cfg(feature = "compression-deflate")]
7560#[test]
7561fn subpacket_test_1 () {
7562 use crate::Packet;
7563 use crate::PacketPile;
7564 use crate::parse::Parse;
7565
7566 let pile = PacketPile::from_bytes(crate::tests::message("signed.pgp")).unwrap();
7567 eprintln!("PacketPile has {} top-level packets.", pile.children().len());
7568 eprintln!("PacketPile: {:?}", pile);
7569
7570 let mut count = 0;
7571 for p in pile.descendants() {
7572 if let &Packet::Signature(ref sig) = p {
7573 count += 1;
7574
7575 let mut got2 = false;
7576 let mut got16 = false;
7577 let mut got33 = false;
7578
7579 for i in 0..255 {
7580 if let Some(sb) = sig.subpacket(i.into()) {
7581 if i == 2 {
7582 got2 = true;
7583 assert!(!sb.critical);
7584 } else if i == 16 {
7585 got16 = true;
7586 assert!(!sb.critical);
7587 } else if i == 33 {
7588 got33 = true;
7589 assert!(!sb.critical);
7590 } else {
7591 panic!("Unexpectedly found subpacket {}", i);
7592 }
7593 }
7594 }
7595
7596 assert!(got2 && got16 && got33);
7597
7598 let hex = format!("{:X}", sig.issuer_fingerprints().next().unwrap());
7599 assert!(
7600 hex == "7FAF6ED7238143557BDF7ED26863C9AD5B4D22D3"
7601 || hex == "C03FA6411B03AE12576461187223B56678E02528");
7602 }
7603 }
7604 // 2 packets have subpackets.
7605 assert_eq!(count, 2);
7606}
7607
7608#[test]
7609#[allow(deprecated)]
7610fn subpacket_test_2() {
7611 use crate::Packet;
7612 use crate::parse::Parse;
7613 use crate::PacketPile;
7614
7615 // Test # Subpacket
7616 // 1 2 3 4 5 6 SignatureCreationTime
7617 // * SignatureExpirationTime
7618 // 2 ExportableCertification
7619 // 6 TrustSignature
7620 // 6 RegularExpression
7621 // 3 Revocable
7622 // 1 7 KeyExpirationTime
7623 // 1 PreferredSymmetricAlgorithms
7624 // 3 RevocationKey
7625 // 1 3 7 Issuer
7626 // 1 3 5 NotationData
7627 // 1 PreferredHashAlgorithms
7628 // 1 PreferredCompressionAlgorithms
7629 // 1 KeyServerPreferences
7630 // * PreferredKeyServer
7631 // * PrimaryUserID
7632 // * PolicyURI
7633 // 1 KeyFlags
7634 // * SignersUserID
7635 // 4 ReasonForRevocation
7636 // 1 Features
7637 // * SignatureTarget
7638 // 7 EmbeddedSignature
7639 // 1 3 7 IssuerFingerprint
7640 //
7641 // XXX: The subpackets marked with * are not tested.
7642
7643 let pile = PacketPile::from_bytes(
7644 crate::tests::key("subpackets/shaw.pgp")).unwrap();
7645
7646 // Test #1
7647 if let (Some(&Packet::PublicKey(ref key)),
7648 Some(&Packet::Signature(ref sig)))
7649 = (pile.children().next(), pile.children().nth(2))
7650 {
7651 // tag: 2, SignatureCreationTime(1515791508) }
7652 // tag: 9, KeyExpirationTime(63072000) }
7653 // tag: 11, PreferredSymmetricAlgorithms([9, 8, 7, 2]) }
7654 // tag: 16, Issuer(KeyID("F004 B9A4 5C58 6126")) }
7655 // tag: 20, NotationData(NotationData { flags: 2147483648, name: [114, 97, 110, 107, 64, 110, 97, 118, 121, 46, 109, 105, 108], value: [109, 105, 100, 115, 104, 105, 112, 109, 97, 110] }) }
7656 // tag: 21, PreferredHashAlgorithms([8, 9, 10, 11, 2]) }
7657 // tag: 22, PreferredCompressionAlgorithms([2, 3, 1]) }
7658 // tag: 23, KeyServerPreferences([128]) }
7659 // tag: 27, KeyFlags([3]) }
7660 // tag: 30, Features([1]) }
7661 // tag: 33, IssuerFingerprint(Fingerprint("361A 96BD E1A6 5B6D 6C25 AE9F F004 B9A4 5C58 6126")) }
7662 // for i in 0..256 {
7663 // if let Some(sb) = sig.subpacket(i as u8) {
7664 // eprintln!(" {:?}", sb);
7665 // }
7666 // }
7667
7668 assert_eq!(sig.signature_creation_time(),
7669 Some(Timestamp::from(1515791508).into()));
7670 assert_eq!(sig.subpacket(SubpacketTag::SignatureCreationTime),
7671 Some(&Subpacket {
7672 length: 5.into(),
7673 critical: false,
7674 value: SubpacketValue::SignatureCreationTime(
7675 1515791508.into()),
7676 authenticated: false.into(),
7677 }));
7678
7679 // The signature does not expire.
7680 assert!(sig.signature_alive(None, None).is_ok());
7681
7682 assert_eq!(sig.key_validity_period(),
7683 Some(Duration::from(63072000).into()));
7684 assert_eq!(sig.subpacket(SubpacketTag::KeyExpirationTime),
7685 Some(&Subpacket {
7686 length: 5.into(),
7687 critical: false,
7688 value: SubpacketValue::KeyExpirationTime(
7689 63072000.into()),
7690 authenticated: false.into(),
7691 }));
7692
7693 // Check key expiration.
7694 assert!(sig.key_alive(
7695 key,
7696 key.creation_time() + time::Duration::new(63072000 - 1, 0))
7697 .is_ok());
7698 assert!(! sig.key_alive(
7699 key,
7700 key.creation_time() + time::Duration::new(63072000, 0))
7701 .is_ok());
7702
7703 assert_eq!(sig.preferred_symmetric_algorithms(),
7704 Some(&[SymmetricAlgorithm::AES256,
7705 SymmetricAlgorithm::AES192,
7706 SymmetricAlgorithm::AES128,
7707 SymmetricAlgorithm::TripleDES][..]));
7708 assert_eq!(sig.subpacket(SubpacketTag::PreferredSymmetricAlgorithms),
7709 Some(&Subpacket {
7710 length: 5.into(),
7711 critical: false,
7712 value: SubpacketValue::PreferredSymmetricAlgorithms(
7713 vec![SymmetricAlgorithm::AES256,
7714 SymmetricAlgorithm::AES192,
7715 SymmetricAlgorithm::AES128,
7716 SymmetricAlgorithm::TripleDES]
7717 ),
7718 authenticated: false.into(),
7719 }));
7720
7721 assert_eq!(sig.preferred_hash_algorithms(),
7722 Some(&[HashAlgorithm::SHA256,
7723 HashAlgorithm::SHA384,
7724 HashAlgorithm::SHA512,
7725 HashAlgorithm::SHA224,
7726 HashAlgorithm::SHA1][..]));
7727 assert_eq!(sig.subpacket(SubpacketTag::PreferredHashAlgorithms),
7728 Some(&Subpacket {
7729 length: 6.into(),
7730 critical: false,
7731 value: SubpacketValue::PreferredHashAlgorithms(
7732 vec![HashAlgorithm::SHA256,
7733 HashAlgorithm::SHA384,
7734 HashAlgorithm::SHA512,
7735 HashAlgorithm::SHA224,
7736 HashAlgorithm::SHA1]
7737 ),
7738 authenticated: false.into(),
7739 }));
7740
7741 assert_eq!(sig.preferred_compression_algorithms(),
7742 Some(&[CompressionAlgorithm::Zlib,
7743 CompressionAlgorithm::BZip2,
7744 CompressionAlgorithm::Zip][..]));
7745 assert_eq!(sig.subpacket(SubpacketTag::PreferredCompressionAlgorithms),
7746 Some(&Subpacket {
7747 length: 4.into(),
7748 critical: false,
7749 value: SubpacketValue::PreferredCompressionAlgorithms(
7750 vec![CompressionAlgorithm::Zlib,
7751 CompressionAlgorithm::BZip2,
7752 CompressionAlgorithm::Zip]
7753 ),
7754 authenticated: false.into(),
7755 }));
7756
7757 assert_eq!(sig.key_server_preferences().unwrap(),
7758 KeyServerPreferences::empty().set_no_modify());
7759 assert_eq!(sig.subpacket(SubpacketTag::KeyServerPreferences),
7760 Some(&Subpacket {
7761 length: 2.into(),
7762 critical: false,
7763 value: SubpacketValue::KeyServerPreferences(
7764 KeyServerPreferences::empty().set_no_modify()),
7765 authenticated: false.into(),
7766 }));
7767
7768 assert!(sig.key_flags().unwrap().for_certification());
7769 assert!(sig.key_flags().unwrap().for_signing());
7770 assert_eq!(sig.subpacket(SubpacketTag::KeyFlags),
7771 Some(&Subpacket {
7772 length: 2.into(),
7773 critical: false,
7774 value: SubpacketValue::KeyFlags(
7775 KeyFlags::empty().set_certification().set_signing()),
7776 authenticated: false.into(),
7777 }));
7778
7779 assert_eq!(sig.features().unwrap(), Features::empty().set_seipdv1());
7780 assert_eq!(sig.subpacket(SubpacketTag::Features),
7781 Some(&Subpacket {
7782 length: 2.into(),
7783 critical: false,
7784 value: SubpacketValue::Features(
7785 Features::empty().set_seipdv1()),
7786 authenticated: false.into(),
7787 }));
7788
7789 let keyid = "F004 B9A4 5C58 6126".parse().unwrap();
7790 assert_eq!(sig.issuers().collect::<Vec<_>>(), vec![ &keyid ]);
7791 assert_eq!(sig.subpacket(SubpacketTag::Issuer),
7792 Some(&Subpacket {
7793 length: 9.into(),
7794 critical: false,
7795 value: SubpacketValue::Issuer(keyid),
7796 authenticated: false.into(),
7797 }));
7798
7799 let fp = "361A96BDE1A65B6D6C25AE9FF004B9A45C586126".parse().unwrap();
7800 assert_eq!(sig.issuer_fingerprints().collect::<Vec<_>>(), vec![ &fp ]);
7801 assert_eq!(sig.subpacket(SubpacketTag::IssuerFingerprint),
7802 Some(&Subpacket {
7803 length: 22.into(),
7804 critical: false,
7805 value: SubpacketValue::IssuerFingerprint(fp),
7806 authenticated: false.into(),
7807 }));
7808
7809 let n = NotationData {
7810 flags: NotationDataFlags::empty().set_human_readable(),
7811 name: "rank@navy.mil".into(),
7812 value: b"midshipman".to_vec()
7813 };
7814 assert_eq!(sig.notation_data().collect::<Vec<&NotationData>>(),
7815 vec![&n]);
7816 assert_eq!(sig.subpacket(SubpacketTag::NotationData),
7817 Some(&Subpacket {
7818 length: 32.into(),
7819 critical: false,
7820 value: SubpacketValue::NotationData(n.clone()),
7821 authenticated: false.into(),
7822 }));
7823 assert_eq!(sig.hashed_area().subpackets(SubpacketTag::NotationData)
7824 .collect::<Vec<_>>(),
7825 vec![&Subpacket {
7826 length: 32.into(),
7827 critical: false,
7828 value: SubpacketValue::NotationData(n.clone()),
7829 authenticated: false.into(),
7830 }]);
7831 } else {
7832 panic!("Expected signature!");
7833 }
7834
7835 // Test #2
7836 if let Some(&Packet::Signature(ref sig)) = pile.children().nth(3) {
7837 // tag: 2, SignatureCreationTime(1515791490)
7838 // tag: 4, ExportableCertification(false)
7839 // tag: 16, Issuer(KeyID("CEAD 0621 0934 7957"))
7840 // tag: 33, IssuerFingerprint(Fingerprint("B59B 8817 F519 DCE1 0AFD 85E4 CEAD 0621 0934 7957"))
7841
7842 // for i in 0..256 {
7843 // if let Some(sb) = sig.subpacket(i as u8) {
7844 // eprintln!(" {:?}", sb);
7845 // }
7846 // }
7847
7848 assert_eq!(sig.signature_creation_time(),
7849 Some(Timestamp::from(1515791490).into()));
7850 assert_eq!(sig.subpacket(SubpacketTag::SignatureCreationTime),
7851 Some(&Subpacket {
7852 length: 5.into(),
7853 critical: false,
7854 value: SubpacketValue::SignatureCreationTime(
7855 1515791490.into()),
7856 authenticated: false.into(),
7857 }));
7858
7859 assert_eq!(sig.exportable_certification(), Some(false));
7860 assert_eq!(sig.subpacket(SubpacketTag::ExportableCertification),
7861 Some(&Subpacket {
7862 length: 2.into(),
7863 critical: false,
7864 value: SubpacketValue::ExportableCertification(false),
7865 authenticated: false.into(),
7866 }));
7867 }
7868
7869 let pile = PacketPile::from_bytes(
7870 crate::tests::key("subpackets/marven.pgp")).unwrap();
7871
7872 // Test #3
7873 if let Some(&Packet::Signature(ref sig)) = pile.children().nth(1) {
7874 // tag: 2, SignatureCreationTime(1515791376)
7875 // tag: 7, Revocable(false)
7876 // tag: 12, RevocationKey((128, 1, Fingerprint("361A 96BD E1A6 5B6D 6C25 AE9F F004 B9A4 5C58 6126")))
7877 // tag: 16, Issuer(KeyID("CEAD 0621 0934 7957"))
7878 // tag: 33, IssuerFingerprint(Fingerprint("B59B 8817 F519 DCE1 0AFD 85E4 CEAD 0621 0934 7957"))
7879
7880 // for i in 0..256 {
7881 // if let Some(sb) = sig.subpacket(i as u8) {
7882 // eprintln!(" {:?}", sb);
7883 // }
7884 // }
7885
7886 assert_eq!(sig.signature_creation_time(),
7887 Some(Timestamp::from(1515791376).into()));
7888 assert_eq!(sig.subpacket(SubpacketTag::SignatureCreationTime),
7889 Some(&Subpacket {
7890 length: 5.into(),
7891 critical: false,
7892 value: SubpacketValue::SignatureCreationTime(
7893 1515791376.into()),
7894 authenticated: false.into(),
7895 }));
7896
7897 assert_eq!(sig.revocable(), Some(false));
7898 assert_eq!(sig.subpacket(SubpacketTag::Revocable),
7899 Some(&Subpacket {
7900 length: 2.into(),
7901 critical: false,
7902 value: SubpacketValue::Revocable(false),
7903 authenticated: false.into(),
7904 }));
7905
7906 let fp = "361A96BDE1A65B6D6C25AE9FF004B9A45C586126".parse().unwrap();
7907 let rk = RevocationKey::new(PublicKeyAlgorithm::RSAEncryptSign,
7908 fp, false);
7909 assert_eq!(sig.revocation_keys().next().unwrap(), &rk);
7910 assert_eq!(sig.subpacket(SubpacketTag::RevocationKey),
7911 Some(&Subpacket {
7912 length: 23.into(),
7913 critical: false,
7914 value: SubpacketValue::RevocationKey(rk),
7915 authenticated: false.into(),
7916 }));
7917
7918
7919 let keyid = "CEAD 0621 0934 7957".parse().unwrap();
7920 assert_eq!(sig.issuers().collect::<Vec<_>>(),
7921 vec![ &keyid ]);
7922 assert_eq!(sig.subpacket(SubpacketTag::Issuer),
7923 Some(&Subpacket {
7924 length: 9.into(),
7925 critical: false,
7926 value: SubpacketValue::Issuer(keyid),
7927 authenticated: false.into(),
7928 }));
7929
7930 let fp = "B59B8817F519DCE10AFD85E4CEAD062109347957".parse().unwrap();
7931 assert_eq!(sig.issuer_fingerprints().collect::<Vec<_>>(),
7932 vec![ &fp ]);
7933 assert_eq!(sig.subpacket(SubpacketTag::IssuerFingerprint),
7934 Some(&Subpacket {
7935 length: 22.into(),
7936 critical: false,
7937 value: SubpacketValue::IssuerFingerprint(fp),
7938 authenticated: false.into(),
7939 }));
7940
7941 // This signature does not contain any notation data.
7942 assert_eq!(sig.notation_data().count(), 0);
7943 assert_eq!(sig.subpacket(SubpacketTag::NotationData),
7944 None);
7945 assert_eq!(sig.subpackets(SubpacketTag::NotationData).count(), 0);
7946 } else {
7947 panic!("Expected signature!");
7948 }
7949
7950 // Test #4
7951 if let Some(&Packet::Signature(ref sig)) = pile.children().nth(6) {
7952 // for i in 0..256 {
7953 // if let Some(sb) = sig.subpacket(i as u8) {
7954 // eprintln!(" {:?}", sb);
7955 // }
7956 // }
7957
7958 assert_eq!(sig.signature_creation_time(),
7959 Some(Timestamp::from(1515886658).into()));
7960 assert_eq!(sig.subpacket(SubpacketTag::SignatureCreationTime),
7961 Some(&Subpacket {
7962 length: 5.into(),
7963 critical: false,
7964 value: SubpacketValue::SignatureCreationTime(
7965 1515886658.into()),
7966 authenticated: false.into(),
7967 }));
7968
7969 assert_eq!(sig.reason_for_revocation(),
7970 Some((ReasonForRevocation::Unspecified,
7971 &b"Forgot to set a sig expiration."[..])));
7972 assert_eq!(sig.subpacket(SubpacketTag::ReasonForRevocation),
7973 Some(&Subpacket {
7974 length: 33.into(),
7975 critical: false,
7976 value: SubpacketValue::ReasonForRevocation {
7977 code: ReasonForRevocation::Unspecified,
7978 reason: b"Forgot to set a sig expiration.".to_vec(),
7979 },
7980 authenticated: false.into(),
7981 }));
7982 }
7983
7984
7985 // Test #5
7986 if let Some(&Packet::Signature(ref sig)) = pile.children().nth(7) {
7987 // The only thing interesting about this signature is that it
7988 // has multiple notations.
7989
7990 assert_eq!(sig.signature_creation_time(),
7991 Some(Timestamp::from(1515791467).into()));
7992 assert_eq!(sig.subpacket(SubpacketTag::SignatureCreationTime),
7993 Some(&Subpacket {
7994 length: 5.into(),
7995 critical: false,
7996 value: SubpacketValue::SignatureCreationTime(
7997 1515791467.into()),
7998 authenticated: false.into(),
7999 }));
8000
8001 let n1 = NotationData {
8002 flags: NotationDataFlags::empty().set_human_readable(),
8003 name: "rank@navy.mil".into(),
8004 value: b"third lieutenant".to_vec()
8005 };
8006 let n2 = NotationData {
8007 flags: NotationDataFlags::empty().set_human_readable(),
8008 name: "foo@navy.mil".into(),
8009 value: b"bar".to_vec()
8010 };
8011 let n3 = NotationData {
8012 flags: NotationDataFlags::empty().set_human_readable(),
8013 name: "whistleblower@navy.mil".into(),
8014 value: b"true".to_vec()
8015 };
8016
8017 // We expect all three notations, in order.
8018 assert_eq!(sig.notation_data().collect::<Vec<&NotationData>>(),
8019 vec![&n1, &n2, &n3]);
8020
8021 // We expect only the last notation.
8022 assert_eq!(sig.subpacket(SubpacketTag::NotationData),
8023 Some(&Subpacket {
8024 length: 35.into(),
8025 critical: false,
8026 value: SubpacketValue::NotationData(n3.clone()),
8027 authenticated: false.into(),
8028 }));
8029
8030 // We expect all three notations, in order.
8031 assert_eq!(sig.subpackets(SubpacketTag::NotationData)
8032 .collect::<Vec<_>>(),
8033 vec![
8034 &Subpacket {
8035 length: 38.into(),
8036 critical: false,
8037 value: SubpacketValue::NotationData(n1),
8038 authenticated: false.into(),
8039 },
8040 &Subpacket {
8041 length: 24.into(),
8042 critical: false,
8043 value: SubpacketValue::NotationData(n2),
8044 authenticated: false.into(),
8045 },
8046 &Subpacket {
8047 length: 35.into(),
8048 critical: false,
8049 value: SubpacketValue::NotationData(n3),
8050 authenticated: false.into(),
8051 },
8052 ]);
8053 }
8054
8055 // # Test 6
8056 if let Some(&Packet::Signature(ref sig)) = pile.children().nth(8) {
8057 // A trusted signature.
8058
8059 // tag: 2, SignatureCreationTime(1515791223)
8060 // tag: 5, TrustSignature((2, 120))
8061 // tag: 6, RegularExpression([60, 91, 94, 62, 93, 43, 91, 64, 46, 93, 110, 97, 118, 121, 92, 46, 109, 105, 108, 62, 36])
8062 // tag: 16, Issuer(KeyID("F004 B9A4 5C58 6126"))
8063 // tag: 33, IssuerFingerprint(Fingerprint("361A 96BD E1A6 5B6D 6C25 AE9F F004 B9A4 5C58 6126"))
8064
8065 // for i in 0..256 {
8066 // if let Some(sb) = sig.subpacket(i as u8) {
8067 // eprintln!(" {:?}", sb);
8068 // }
8069 // }
8070
8071 assert_eq!(sig.signature_creation_time(),
8072 Some(Timestamp::from(1515791223).into()));
8073 assert_eq!(sig.subpacket(SubpacketTag::SignatureCreationTime),
8074 Some(&Subpacket {
8075 length: 5.into(),
8076 critical: false,
8077 value: SubpacketValue::SignatureCreationTime(
8078 1515791223.into()),
8079 authenticated: false.into(),
8080 }));
8081
8082 assert_eq!(sig.trust_signature(), Some((2, 120)));
8083 assert_eq!(sig.subpacket(SubpacketTag::TrustSignature),
8084 Some(&Subpacket {
8085 length: 3.into(),
8086 critical: false,
8087 value: SubpacketValue::TrustSignature {
8088 level: 2,
8089 trust: 120,
8090 },
8091 authenticated: false.into(),
8092 }));
8093
8094 // Note: our parser strips the trailing NUL.
8095 let regex = &b"<[^>]+[@.]navy\\.mil>$"[..];
8096 assert_eq!(sig.regular_expressions().collect::<Vec<&[u8]>>(),
8097 vec![ regex ]);
8098 assert_eq!(sig.subpacket(SubpacketTag::RegularExpression),
8099 Some(&Subpacket {
8100 length: 23.into(),
8101 critical: true,
8102 value: SubpacketValue::RegularExpression(regex.to_vec()),
8103 authenticated: false.into(),
8104 }));
8105 }
8106
8107 // Test #7
8108 if let Some(&Packet::Signature(ref sig)) = pile.children().nth(11) {
8109 // A subkey self-sig, which contains an embedded signature.
8110 // tag: 2, SignatureCreationTime(1515798986)
8111 // tag: 9, KeyExpirationTime(63072000)
8112 // tag: 16, Issuer(KeyID("CEAD 0621 0934 7957"))
8113 // tag: 27, KeyFlags([2])
8114 // tag: 32, EmbeddedSignature(Signature(Signature {
8115 // version: 4, sigtype: 25, timestamp: Some(1515798986),
8116 // issuer: "F682 42EA 9847 7034 5DEC 5F08 4688 10D3 D67F 6CA9",
8117 // pk_algo: 1, hash_algo: 8, hashed_area: "29 bytes",
8118 // unhashed_area: "10 bytes", hash_prefix: [162, 209],
8119 // mpis: "258 bytes"))
8120 // tag: 33, IssuerFingerprint(Fingerprint("B59B 8817 F519 DCE1 0AFD 85E4 CEAD 0621 0934 7957"))
8121
8122 // for i in 0..256 {
8123 // if let Some(sb) = sig.subpacket(i as u8) {
8124 // eprintln!(" {:?}", sb);
8125 // }
8126 // }
8127
8128 assert_eq!(sig.key_validity_period(),
8129 Some(Duration::from(63072000).into()));
8130 assert_eq!(sig.subpacket(SubpacketTag::KeyExpirationTime),
8131 Some(&Subpacket {
8132 length: 5.into(),
8133 critical: false,
8134 value: SubpacketValue::KeyExpirationTime(
8135 63072000.into()),
8136 authenticated: false.into(),
8137 }));
8138
8139 let keyid = "CEAD 0621 0934 7957".parse().unwrap();
8140 assert_eq!(sig.issuers().collect::<Vec<_>>(), vec! [&keyid ]);
8141 assert_eq!(sig.subpacket(SubpacketTag::Issuer),
8142 Some(&Subpacket {
8143 length: 9.into(),
8144 critical: false,
8145 value: SubpacketValue::Issuer(keyid),
8146 authenticated: false.into(),
8147 }));
8148
8149 let fp = "B59B8817F519DCE10AFD85E4CEAD062109347957".parse().unwrap();
8150 assert_eq!(sig.issuer_fingerprints().collect::<Vec<_>>(),
8151 vec![ &fp ]);
8152 assert_eq!(sig.subpacket(SubpacketTag::IssuerFingerprint),
8153 Some(&Subpacket {
8154 length: 22.into(),
8155 critical: false,
8156 value: SubpacketValue::IssuerFingerprint(fp),
8157 authenticated: false.into(),
8158 }));
8159
8160 assert_eq!(sig.embedded_signatures().count(), 1);
8161 assert!(sig.subpacket(SubpacketTag::EmbeddedSignature)
8162 .is_some());
8163 }
8164
8165// for (i, p) in pile.children().enumerate() {
8166// if let &Packet::Signature(ref sig) = p {
8167// eprintln!("{:?}: {:?}", i, sig);
8168// for j in 0..256 {
8169// if let Some(sb) = sig.subpacket(j as u8) {
8170// eprintln!(" {:?}", sb);
8171// }
8172// }
8173// }
8174 // }
8175 ()
8176}
8177
8178#[test]
8179fn issuer_default_v4() -> Result<()> {
8180 use crate::types::Curve;
8181
8182 let hash_algo = HashAlgorithm::SHA512;
8183 let sig = signature::SignatureBuilder::new(crate::types::SignatureType::Binary);
8184 let key: crate::packet::key::SecretKey =
8185 crate::packet::key::Key4::generate_ecc(true, Curve::Ed25519)?.into();
8186 let mut keypair = key.into_keypair()?;
8187 let hash = hash_algo.context()?.for_signature(keypair.public().version());
8188
8189 // no issuer or issuer_fingerprint present, use default
8190 let sig_ = sig.sign_hash(&mut keypair, hash.clone())?;
8191
8192 assert_eq!(sig_.issuers().collect::<Vec<_>>(),
8193 vec![ &keypair.public().keyid() ]);
8194 assert_eq!(sig_.issuer_fingerprints().collect::<Vec<_>>(),
8195 vec![ &keypair.public().fingerprint() ]);
8196
8197 let fp = Fingerprint::from_bytes(4, b"bbbbbbbbbbbbbbbbbbbb")?;
8198
8199 // issuer subpacket present, do not override
8200 let mut sig = signature::SignatureBuilder::new(crate::types::SignatureType::Binary);
8201
8202 sig = sig.set_issuer(fp.clone().into())?;
8203 let sig_ = sig.clone().sign_hash(&mut keypair, hash.clone())?;
8204
8205 assert_eq!(sig_.issuers().collect::<Vec<_>>(),
8206 vec![ &fp.clone().into() ]);
8207 assert_eq!(sig_.issuer_fingerprints().count(), 0);
8208
8209 // issuer_fingerprint subpacket present, do not override
8210 let mut sig = signature::SignatureBuilder::new(crate::types::SignatureType::Binary);
8211
8212 sig = sig.set_issuer_fingerprint(fp.clone())?;
8213 let sig_ = sig.clone().sign_hash(&mut keypair, hash.clone())?;
8214
8215 assert_eq!(sig_.issuer_fingerprints().collect::<Vec<_>>(),
8216 vec![ &fp ]);
8217 assert_eq!(sig_.issuers().count(), 0);
8218 Ok(())
8219}
8220
8221#[test]
8222fn issuer_default_v6() -> Result<()> {
8223 use crate::types::Curve;
8224
8225 let hash_algo = HashAlgorithm::SHA512;
8226 let sig = signature::SignatureBuilder::new(crate::types::SignatureType::Binary);
8227 let key: crate::packet::key::SecretKey =
8228 crate::packet::key::Key6::generate_ecc(true, Curve::Ed25519)?.into();
8229 let mut keypair = key.into_keypair()?;
8230 let hash = hash_algo.context()?.for_signature(keypair.public().version());
8231
8232 // no issuer or issuer_fingerprint present, use default
8233 let sig_ = sig.sign_hash(&mut keypair, hash.clone())?;
8234
8235 assert_eq!(sig_.issuers().collect::<Vec<_>>(),
8236 Vec::<&KeyID>::new());
8237 assert_eq!(sig_.issuer_fingerprints().collect::<Vec<_>>(),
8238 vec![ &keypair.public().fingerprint() ]);
8239
8240 let fp = Fingerprint::from_bytes(4, b"bbbbbbbbbbbbbbbbbbbb")?;
8241
8242 // issuer subpacket present, ignore, subpacket is not used with v6
8243 let mut sig = signature::SignatureBuilder::new(crate::types::SignatureType::Binary);
8244
8245 sig = sig.set_issuer(fp.clone().into())?;
8246 let sig_ = sig.clone().sign_hash(&mut keypair, hash.clone())?;
8247
8248 assert_eq!(sig_.issuers().collect::<Vec<_>>(),
8249 vec![ &fp.clone().into() ]);
8250 assert_eq!(sig_.issuer_fingerprints().collect::<Vec<_>>(),
8251 vec![ &keypair.public().fingerprint() ]);
8252
8253 // issuer_fingerprint subpacket present, do not override
8254 let mut sig = signature::SignatureBuilder::new(crate::types::SignatureType::Binary);
8255
8256 sig = sig.set_issuer_fingerprint(fp.clone())?;
8257 let sig_ = sig.clone().sign_hash(&mut keypair, hash.clone())?;
8258
8259 assert_eq!(sig_.issuer_fingerprints().collect::<Vec<_>>(),
8260 vec![ &fp ]);
8261 assert_eq!(sig_.issuers().count(), 0);
8262 Ok(())
8263}