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