sequoia_openpgp/serialize/stream.rs
1//! Streaming packet serialization.
2//!
3//! This interface provides a convenient way to create signed and/or
4//! encrypted OpenPGP messages (see [Section 10.3 of RFC 9580]) and is
5//! the preferred interface to generate messages using Sequoia. It
6//! takes advantage of OpenPGP's streaming nature to avoid unnecessary
7//! buffering.
8//!
9//! [Section 10.3 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.3
10//!
11//! To use this interface, a sink implementing [`io::Write`] is
12//! wrapped by [`Message::new`] returning a streaming [`Message`].
13//! The writer stack is a structure to compose filters that create the
14//! desired message structure. There are a number of filters that can
15//! be freely combined:
16//!
17//! - [`Armorer`] applies ASCII-Armor to the stream,
18//! - [`Encryptor`] encrypts data fed into it,
19//! - [`Compressor`] compresses data,
20//! - [`Padder`] pads data,
21//! - [`Signer`] signs data,
22//! - [`LiteralWriter`] wraps literal data (i.e. the payload) into
23//! a literal data packet,
24//! - and finally, [`ArbitraryWriter`] can be used to create
25//! arbitrary packets for testing purposes.
26//!
27//! [`io::Write`]: std::io::Write
28//! [`Message::new`]: Message::new()
29//! [`Padder`]: padding::Padder
30//!
31//! The most common structure is an optionally encrypted, optionally
32//! compressed, and optionally signed message. This structure is
33//! [supported] by all OpenPGP implementations, and applications
34//! should only create messages of that structure to increase
35//! compatibility. See the example below on how to create this
36//! structure. This is a sketch of such a message:
37//!
38//! ```text
39//! [ encryption layer: [ compression layer: [ signature group: [ literal data ]]]]
40//! ```
41//!
42//! [supported]: https://tests.sequoia-pgp.org/#Unusual_Message_Structure
43//!
44//! # Examples
45//!
46//! This example demonstrates how to create the simplest possible
47//! OpenPGP message (see [Section 10.3 of RFC 9580]) containing just a
48//! literal data packet (see [Section 5.9 of RFC 9580]):
49//!
50//! [Section 5.9 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.9
51//!
52//! ```
53//! # fn main() -> sequoia_openpgp::Result<()> {
54//! use std::io::Write;
55//! use sequoia_openpgp as openpgp;
56//! use openpgp::serialize::stream::{Message, LiteralWriter};
57//!
58//! let mut sink = vec![];
59//! {
60//! let message = Message::new(&mut sink);
61//! let mut message = LiteralWriter::new(message).build()?;
62//! message.write_all(b"Hello world.")?;
63//! message.finalize()?;
64//! }
65//! assert_eq!(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.", sink.as_slice());
66//! # Ok(()) }
67//! ```
68//!
69//! This example demonstrates how to create the most common OpenPGP
70//! message structure (see [Section 10.3 of RFC 9580]). The plaintext
71//! is first signed, then padded, encrypted, and finally ASCII armored.
72//!
73//! ```
74//! # fn main() -> sequoia_openpgp::Result<()> {
75//! use std::io::Write;
76//! use sequoia_openpgp as openpgp;
77//! use openpgp::policy::StandardPolicy;
78//! use openpgp::cert::prelude::*;
79//! use openpgp::serialize::stream::{
80//! Message, Armorer, Encryptor, Signer, LiteralWriter, padding::Padder,
81//! };
82//! # use openpgp::parse::Parse;
83//!
84//! let p = &StandardPolicy::new();
85//!
86//! let sender: Cert = // ...
87//! # Cert::from_bytes(&include_bytes!(
88//! # "../../tests/data/keys/testy-new-private.pgp")[..])?;
89//! let signing_keypair = sender.keys().secret()
90//! .with_policy(p, None).supported().alive().revoked(false).for_signing()
91//! .nth(0).unwrap()
92//! .key().clone().into_keypair()?;
93//!
94//! let recipient: Cert = // ...
95//! # sender.clone();
96//! // Note: One certificate may contain several suitable encryption keys.
97//! let recipients =
98//! recipient.keys().with_policy(p, None).supported().alive().revoked(false)
99//! // Or `for_storage_encryption()`, for data at rest.
100//! .for_transport_encryption();
101//!
102//! # let mut sink = vec![];
103//! let message = Message::new(&mut sink);
104//! let message = Armorer::new(message).build()?;
105//! let message = Encryptor::for_recipients(message, recipients).build()?;
106//! // Reduce metadata leakage by concealing the message size.
107//! let message = Padder::new(message).build()?;
108//! let message = Signer::new(message, signing_keypair)?
109//! // Prevent Surreptitious Forwarding.
110//! .add_intended_recipient(&recipient)
111//! .build()?;
112//! let mut message = LiteralWriter::new(message).build()?;
113//! message.write_all(b"Hello world.")?;
114//! message.finalize()?;
115//! # Ok(()) }
116//! ```
117
118use std::fmt;
119use std::io::{self, Write};
120use std::time::SystemTime;
121
122use crate::{
123 armor,
124 crypto,
125 Error,
126 Fingerprint,
127 HashAlgorithm,
128 KeyHandle,
129 Profile,
130 Result,
131 crypto::Password,
132 crypto::SessionKey,
133 packet::prelude::*,
134 packet::signature,
135 packet::key,
136 cert::prelude::*,
137};
138use crate::packet::header::CTB;
139use crate::packet::header::BodyLength;
140use crate::parse::HashingMode;
141use super::{
142 Marshal,
143};
144use crate::types::{
145 AEADAlgorithm,
146 CompressionAlgorithm,
147 CompressionLevel,
148 DataFormat,
149 Features,
150 SignatureType,
151 SymmetricAlgorithm,
152};
153
154pub(crate) mod writer;
155pub mod padding;
156mod partial_body;
157use partial_body::PartialBodyFilter;
158mod dash_escape;
159use dash_escape::DashEscapeFilter;
160mod trim_whitespace;
161use trim_whitespace::TrailingWSFilter;
162
163
164/// Cookie must be public because the writers are.
165#[derive(Debug)]
166struct Cookie {
167 level: usize,
168 private: Private,
169}
170
171impl Cookie {
172 /// Sets the private data part of the cookie.
173 pub fn set_private(mut self, p: Private) -> Self {
174 self.private = p;
175 self
176 }
177}
178
179/// An enum to store writer-specific data.
180#[derive(Debug)]
181enum Private {
182 Nothing,
183 Signer,
184 Armorer {
185 set_profile: Option<Profile>,
186 },
187 Encryptor {
188 profile: Profile,
189 },
190}
191
192impl Cookie {
193 fn new(level: usize) -> Self {
194 Cookie {
195 level,
196 private: Private::Nothing,
197 }
198 }
199}
200
201impl Default for Cookie {
202 fn default() -> Self {
203 Cookie::new(0)
204 }
205}
206
207/// Streams an OpenPGP message.
208///
209/// Wraps an [`io::Write`]r for use with the streaming subsystem. The
210/// `Message` is a stack of filters that create the desired message
211/// structure. Literal data must be framed using the
212/// [`LiteralWriter`] filter. Once all the has been written, the
213/// `Message` must be finalized using [`Message::finalize`].
214///
215/// [`io::Write`]: std::io::Write
216/// [`Message::finalize`]: Message::finalize()
217#[derive(Debug)]
218pub struct Message<'a>(writer::BoxStack<'a, Cookie>);
219assert_send_and_sync!(Message<'_>);
220
221impl<'a> Message<'a> {
222 /// Starts streaming an OpenPGP message.
223 ///
224 /// # Examples
225 ///
226 /// ```
227 /// # fn main() -> sequoia_openpgp::Result<()> {
228 /// use sequoia_openpgp as openpgp;
229 /// use openpgp::serialize::stream::{Message, LiteralWriter};
230 ///
231 /// # let mut sink = vec![]; // Vec<u8> implements io::Write.
232 /// let message = Message::new(&mut sink);
233 /// // Construct the writer stack here.
234 /// let mut message = LiteralWriter::new(message).build()?;
235 /// // Write literal data to `message` here.
236 /// // ...
237 /// // Finalize the message.
238 /// message.finalize()?;
239 /// # Ok(()) }
240 /// ```
241 pub fn new<W: 'a + io::Write + Send + Sync>(w: W) -> Message<'a> {
242 writer::Generic::new(w, Cookie::new(0))
243 }
244
245 /// Finalizes the topmost writer, returning the underlying writer.
246 ///
247 /// Finalizes the topmost writer, i.e. flushes any buffered data,
248 /// and pops it of the stack. This allows for fine-grained
249 /// control of the resulting message, but must be done with great
250 /// care. If done improperly, the resulting message may be
251 /// malformed.
252 ///
253 /// # Examples
254 ///
255 /// This demonstrates how to create a compressed, signed message
256 /// from a detached signature.
257 ///
258 /// ```
259 /// # fn main() -> sequoia_openpgp::Result<()> {
260 /// use std::io::Write;
261 /// use std::convert::TryFrom;
262 /// use sequoia_openpgp as openpgp;
263 /// use openpgp::packet::{Packet, Signature, one_pass_sig::OnePassSig3};
264 /// # use openpgp::parse::Parse;
265 /// use openpgp::serialize::Serialize;
266 /// use openpgp::serialize::stream::{Message, Compressor, LiteralWriter};
267 ///
268 /// let data: &[u8] = // ...
269 /// # &include_bytes!(
270 /// # "../../tests/data/messages/a-cypherpunks-manifesto.txt")[..];
271 /// let sig: Signature = // ...
272 /// # if let Packet::Signature(s) = Packet::from_bytes(&include_bytes!(
273 /// # "../../tests/data/messages/a-cypherpunks-manifesto.txt.ed25519.sig")[..])?
274 /// # { s } else { panic!() };
275 ///
276 /// # let mut sink = vec![]; // Vec<u8> implements io::Write.
277 /// let message = Message::new(&mut sink);
278 /// let mut message = Compressor::new(message).build()?;
279 ///
280 /// // First, write a one-pass-signature packet.
281 /// Packet::from(OnePassSig3::try_from(&sig)?)
282 /// .serialize(&mut message)?;
283 ///
284 /// // Then, add the literal data.
285 /// let mut message = LiteralWriter::new(message).build()?;
286 /// message.write_all(data)?;
287 ///
288 /// // Finally, pop the `LiteralWriter` off the stack to write the
289 /// // signature.
290 /// let mut message = message.finalize_one()?.unwrap();
291 /// Packet::from(sig).serialize(&mut message)?;
292 ///
293 /// // Finalize the message.
294 /// message.finalize()?;
295 /// # Ok(()) }
296 /// ```
297 pub fn finalize_one(self) -> Result<Option<Message<'a>>> {
298 Ok(self.0.into_inner()?.map(|bs| Self::from(bs)))
299 }
300
301 /// Finalizes the message.
302 ///
303 /// Finalizes all writers on the stack, flushing any buffered
304 /// data.
305 ///
306 /// # Note
307 ///
308 /// Failing to finalize the message may result in corrupted
309 /// messages.
310 ///
311 /// # Examples
312 ///
313 /// ```
314 /// # fn main() -> sequoia_openpgp::Result<()> {
315 /// use sequoia_openpgp as openpgp;
316 /// use openpgp::serialize::stream::{Message, LiteralWriter};
317 ///
318 /// # let mut sink = vec![]; // Vec<u8> implements io::Write.
319 /// let message = Message::new(&mut sink);
320 /// // Construct the writer stack here.
321 /// let mut message = LiteralWriter::new(message).build()?;
322 /// // Write literal data to `message` here.
323 /// // ...
324 /// // Finalize the message.
325 /// message.finalize()?;
326 /// # Ok(()) }
327 /// ```
328 pub fn finalize(self) -> Result<()> {
329 let mut stack = self;
330 while let Some(s) = stack.finalize_one()? {
331 stack = s;
332 }
333 Ok(())
334 }
335}
336
337impl<'a> From<&'a mut (dyn io::Write + Send + Sync)> for Message<'a> {
338 fn from(w: &'a mut (dyn io::Write + Send + Sync)) -> Self {
339 writer::Generic::new(w, Cookie::new(0))
340 }
341}
342
343
344/// Applies ASCII Armor to the message.
345///
346/// ASCII armored data (see [Section 6 of RFC 9580]) is a OpenPGP data
347/// stream that has been base64-encoded and decorated with a header,
348/// footer, and optional headers representing key-value pairs. It can
349/// be safely transmitted over protocols that can only transmit
350/// printable characters, and can be handled by end users (e.g. copied
351/// and pasted).
352///
353/// [Section 6 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-6
354pub struct Armorer<'a> {
355 kind: armor::Kind,
356 headers: Vec<(String, String)>,
357 inner: Message<'a>,
358}
359assert_send_and_sync!(Armorer<'_>);
360
361impl<'a> Armorer<'a> {
362 /// Creates a new armoring filter.
363 ///
364 /// By default, the type of the armored data is set to
365 /// [`armor::Kind`]`::Message`. To change it, use
366 /// [`Armorer::kind`]. To add headers to the armor, use
367 /// [`Armorer::add_header`].
368 ///
369 /// [`armor::Kind`]: crate::armor::Kind
370 /// [`Armorer::kind`]: Armorer::kind()
371 /// [`Armorer::add_header`]: Armorer::add_header()
372 ///
373 /// # Examples
374 ///
375 /// ```
376 /// # fn main() -> sequoia_openpgp::Result<()> {
377 /// use std::io::Write;
378 /// use sequoia_openpgp as openpgp;
379 /// use openpgp::serialize::stream::{Message, Armorer, LiteralWriter};
380 ///
381 /// let mut sink = vec![];
382 /// {
383 /// let message = Message::new(&mut sink);
384 /// let message = Armorer::new(message)
385 /// // Customize the `Armorer` here.
386 /// .build()?;
387 /// let mut message = LiteralWriter::new(message).build()?;
388 /// message.write_all(b"Hello world.")?;
389 /// message.finalize()?;
390 /// }
391 /// assert_eq!("-----BEGIN PGP MESSAGE-----\n\
392 /// \n\
393 /// yxJiAAAAAABIZWxsbyB3b3JsZC4=\n\
394 /// =6nHv\n\
395 /// -----END PGP MESSAGE-----\n",
396 /// std::str::from_utf8(&sink)?);
397 /// # Ok(()) }
398 pub fn new(inner: Message<'a>) -> Self {
399 Self {
400 kind: armor::Kind::Message,
401 headers: Vec::with_capacity(0),
402 inner,
403 }
404 }
405
406 /// Changes the kind of armoring.
407 ///
408 /// The armor header and footer changes depending on the type of
409 /// wrapped data. See [`armor::Kind`] for the possible values.
410 ///
411 /// [`armor::Kind`]: crate::armor::Kind
412 ///
413 /// # Examples
414 ///
415 /// ```
416 /// # fn main() -> sequoia_openpgp::Result<()> {
417 /// use std::io::Write;
418 /// use sequoia_openpgp as openpgp;
419 /// use openpgp::armor;
420 /// use openpgp::serialize::stream::{Message, Armorer, Signer};
421 /// # use sequoia_openpgp::policy::StandardPolicy;
422 /// # use openpgp::{Result, Cert};
423 /// # use openpgp::packet::prelude::*;
424 /// # use openpgp::crypto::KeyPair;
425 /// # use openpgp::parse::Parse;
426 /// # use openpgp::parse::stream::*;
427 /// # let p = &StandardPolicy::new();
428 /// # let cert = Cert::from_bytes(&include_bytes!(
429 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?;
430 /// # let signing_keypair
431 /// # = cert.keys().secret()
432 /// # .with_policy(p, None).alive().revoked(false).for_signing()
433 /// # .nth(0).unwrap()
434 /// # .key().clone().into_keypair()?;
435 ///
436 /// let mut sink = vec![];
437 /// {
438 /// let message = Message::new(&mut sink);
439 /// let message = Armorer::new(message)
440 /// .kind(armor::Kind::Signature)
441 /// .build()?;
442 /// let mut signer = Signer::new(message, signing_keypair)?
443 /// .detached()
444 /// .build()?;
445 ///
446 /// // Write the data directly to the `Signer`.
447 /// signer.write_all(b"Make it so, number one!")?;
448 /// // In reality, just io::copy() the file to be signed.
449 /// signer.finalize()?;
450 /// }
451 ///
452 /// assert!(std::str::from_utf8(&sink)?
453 /// .starts_with("-----BEGIN PGP SIGNATURE-----\n"));
454 /// # Ok(()) }
455 pub fn kind(mut self, kind: armor::Kind) -> Self {
456 self.kind = kind;
457 self
458 }
459
460 /// Adds a header to the armor block.
461 ///
462 /// There are a number of defined armor header keys (see [Section
463 /// 6 of RFC 9580]), but in practice, any key may be used, as
464 /// implementations should simply ignore unknown keys.
465 ///
466 /// [Section 6 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-6
467 ///
468 /// # Examples
469 ///
470 /// ```
471 /// # fn main() -> sequoia_openpgp::Result<()> {
472 /// use std::io::Write;
473 /// use sequoia_openpgp as openpgp;
474 /// use openpgp::serialize::stream::{Message, Armorer, LiteralWriter};
475 ///
476 /// let mut sink = vec![];
477 /// {
478 /// let message = Message::new(&mut sink);
479 /// let message = Armorer::new(message)
480 /// .add_header("Comment", "No comment.")
481 /// .build()?;
482 /// let mut message = LiteralWriter::new(message).build()?;
483 /// message.write_all(b"Hello world.")?;
484 /// message.finalize()?;
485 /// }
486 /// assert_eq!("-----BEGIN PGP MESSAGE-----\n\
487 /// Comment: No comment.\n\
488 /// \n\
489 /// yxJiAAAAAABIZWxsbyB3b3JsZC4=\n\
490 /// =6nHv\n\
491 /// -----END PGP MESSAGE-----\n",
492 /// std::str::from_utf8(&sink)?);
493 /// # Ok(()) }
494 pub fn add_header<K, V>(mut self, key: K, value: V) -> Self
495 where K: AsRef<str>,
496 V: AsRef<str>,
497 {
498 self.headers.push((key.as_ref().to_string(),
499 value.as_ref().to_string()));
500 self
501 }
502
503 /// Builds the armor writer, returning the writer stack.
504 ///
505 /// # Examples
506 ///
507 /// ```
508 /// # fn main() -> sequoia_openpgp::Result<()> {
509 /// use sequoia_openpgp as openpgp;
510 /// use openpgp::serialize::stream::{Message, Armorer, LiteralWriter};
511 ///
512 /// # let mut sink = vec![];
513 /// let message = Message::new(&mut sink);
514 /// let message = Armorer::new(message)
515 /// // Customize the `Armorer` here.
516 /// .build()?;
517 /// # Ok(()) }
518 pub fn build(self) -> Result<Message<'a>> {
519 let level = self.inner.as_ref().cookie_ref().level;
520 let mut cookie = Cookie::new(level + 1);
521 cookie.private = Private::Armorer {
522 set_profile: None,
523 };
524
525 writer::Armorer::new(
526 self.inner,
527 cookie,
528 self.kind,
529 self.headers,
530 )
531 }
532}
533
534impl<'a> fmt::Debug for Armorer<'a> {
535 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
536 f.debug_struct("Armorer")
537 .field("inner", &self.inner)
538 .field("kind", &self.kind)
539 .field("headers", &self.headers)
540 .finish()
541 }
542}
543
544
545/// Writes an arbitrary packet.
546///
547/// This writer can be used to construct arbitrary OpenPGP packets.
548/// This is mainly useful for testing. The body will be written using
549/// partial length encoding, or, if the body is short, using full
550/// length encoding.
551pub struct ArbitraryWriter<'a> {
552 inner: writer::BoxStack<'a, Cookie>,
553}
554assert_send_and_sync!(ArbitraryWriter<'_>);
555
556impl<'a> ArbitraryWriter<'a> {
557 /// Creates a new writer with the given tag.
558 ///
559 /// # Examples
560 ///
561 /// ```
562 /// # fn main() -> sequoia_openpgp::Result<()> {
563 /// use std::io::Write;
564 /// use sequoia_openpgp as openpgp;
565 /// use openpgp::packet::Tag;
566 /// use openpgp::serialize::stream::{Message, ArbitraryWriter};
567 ///
568 /// let mut sink = vec![];
569 /// {
570 /// let message = Message::new(&mut sink);
571 /// let mut message = ArbitraryWriter::new(message, Tag::Literal)?;
572 /// message.write_all(b"t")?; // type
573 /// message.write_all(b"\x00")?; // filename length
574 /// message.write_all(b"\x00\x00\x00\x00")?; // date
575 /// message.write_all(b"Hello world.")?; // body
576 /// message.finalize()?;
577 /// }
578 /// assert_eq!(b"\xcb\x12t\x00\x00\x00\x00\x00Hello world.",
579 /// sink.as_slice());
580 /// # Ok(()) }
581 pub fn new(mut inner: Message<'a>, tag: Tag)
582 -> Result<Message<'a>> {
583 let level = inner.as_ref().cookie_ref().level + 1;
584 CTB::new(tag).serialize(&mut inner)?;
585 Ok(Message::from(Box::new(ArbitraryWriter {
586 inner: PartialBodyFilter::new(inner, Cookie::new(level)).into()
587 })))
588 }
589}
590
591impl<'a> fmt::Debug for ArbitraryWriter<'a> {
592 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
593 f.debug_struct("ArbitraryWriter")
594 .field("inner", &self.inner)
595 .finish()
596 }
597}
598
599impl<'a> Write for ArbitraryWriter<'a> {
600 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
601 self.inner.write(buf)
602 }
603 fn flush(&mut self) -> io::Result<()> {
604 self.inner.flush()
605 }
606}
607
608impl<'a> writer::Stackable<'a, Cookie> for ArbitraryWriter<'a> {
609 fn into_inner(self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> {
610 Box::new(self.inner).into_inner()
611 }
612 fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> {
613 unreachable!("Only implemented by Signer")
614 }
615 /// Sets the inner stackable.
616 fn mount(&mut self, _new: writer::BoxStack<'a, Cookie>) {
617 unreachable!("Only implemented by Signer")
618 }
619 fn inner_ref(&self) -> Option<&(dyn writer::Stackable<'a, Cookie> + Send + Sync)> {
620 Some(self.inner.as_ref())
621 }
622 fn inner_mut(&mut self) -> Option<&mut (dyn writer::Stackable<'a, Cookie> + Send + Sync)> {
623 Some(self.inner.as_mut())
624 }
625 fn cookie_set(&mut self, cookie: Cookie) -> Cookie {
626 self.inner.cookie_set(cookie)
627 }
628 fn cookie_ref(&self) -> &Cookie {
629 self.inner.cookie_ref()
630 }
631 fn cookie_mut(&mut self) -> &mut Cookie {
632 self.inner.cookie_mut()
633 }
634 fn position(&self) -> u64 {
635 self.inner.position()
636 }
637}
638
639/// Signs a message.
640///
641/// Signs a message with every [`crypto::Signer`] added to the
642/// streaming signer.
643///
644/// [`crypto::Signer`]: super::super::crypto::Signer
645pub struct Signer<'a> {
646 // The underlying writer.
647 //
648 // Because this writer implements `Drop`, we cannot move the inner
649 // writer out of this writer. We therefore wrap it with `Option`
650 // so that we can `take()` it.
651 //
652 // Furthermore, the LiteralWriter will pop us off the stack, and
653 // take our inner reader. If that happens, we only update the
654 // digests.
655 inner: Option<writer::BoxStack<'a, Cookie>>,
656 signers: Vec<(Box<dyn crypto::Signer + Send + Sync + 'a>,
657 HashAlgorithm, Vec<u8>)>,
658
659 /// The set of acceptable hashes.
660 acceptable_hash_algos: Vec<HashAlgorithm>,
661
662 /// The explicitly selected algo, if any.
663 hash_algo: Option<HashAlgorithm>,
664
665 intended_recipients: Vec<Fingerprint>,
666 mode: SignatureMode,
667 template: signature::SignatureBuilder,
668 creation_time: Option<SystemTime>,
669 hashes: Vec<HashingMode<crypto::hash::Context>>,
670 cookie: Cookie,
671 position: u64,
672}
673assert_send_and_sync!(Signer<'_>);
674
675#[derive(Clone, Copy, Debug, PartialEq, Eq)]
676enum SignatureMode {
677 Inline,
678 Detached,
679 Cleartext,
680}
681
682impl<'a> Signer<'a> {
683 /// Creates a signer.
684 ///
685 /// Signs the message with the given [`crypto::Signer`]. To
686 /// create more than one signature, add more [`crypto::Signer`]s
687 /// using [`Signer::add_signer`]. Properties of the signatures
688 /// can be tweaked using the methods of this type. Notably, to
689 /// generate a detached signature (see [Section 10.4 of RFC
690 /// 9580]), use [`Signer::detached`]. For even more control over
691 /// the generated signatures, use [`Signer::with_template`].
692 ///
693 /// [`crypto::Signer`]: super::super::crypto::Signer
694 /// [`Signer::add_signer`]: Signer::add_signer()
695 /// [Section 10.4 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.4
696 /// [`Signer::detached`]: Signer::detached()
697 /// [`Signer::with_template`]: Signer::with_template()
698 ///
699 /// # Examples
700 ///
701 /// ```
702 /// # fn main() -> sequoia_openpgp::Result<()> {
703 /// use std::io::{Read, Write};
704 /// use sequoia_openpgp as openpgp;
705 /// use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
706 /// use openpgp::policy::StandardPolicy;
707 /// # use openpgp::{Result, Cert};
708 /// # use openpgp::packet::prelude::*;
709 /// # use openpgp::parse::Parse;
710 /// # use openpgp::parse::stream::*;
711 ///
712 /// let p = &StandardPolicy::new();
713 /// let cert: Cert = // ...
714 /// # Cert::from_bytes(&include_bytes!(
715 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?;
716 /// let signing_keypair = cert.keys().secret()
717 /// .with_policy(p, None).supported().alive().revoked(false).for_signing()
718 /// .nth(0).unwrap()
719 /// .key().clone().into_keypair()?;
720 ///
721 /// let mut sink = vec![];
722 /// {
723 /// let message = Message::new(&mut sink);
724 /// let message = Signer::new(message, signing_keypair)?
725 /// // Customize the `Signer` here.
726 /// .build()?;
727 /// let mut message = LiteralWriter::new(message).build()?;
728 /// message.write_all(b"Make it so, number one!")?;
729 /// message.finalize()?;
730 /// }
731 ///
732 /// // Now check the signature.
733 /// struct Helper<'a>(&'a openpgp::Cert);
734 /// impl<'a> VerificationHelper for Helper<'a> {
735 /// fn get_certs(&mut self, _: &[openpgp::KeyHandle])
736 /// -> openpgp::Result<Vec<openpgp::Cert>> {
737 /// Ok(vec![self.0.clone()])
738 /// }
739 ///
740 /// fn check(&mut self, structure: MessageStructure)
741 /// -> openpgp::Result<()> {
742 /// if let MessageLayer::SignatureGroup { ref results } =
743 /// structure.iter().nth(0).unwrap()
744 /// {
745 /// results.get(0).unwrap().as_ref().unwrap();
746 /// Ok(())
747 /// } else { panic!() }
748 /// }
749 /// }
750 ///
751 /// let mut verifier = VerifierBuilder::from_bytes(&sink)?
752 /// .with_policy(p, None, Helper(&cert))?;
753 ///
754 /// let mut message = String::new();
755 /// verifier.read_to_string(&mut message)?;
756 /// assert_eq!(&message, "Make it so, number one!");
757 /// # Ok(()) }
758 /// ```
759 pub fn new<S>(inner: Message<'a>, signer: S) -> Result<Self>
760 where S: crypto::Signer + Send + Sync + 'a
761 {
762 Self::with_template(inner, signer,
763 signature::SignatureBuilder::new(SignatureType::Binary))
764 }
765
766 /// Creates a signer with a given signature template.
767 ///
768 /// Signs the message with the given [`crypto::Signer`] like
769 /// [`Signer::new`], but allows more control over the generated
770 /// signatures. The given [`signature::SignatureBuilder`] is used to
771 /// create all the signatures.
772 ///
773 /// For every signature, the creation time is set to the current
774 /// time or the one specified using [`Signer::creation_time`], the
775 /// intended recipients are added (see
776 /// [`Signer::add_intended_recipient`]), the issuer and issuer
777 /// fingerprint subpackets are set according to the signing key,
778 /// and the hash algorithm set using [`Signer::hash_algo`] is used
779 /// to create the signature.
780 ///
781 /// [`crypto::Signer`]: super::super::crypto::Signer
782 /// [`Signer::new`]: Message::new()
783 /// [`signature::SignatureBuilder`]: crate::packet::signature::SignatureBuilder
784 /// [`Signer::creation_time`]: Signer::creation_time()
785 /// [`Signer::hash_algo`]: Signer::hash_algo()
786 /// [`Signer::add_intended_recipient`]: Signer::add_intended_recipient()
787 ///
788 /// # Examples
789 ///
790 /// ```
791 /// # fn main() -> sequoia_openpgp::Result<()> {
792 /// use std::io::{Read, Write};
793 /// use sequoia_openpgp as openpgp;
794 /// use openpgp::types::SignatureType;
795 /// use openpgp::packet::signature;
796 /// use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
797 /// # use openpgp::policy::StandardPolicy;
798 /// # use openpgp::{Result, Cert};
799 /// # use openpgp::packet::prelude::*;
800 /// # use openpgp::parse::Parse;
801 /// # use openpgp::parse::stream::*;
802 /// #
803 /// # let p = &StandardPolicy::new();
804 /// # let cert: Cert = // ...
805 /// # Cert::from_bytes(&include_bytes!(
806 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?;
807 /// # let signing_keypair = cert.keys().secret()
808 /// # .with_policy(p, None).supported().alive().revoked(false).for_signing()
809 /// # .nth(0).unwrap()
810 /// # .key().clone().into_keypair()?;
811 /// # let mut sink = vec![];
812 ///
813 /// let message = Message::new(&mut sink);
814 /// let message = Signer::with_template(
815 /// message, signing_keypair,
816 /// signature::SignatureBuilder::new(SignatureType::Text)
817 /// .add_notation("issuer@starfleet.command", "Jean-Luc Picard",
818 /// None, true)?)?
819 /// // Further customize the `Signer` here.
820 /// .build()?;
821 /// let mut message = LiteralWriter::new(message).build()?;
822 /// message.write_all(b"Make it so, number one!")?;
823 /// message.finalize()?;
824 /// # Ok(()) }
825 /// ```
826 pub fn with_template<S, T>(inner: Message<'a>, signer: S, template: T)
827 -> Result<Self>
828 where S: crypto::Signer + Send + Sync + 'a,
829 T: Into<signature::SignatureBuilder>,
830 {
831 let inner = writer::BoxStack::from(inner);
832 let level = inner.cookie_ref().level + 1;
833 Signer {
834 inner: Some(inner),
835 signers: Default::default(),
836 acceptable_hash_algos:
837 crate::crypto::hash::default_hashes().to_vec(),
838 intended_recipients: Vec::new(),
839 mode: SignatureMode::Inline,
840 template: template.into(),
841 creation_time: None,
842 hash_algo: Default::default(),
843 hashes: vec![],
844 cookie: Cookie {
845 level,
846 private: Private::Signer,
847 },
848 position: 0,
849 }.add_signer(signer)
850 }
851
852 /// Creates a signer for a detached signature.
853 ///
854 /// Changes the `Signer` to create a detached signature (see
855 /// [Section 10.4 of RFC 9580]). Note that the literal data *must
856 /// not* be wrapped using the [`LiteralWriter`].
857 ///
858 /// This overrides any prior call to [`Signer::cleartext`].
859 ///
860 /// [Section 10.4 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.4
861 /// [`Signer::cleartext`]: Signer::cleartext()
862 ///
863 /// # Examples
864 ///
865 /// ```
866 /// # fn main() -> sequoia_openpgp::Result<()> {
867 /// use std::io::Write;
868 /// use sequoia_openpgp as openpgp;
869 /// use openpgp::serialize::stream::{Message, Signer};
870 /// use openpgp::policy::StandardPolicy;
871 /// # use openpgp::{Result, Cert};
872 /// # use openpgp::packet::prelude::*;
873 /// # use openpgp::crypto::KeyPair;
874 /// # use openpgp::parse::Parse;
875 /// # use openpgp::parse::stream::*;
876 ///
877 /// let p = &StandardPolicy::new();
878 /// # let cert = Cert::from_bytes(&include_bytes!(
879 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?;
880 /// # let signing_keypair
881 /// # = cert.keys().secret()
882 /// # .with_policy(p, None).supported().alive().revoked(false).for_signing()
883 /// # .nth(0).unwrap()
884 /// # .key().clone().into_keypair()?;
885 ///
886 /// let mut sink = vec![];
887 /// {
888 /// let message = Message::new(&mut sink);
889 /// let mut signer = Signer::new(message, signing_keypair)?
890 /// .detached()
891 /// // Customize the `Signer` here.
892 /// .build()?;
893 ///
894 /// // Write the data directly to the `Signer`.
895 /// signer.write_all(b"Make it so, number one!")?;
896 /// // In reality, just io::copy() the file to be signed.
897 /// signer.finalize()?;
898 /// }
899 ///
900 /// // Now check the signature.
901 /// struct Helper<'a>(&'a openpgp::Cert);
902 /// impl<'a> VerificationHelper for Helper<'a> {
903 /// fn get_certs(&mut self, _: &[openpgp::KeyHandle])
904 /// -> openpgp::Result<Vec<openpgp::Cert>> {
905 /// Ok(vec![self.0.clone()])
906 /// }
907 ///
908 /// fn check(&mut self, structure: MessageStructure)
909 /// -> openpgp::Result<()> {
910 /// if let MessageLayer::SignatureGroup { ref results } =
911 /// structure.iter().nth(0).unwrap()
912 /// {
913 /// results.get(0).unwrap().as_ref().unwrap();
914 /// Ok(())
915 /// } else { panic!() }
916 /// }
917 /// }
918 ///
919 /// let mut verifier = DetachedVerifierBuilder::from_bytes(&sink)?
920 /// .with_policy(p, None, Helper(&cert))?;
921 ///
922 /// verifier.verify_bytes(b"Make it so, number one!")?;
923 /// # Ok(()) }
924 /// ```
925 pub fn detached(mut self) -> Self {
926 self.mode = SignatureMode::Detached;
927 self
928 }
929
930 /// Creates a signer for a cleartext signed message.
931 ///
932 /// Changes the `Signer` to create a cleartext signed message (see
933 /// [Section 7 of RFC 9580]). Note that the literal data *must
934 /// not* be wrapped using the [`LiteralWriter`]. This implies
935 /// ASCII armored output, *do not* add an [`Armorer`] to the
936 /// stack.
937 ///
938 /// Note:
939 ///
940 /// - The cleartext signature framework does not hash trailing
941 /// whitespace (in this case, space and tab, see [Section 7.2 of
942 /// RFC 9580] for more information). We align what we emit and
943 /// what is being signed by trimming whitespace off of line
944 /// endings.
945 ///
946 /// - That means that you can not recover a byte-accurate copy of
947 /// the signed message if your message contains either a line
948 /// with trailing whitespace, or no final newline. This is a
949 /// limitation of the Cleartext Signature Framework, which is
950 /// not designed to be reversible (see [Section 7 of RFC 9580]).
951 ///
952 /// This overrides any prior call to [`Signer::detached`].
953 ///
954 /// [Section 7 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-7
955 /// [Section 7.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-7.2
956 /// [`Signer::detached`]: Signer::detached()
957 ///
958 /// # Examples
959 ///
960 /// ```
961 /// # fn main() -> sequoia_openpgp::Result<()> {
962 /// use std::io::{Write, Read};
963 /// use sequoia_openpgp as openpgp;
964 /// use openpgp::serialize::stream::{Message, Signer};
965 /// use openpgp::policy::StandardPolicy;
966 /// # use openpgp::{Result, Cert};
967 /// # use openpgp::packet::prelude::*;
968 /// # use openpgp::crypto::KeyPair;
969 /// # use openpgp::parse::Parse;
970 /// # use openpgp::parse::stream::*;
971 ///
972 /// let p = &StandardPolicy::new();
973 /// # let cert = Cert::from_bytes(&include_bytes!(
974 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?;
975 /// # let signing_keypair
976 /// # = cert.keys().secret()
977 /// # .with_policy(p, None).supported().alive().revoked(false).for_signing()
978 /// # .nth(0).unwrap()
979 /// # .key().clone().into_keypair()?;
980 ///
981 /// let mut sink = vec![];
982 /// {
983 /// let message = Message::new(&mut sink);
984 /// let mut signer = Signer::new(message, signing_keypair)?
985 /// .cleartext()
986 /// // Customize the `Signer` here.
987 /// .build()?;
988 ///
989 /// // Write the data directly to the `Signer`.
990 /// signer.write_all(b"Make it so, number one!")?;
991 /// // In reality, just io::copy() the file to be signed.
992 /// signer.finalize()?;
993 /// }
994 ///
995 /// // Now check the signature.
996 /// struct Helper<'a>(&'a openpgp::Cert);
997 /// impl<'a> VerificationHelper for Helper<'a> {
998 /// fn get_certs(&mut self, _: &[openpgp::KeyHandle])
999 /// -> openpgp::Result<Vec<openpgp::Cert>> {
1000 /// Ok(vec![self.0.clone()])
1001 /// }
1002 ///
1003 /// fn check(&mut self, structure: MessageStructure)
1004 /// -> openpgp::Result<()> {
1005 /// if let MessageLayer::SignatureGroup { ref results } =
1006 /// structure.iter().nth(0).unwrap()
1007 /// {
1008 /// results.get(0).unwrap().as_ref().unwrap();
1009 /// Ok(())
1010 /// } else { panic!() }
1011 /// }
1012 /// }
1013 ///
1014 /// let mut verifier = VerifierBuilder::from_bytes(&sink)?
1015 /// .with_policy(p, None, Helper(&cert))?;
1016 ///
1017 /// let mut content = Vec::new();
1018 /// verifier.read_to_end(&mut content)?;
1019 /// assert_eq!(content, b"Make it so, number one!");
1020 /// # Ok(()) }
1021 /// ```
1022 //
1023 // Some notes on the implementation:
1024 //
1025 // There are a few pitfalls when implementing the CSF. We
1026 // separate concerns as much as possible.
1027 //
1028 // - Trailing whitespace must be stripped. We do this using the
1029 // TrailingWSFilter before the data hits this streaming signer.
1030 // This filter also adds a final newline, if missing.
1031 //
1032 // - We hash what we get from the TrailingWSFilter.
1033 //
1034 // - We write into the DashEscapeFilter, which takes care of the
1035 // dash-escaping.
1036 pub fn cleartext(mut self) -> Self {
1037 self.mode = SignatureMode::Cleartext;
1038 self
1039 }
1040
1041 /// Adds an additional signer.
1042 ///
1043 /// Can be used multiple times.
1044 ///
1045 /// Note that some signers only support a subset of hash
1046 /// algorithms, see [`crate::crypto::Signer.acceptable_hashes`].
1047 /// If the given signer supports at least one hash from the
1048 /// current set of acceptable hashes, the signer is added and all
1049 /// algorithms not supported by it are removed from the set of
1050 /// acceptable hashes. Otherwise, an error is returned.
1051 ///
1052 /// # Examples
1053 ///
1054 /// ```
1055 /// # fn main() -> sequoia_openpgp::Result<()> {
1056 /// use std::io::Write;
1057 /// use sequoia_openpgp as openpgp;
1058 /// use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
1059 /// # use openpgp::policy::StandardPolicy;
1060 /// # use openpgp::{Result, Cert};
1061 /// # use openpgp::packet::prelude::*;
1062 /// # use openpgp::parse::Parse;
1063 /// # use openpgp::parse::stream::*;
1064 ///
1065 /// # let p = &StandardPolicy::new();
1066 /// # let cert = Cert::from_bytes(&include_bytes!(
1067 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?;
1068 /// # let signing_keypair = cert.keys().secret()
1069 /// # .with_policy(p, None).supported().alive().revoked(false).for_signing()
1070 /// # .nth(0).unwrap()
1071 /// # .key().clone().into_keypair()?;
1072 /// # let additional_signing_keypair = cert.keys().secret()
1073 /// # .with_policy(p, None).supported().alive().revoked(false).for_signing()
1074 /// # .nth(0).unwrap()
1075 /// # .key().clone().into_keypair()?;
1076 ///
1077 /// # let mut sink = vec![];
1078 /// let message = Message::new(&mut sink);
1079 /// let message = Signer::new(message, signing_keypair)?
1080 /// .add_signer(additional_signing_keypair)?
1081 /// .build()?;
1082 /// let mut message = LiteralWriter::new(message).build()?;
1083 /// message.write_all(b"Make it so, number one!")?;
1084 /// message.finalize()?;
1085 /// # Ok(()) }
1086 /// ```
1087 pub fn add_signer<S>(mut self, signer: S) -> Result<Self>
1088 where S: crypto::Signer + Send + Sync + 'a
1089 {
1090 // Update the set of acceptable hash algorithms.
1091 let is_sorted = |data: &[HashAlgorithm]| {
1092 data.windows(2).all(|w| w[0] <= w[1])
1093 };
1094
1095 let mut signer_hashes = signer.acceptable_hashes();
1096 let mut signer_hashes_;
1097 if ! is_sorted(signer_hashes) {
1098 signer_hashes_ = signer_hashes.to_vec();
1099 signer_hashes_.sort();
1100 signer_hashes = &signer_hashes_;
1101 }
1102 self.acceptable_hash_algos.retain(
1103 |hash| signer_hashes.binary_search(hash).is_ok());
1104
1105 if self.acceptable_hash_algos.is_empty() {
1106 return Err(Error::NoAcceptableHash.into());
1107 }
1108
1109 if let Some(a) = self.hash_algo {
1110 if ! self.acceptable_hash_algos.contains(&a) {
1111 return Err(Error::NoAcceptableHash.into());
1112 }
1113 }
1114
1115 self.signers.push((Box::new(signer), Default::default(), Vec::new()));
1116 Ok(self)
1117 }
1118
1119 /// Adds an intended recipient.
1120 ///
1121 /// Indicates that the given certificate is an intended recipient
1122 /// of this message. Can be used multiple times. This prevents
1123 /// [*Surreptitious Forwarding*] of encrypted and signed messages,
1124 /// i.e. forwarding a signed message using a different encryption
1125 /// context.
1126 ///
1127 /// [*Surreptitious Forwarding*]: http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html
1128 ///
1129 /// # Examples
1130 ///
1131 /// ```
1132 /// # fn main() -> sequoia_openpgp::Result<()> {
1133 /// use std::io::Write;
1134 /// use sequoia_openpgp as openpgp;
1135 /// use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
1136 /// # use openpgp::policy::StandardPolicy;
1137 /// # use openpgp::{Result, Cert};
1138 /// # use openpgp::packet::prelude::*;
1139 /// # use openpgp::crypto::KeyPair;
1140 /// # use openpgp::parse::Parse;
1141 /// # use openpgp::parse::stream::*;
1142 ///
1143 /// # let p = &StandardPolicy::new();
1144 /// # let cert = Cert::from_bytes(&include_bytes!(
1145 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?;
1146 /// # let signing_keypair = cert.keys().secret()
1147 /// # .with_policy(p, None).supported().alive().revoked(false).for_signing()
1148 /// # .nth(0).unwrap()
1149 /// # .key().clone().into_keypair()?;
1150 /// let recipient: Cert = // ...
1151 /// # Cert::from_bytes(&include_bytes!(
1152 /// # "../../tests/data/keys/testy.pgp")[..])?;
1153 ///
1154 /// # let mut sink = vec![];
1155 /// let message = Message::new(&mut sink);
1156 /// let message = Signer::new(message, signing_keypair)?
1157 /// .add_intended_recipient(&recipient)
1158 /// .build()?;
1159 /// let mut message = LiteralWriter::new(message).build()?;
1160 /// message.write_all(b"Make it so, number one!")?;
1161 /// message.finalize()?;
1162 /// # Ok(()) }
1163 /// ```
1164 pub fn add_intended_recipient(mut self, recipient: &Cert) -> Self {
1165 self.intended_recipients.push(recipient.fingerprint());
1166 self
1167 }
1168
1169 /// Sets the preferred hash algorithm to use for the signatures.
1170 ///
1171 /// Note that some signers only support a subset of hash
1172 /// algorithms, see [`crate::crypto::Signer.acceptable_hashes`].
1173 /// If the given algorithm is not supported by all signers, an
1174 /// error is returned.
1175 ///
1176 /// # Examples
1177 ///
1178 /// ```
1179 /// # fn main() -> sequoia_openpgp::Result<()> {
1180 /// use std::io::Write;
1181 /// use sequoia_openpgp as openpgp;
1182 /// use openpgp::types::HashAlgorithm;
1183 /// use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
1184 /// # use openpgp::policy::StandardPolicy;
1185 /// # use openpgp::{Result, Cert};
1186 /// # use openpgp::packet::prelude::*;
1187 /// # use openpgp::parse::Parse;
1188 /// # use openpgp::parse::stream::*;
1189 ///
1190 /// # let p = &StandardPolicy::new();
1191 /// # let cert = Cert::from_bytes(&include_bytes!(
1192 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?;
1193 /// # let signing_keypair = cert.keys().secret()
1194 /// # .with_policy(p, None).supported().alive().revoked(false).for_signing()
1195 /// # .nth(0).unwrap()
1196 /// # .key().clone().into_keypair()?;
1197 ///
1198 /// # let mut sink = vec![];
1199 /// let message = Message::new(&mut sink);
1200 /// let message = Signer::new(message, signing_keypair)?
1201 /// .hash_algo(HashAlgorithm::SHA384)?
1202 /// .build()?;
1203 /// let mut message = LiteralWriter::new(message).build()?;
1204 /// message.write_all(b"Make it so, number one!")?;
1205 /// message.finalize()?;
1206 /// # Ok(()) }
1207 /// ```
1208 pub fn hash_algo(mut self, algo: HashAlgorithm) -> Result<Self> {
1209 if self.acceptable_hash_algos.contains(&algo) {
1210 self.hash_algo = Some(algo);
1211 Ok(self)
1212 } else {
1213 Err(Error::NoAcceptableHash.into())
1214 }
1215 }
1216
1217 /// Sets the signature's creation time to `time`.
1218 ///
1219 /// Note: it is up to the caller to make sure the signing keys are
1220 /// actually valid as of `time`.
1221 ///
1222 /// # Examples
1223 ///
1224 /// ```
1225 /// # fn main() -> sequoia_openpgp::Result<()> {
1226 /// use std::io::Write;
1227 /// use sequoia_openpgp as openpgp;
1228 /// use openpgp::types::Timestamp;
1229 /// use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
1230 /// use openpgp::policy::StandardPolicy;
1231 /// # use openpgp::{Result, Cert};
1232 /// # use openpgp::packet::prelude::*;
1233 /// # use openpgp::parse::Parse;
1234 /// # use openpgp::parse::stream::*;
1235 ///
1236 /// let p = &StandardPolicy::new();
1237 /// let cert: Cert = // ...
1238 /// # Cert::from_bytes(&include_bytes!(
1239 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?;
1240 /// let signing_key = cert.keys().secret()
1241 /// .with_policy(p, None).supported().alive().revoked(false).for_signing()
1242 /// .nth(0).unwrap()
1243 /// .key();
1244 /// let signing_keypair = signing_key.clone().into_keypair()?;
1245 ///
1246 /// # let mut sink = vec![];
1247 /// let message = Message::new(&mut sink);
1248 /// let message = Signer::new(message, signing_keypair)?
1249 /// .creation_time(Timestamp::now()
1250 /// .round_down(None, signing_key.creation_time())?)
1251 /// .build()?;
1252 /// let mut message = LiteralWriter::new(message).build()?;
1253 /// message.write_all(b"Make it so, number one!")?;
1254 /// message.finalize()?;
1255 /// # Ok(()) }
1256 /// ```
1257 pub fn creation_time<T: Into<SystemTime>>(mut self, creation_time: T)
1258 -> Self
1259 {
1260 self.creation_time = Some(creation_time.into());
1261 self
1262 }
1263
1264 /// Builds the signer, returning the writer stack.
1265 ///
1266 /// The most useful filter to push to the writer stack next is the
1267 /// [`LiteralWriter`]. Note, if you are creating a signed OpenPGP
1268 /// message (see [Section 10.3 of RFC 9580]), literal data *must*
1269 /// be wrapped using the [`LiteralWriter`]. On the other hand, if
1270 /// you are creating a detached signature (see [Section 10.4 of
1271 /// RFC 9580]), the literal data *must not* be wrapped using the
1272 /// [`LiteralWriter`].
1273 ///
1274 /// [Section 10.3 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.3
1275 /// [Section 10.4 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.4
1276 ///
1277 /// # Examples
1278 ///
1279 /// ```
1280 /// # fn main() -> sequoia_openpgp::Result<()> {
1281 /// use std::io::Write;
1282 /// use sequoia_openpgp as openpgp;
1283 /// use openpgp::types::Timestamp;
1284 /// use openpgp::serialize::stream::{Message, Signer};
1285 /// # use openpgp::policy::StandardPolicy;
1286 /// # use openpgp::{Result, Cert};
1287 /// # use openpgp::packet::prelude::*;
1288 /// # use openpgp::parse::Parse;
1289 /// # use openpgp::parse::stream::*;
1290 ///
1291 /// # let p = &StandardPolicy::new();
1292 /// # let cert: Cert = // ...
1293 /// # Cert::from_bytes(&include_bytes!(
1294 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?;
1295 /// # let signing_keypair
1296 /// # = cert.keys().secret()
1297 /// # .with_policy(p, None).supported().alive().revoked(false).for_signing()
1298 /// # .nth(0).unwrap()
1299 /// # .key().clone().into_keypair()?;
1300 /// #
1301 /// # let mut sink = vec![];
1302 /// let message = Message::new(&mut sink);
1303 /// let message = Signer::new(message, signing_keypair)?
1304 /// // Customize the `Signer` here.
1305 /// .build()?;
1306 /// # Ok(()) }
1307 /// ```
1308 pub fn build(mut self) -> Result<Message<'a>>
1309 {
1310 assert!(!self.signers.is_empty(), "The constructor adds a signer.");
1311 assert!(self.inner.is_some(), "The constructor adds an inner writer.");
1312
1313 // Possibly configure any armor writer above us.
1314 if self.signers.iter().all(|(kp, _, _)| kp.public().version() > 4) {
1315 writer::Armorer::set_profile(&mut self, Profile::RFC9580);
1316 }
1317
1318 for (keypair, signer_hash, signer_salt) in self.signers.iter_mut() {
1319 let algo = if let Some(a) = self.hash_algo {
1320 a
1321 } else {
1322 self.acceptable_hash_algos.get(0)
1323 .expect("we make sure the set is never empty")
1324 .clone()
1325 };
1326 *signer_hash = algo;
1327 let mut hash = algo.context()?
1328 .for_signature(keypair.public().version());
1329
1330 match keypair.public().version() {
1331 4 => {
1332 self.hashes.push(
1333 if self.template.typ() == SignatureType::Text
1334 || self.mode == SignatureMode::Cleartext
1335 {
1336 HashingMode::Text(vec![], hash)
1337 } else {
1338 HashingMode::Binary(vec![], hash)
1339 });
1340 },
1341 6 => {
1342 // Version 6 signatures are salted, and we
1343 // need to include it in the OPS packet.
1344 // Generate and remember the salt here.
1345 let mut salt = vec![0; algo.salt_size()?];
1346 crate::crypto::random(&mut salt)?;
1347
1348 // Add the salted context.
1349 hash.update(&salt);
1350 self.hashes.push(
1351 if self.template.typ() == SignatureType::Text
1352 || self.mode == SignatureMode::Cleartext
1353 {
1354 HashingMode::Text(salt.clone(), hash)
1355 } else {
1356 HashingMode::Binary(salt.clone(), hash)
1357 });
1358
1359 // And remember which signer used which salt.
1360 *signer_salt = salt;
1361 },
1362 v => return Err(Error::InvalidOperation(
1363 format!("Unsupported Key version {}", v)).into()),
1364 }
1365 }
1366
1367 match self.mode {
1368 SignatureMode::Inline => {
1369 // For every key we collected, build and emit a one pass
1370 // signature packet.
1371 let signers_count = self.signers.len();
1372 for (i, (keypair, hash_algo, salt)) in
1373 self.signers.iter().enumerate()
1374 {
1375 let last = i == signers_count - 1;
1376 let key = keypair.public();
1377
1378 match key.version() {
1379 4 => {
1380 let mut ops = OnePassSig3::new(self.template.typ());
1381 ops.set_pk_algo(key.pk_algo());
1382 ops.set_hash_algo(*hash_algo);
1383 ops.set_issuer(key.keyid());
1384 ops.set_last(last);
1385 Packet::from(ops)
1386 .serialize(self.inner.as_mut().unwrap())?;
1387 },
1388 6 => {
1389 // Version 6 signatures are salted, and we
1390 // need to include it in the OPS packet.
1391 let mut ops = OnePassSig6::new(
1392 self.template.typ(), key.fingerprint());
1393 ops.set_pk_algo(key.pk_algo());
1394 ops.set_hash_algo(*hash_algo);
1395 ops.set_salt(salt.clone());
1396 ops.set_last(last);
1397 Packet::from(ops)
1398 .serialize(self.inner.as_mut().unwrap())?;
1399 },
1400 v => return Err(Error::InvalidOperation(
1401 format!("Unsupported Key version {}", v)).into()),
1402 }
1403 }
1404 },
1405 SignatureMode::Detached => (), // Do nothing.
1406 SignatureMode::Cleartext => {
1407 // Cleartext signatures are always text signatures.
1408 self.template = self.template.set_type(SignatureType::Text);
1409
1410 // Write the header.
1411 let mut sink = self.inner.take().unwrap();
1412 writeln!(sink, "-----BEGIN PGP SIGNED MESSAGE-----")?;
1413 let mut hashes = self.signers.iter().filter_map(
1414 |(keypair, algo, _)| if keypair.public().version() == 4 {
1415 Some(algo)
1416 } else {
1417 None
1418 })
1419 .collect::<Vec<_>>();
1420 hashes.sort();
1421 hashes.dedup();
1422 for hash in hashes {
1423 writeln!(sink, "Hash: {}", hash.text_name()?)?;
1424 }
1425 writeln!(sink)?;
1426
1427 // We now install two filters. See the comment on
1428 // Signer::cleartext.
1429
1430 // Install the filter dash-escaping the text below us.
1431 self.inner =
1432 Some(writer::BoxStack::from(
1433 DashEscapeFilter::new(Message::from(sink),
1434 Default::default())));
1435
1436 // Install the filter trimming the trailing whitespace
1437 // above us.
1438 return Ok(TrailingWSFilter::new(Message::from(Box::new(self)),
1439 Default::default()));
1440 },
1441 }
1442
1443 Ok(Message::from(Box::new(self)))
1444 }
1445
1446 fn emit_signatures(&mut self) -> Result<()> {
1447 if self.mode == SignatureMode::Cleartext {
1448 // Pop off the DashEscapeFilter.
1449 let mut inner =
1450 self.inner.take().expect("It's the DashEscapeFilter")
1451 .into_inner()?.expect("It's the DashEscapeFilter");
1452
1453 // Add the separating newline that is not part of the message.
1454 writeln!(inner)?;
1455
1456 // And install an armorer.
1457 self.inner =
1458 Some(writer::BoxStack::from(
1459 writer::Armorer::new(Message::from(inner),
1460 Default::default(),
1461 armor::Kind::Signature,
1462 Option::<(&str, &str)>::None)?));
1463 }
1464
1465 if let Some(ref mut sink) = self.inner {
1466 // Emit the signatures in reverse, so that the
1467 // one-pass-signature and signature packets "bracket" the
1468 // message.
1469 for (signer, algo, signer_salt) in self.signers.iter_mut().rev() {
1470 let (mut sig, hash) = match signer.public().version() {
1471 4 => {
1472 // V4 signature.
1473
1474 let hash = self.hashes.iter()
1475 .find_map(|hash| {
1476 if hash.salt().is_empty()
1477 && hash.as_ref().algo() == *algo
1478 {
1479 Some(hash.clone())
1480 } else {
1481 None
1482 }
1483 })
1484 .expect("we put it in there");
1485
1486 // Make and hash a signature packet.
1487 let sig = self.template.clone();
1488
1489 (sig, hash)
1490 },
1491 6 => {
1492 // V6 signature.
1493 let hash = self.hashes.iter()
1494 .find_map(|hash| if signer_salt == hash.salt() {
1495 Some(hash.clone())
1496 } else {
1497 None
1498 })
1499 .expect("we put it in there");
1500
1501 // Make and hash a signature packet.
1502 let sig = self.template.clone()
1503 .set_prefix_salt(signer_salt.clone()).0;
1504
1505 (sig, hash)
1506 },
1507 v => return Err(Error::InvalidOperation(
1508 format!("Unsupported Key version {}", v)).into()),
1509 };
1510
1511 sig = sig.set_signature_creation_time(
1512 self.creation_time
1513 .unwrap_or_else(crate::now))?;
1514
1515 if ! self.intended_recipients.is_empty() {
1516 sig = sig.set_intended_recipients(
1517 self.intended_recipients.clone())?;
1518 }
1519
1520 // Compute the signature.
1521 let sig = sig.sign_hash(signer.as_mut(),
1522 hash.into_inner())?;
1523
1524 // And emit the packet.
1525 Packet::Signature(sig).serialize(sink)?;
1526 }
1527 }
1528 Ok(())
1529 }
1530}
1531
1532impl<'a> fmt::Debug for Signer<'a> {
1533 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1534 f.debug_struct("Signer")
1535 .field("inner", &self.inner)
1536 .field("cookie", &self.cookie)
1537 .field("mode", &self.mode)
1538 .finish()
1539 }
1540}
1541
1542impl<'a> Write for Signer<'a> {
1543 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1544 // Shortcut empty writes. This is important for the code
1545 // below that delays hashing newlines when creating cleartext
1546 // signed messages.
1547 if buf.is_empty() {
1548 return Ok(0);
1549 }
1550
1551 use SignatureMode::*;
1552 let written = match (self.inner.as_mut(), self.mode) {
1553 // If we are creating a normal signature, pass data
1554 // through.
1555 (Some(ref mut w), Inline) => w.write(buf),
1556 // If we are creating a detached signature, just hash all
1557 // bytes.
1558 (Some(_), Detached) => Ok(buf.len()),
1559 // If we are creating a cleartext signed message, just
1560 // write through (the DashEscapeFilter takes care of the
1561 // encoding), and hash all bytes as is.
1562 (Some(ref mut w), Cleartext) => w.write(buf),
1563 // When we are popped off the stack, we have no inner
1564 // writer. Just hash all bytes.
1565 (None, _) => Ok(buf.len()),
1566 };
1567
1568 if let Ok(amount) = written {
1569 let data = &buf[..amount];
1570
1571 self.hashes.iter_mut().for_each(
1572 |hash| hash.update(data));
1573 self.position += amount as u64;
1574 }
1575
1576 written
1577 }
1578
1579 fn flush(&mut self) -> io::Result<()> {
1580 match self.inner.as_mut() {
1581 Some(ref mut w) => w.flush(),
1582 // When we are popped off the stack, we have no inner
1583 // writer. Just do nothing.
1584 None => Ok(()),
1585 }
1586 }
1587}
1588
1589impl<'a> writer::Stackable<'a, Cookie> for Signer<'a> {
1590 fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> {
1591 Ok(self.inner.take())
1592 }
1593 fn mount(&mut self, new: writer::BoxStack<'a, Cookie>) {
1594 self.inner = Some(new);
1595 }
1596 fn inner_mut(&mut self) -> Option<&mut (dyn writer::Stackable<'a, Cookie> + Send + Sync)> {
1597 if let Some(ref mut i) = self.inner {
1598 Some(i)
1599 } else {
1600 None
1601 }
1602 }
1603 fn inner_ref(&self) -> Option<&(dyn writer::Stackable<'a, Cookie> + Send + Sync)> {
1604 self.inner.as_ref().map(|r| r.as_ref())
1605 }
1606 fn into_inner(mut self: Box<Self>)
1607 -> Result<Option<writer::BoxStack<'a, Cookie>>> {
1608 self.emit_signatures()?;
1609 Ok(self.inner.take())
1610 }
1611 fn cookie_set(&mut self, cookie: Cookie) -> Cookie {
1612 ::std::mem::replace(&mut self.cookie, cookie)
1613 }
1614 fn cookie_ref(&self) -> &Cookie {
1615 &self.cookie
1616 }
1617 fn cookie_mut(&mut self) -> &mut Cookie {
1618 &mut self.cookie
1619 }
1620 fn position(&self) -> u64 {
1621 self.position
1622 }
1623}
1624
1625
1626/// Writes a literal data packet.
1627///
1628/// Literal data, i.e. the payload or plaintext, must be wrapped in a
1629/// literal data packet to be transported over OpenPGP (see [Section
1630/// 5.9 of RFC 9580]). The body will be written using partial length
1631/// encoding, or, if the body is short, using full length encoding.
1632///
1633/// [Section 5.9 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.9
1634///
1635/// # Note on metadata
1636///
1637/// A literal data packet can communicate some metadata: a hint as to
1638/// what kind of data is transported, the original file name, and a
1639/// timestamp. Note that this metadata will not be authenticated by
1640/// signatures (but will be authenticated by a SEIP/MDC container),
1641/// and are therefore unreliable and should not be trusted.
1642///
1643/// Therefore, it is good practice not to set this metadata when
1644/// creating a literal data packet, and not to interpret it when
1645/// consuming one.
1646pub struct LiteralWriter<'a> {
1647 template: Literal,
1648 inner: writer::BoxStack<'a, Cookie>,
1649 signature_writer: Option<writer::BoxStack<'a, Cookie>>,
1650}
1651assert_send_and_sync!(LiteralWriter<'_>);
1652
1653impl<'a> LiteralWriter<'a> {
1654 /// Creates a new literal writer.
1655 ///
1656 /// # Examples
1657 ///
1658 /// ```
1659 /// # fn main() -> sequoia_openpgp::Result<()> {
1660 /// use std::io::Write;
1661 /// use sequoia_openpgp as openpgp;
1662 /// use openpgp::serialize::stream::{Message, LiteralWriter};
1663 ///
1664 /// let mut sink = vec![];
1665 /// {
1666 /// let message = Message::new(&mut sink);
1667 /// let mut message = LiteralWriter::new(message)
1668 /// // Customize the `LiteralWriter` here.
1669 /// .build()?;
1670 /// message.write_all(b"Hello world.")?;
1671 /// message.finalize()?;
1672 /// }
1673 /// assert_eq!(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.",
1674 /// sink.as_slice());
1675 /// # Ok(()) }
1676 /// ```
1677 pub fn new(inner: Message<'a>) -> Self {
1678 LiteralWriter {
1679 template: Literal::new(DataFormat::default()),
1680 inner: writer::BoxStack::from(inner),
1681 signature_writer: None,
1682 }
1683 }
1684
1685 /// Sets the data format.
1686 ///
1687 /// # Examples
1688 ///
1689 /// ```
1690 /// # fn main() -> sequoia_openpgp::Result<()> {
1691 /// use std::io::Write;
1692 /// use sequoia_openpgp as openpgp;
1693 /// use openpgp::types::DataFormat;
1694 /// use openpgp::serialize::stream::{Message, LiteralWriter};
1695 ///
1696 /// let mut sink = vec![];
1697 /// {
1698 /// let message = Message::new(&mut sink);
1699 /// let mut message = LiteralWriter::new(message)
1700 /// .format(DataFormat::Unicode)
1701 /// .build()?;
1702 /// message.write_all(b"Hello world.")?;
1703 /// message.finalize()?;
1704 /// }
1705 /// assert_eq!(b"\xcb\x12u\x00\x00\x00\x00\x00Hello world.",
1706 /// sink.as_slice());
1707 /// # Ok(()) }
1708 /// ```
1709 pub fn format(mut self, format: DataFormat) -> Self {
1710 self.template.set_format(format);
1711 self
1712 }
1713
1714 /// Sets the filename.
1715 ///
1716 /// The standard does not specify the encoding. Filenames must
1717 /// not be longer than 255 bytes. Returns an error if the given
1718 /// name is longer than that.
1719 ///
1720 /// # Examples
1721 ///
1722 /// ```
1723 /// # fn main() -> sequoia_openpgp::Result<()> {
1724 /// use std::io::Write;
1725 /// use sequoia_openpgp as openpgp;
1726 /// use openpgp::serialize::stream::{Message, LiteralWriter};
1727 ///
1728 /// let mut sink = vec![];
1729 /// {
1730 /// let message = Message::new(&mut sink);
1731 /// let mut message = LiteralWriter::new(message)
1732 /// .filename("foobar")?
1733 /// .build()?;
1734 /// message.write_all(b"Hello world.")?;
1735 /// message.finalize()?;
1736 /// }
1737 /// assert_eq!(b"\xcb\x18b\x06foobar\x00\x00\x00\x00Hello world.",
1738 /// sink.as_slice());
1739 /// # Ok(()) }
1740 /// ```
1741 pub fn filename<B: AsRef<[u8]>>(mut self, filename: B) -> Result<Self> {
1742 self.template.set_filename(filename.as_ref())?;
1743 Ok(self)
1744 }
1745
1746 /// Sets the date.
1747 ///
1748 /// This date may be the modification date or the creation date.
1749 /// Returns an error if the given date is not representable by
1750 /// OpenPGP.
1751 ///
1752 /// # Examples
1753 ///
1754 /// ```
1755 /// # fn main() -> sequoia_openpgp::Result<()> {
1756 /// use std::io::Write;
1757 /// use sequoia_openpgp as openpgp;
1758 /// use openpgp::types::Timestamp;
1759 /// use openpgp::serialize::stream::{Message, LiteralWriter};
1760 ///
1761 /// let mut sink = vec![];
1762 /// {
1763 /// let message = Message::new(&mut sink);
1764 /// let mut message = LiteralWriter::new(message)
1765 /// .date(Timestamp::from(1585925313))?
1766 /// .build()?;
1767 /// message.write_all(b"Hello world.")?;
1768 /// message.finalize()?;
1769 /// }
1770 /// assert_eq!(b"\xcb\x12b\x00\x5e\x87\x4c\xc1Hello world.",
1771 /// sink.as_slice());
1772 /// # Ok(()) }
1773 /// ```
1774 pub fn date<T: Into<SystemTime>>(mut self, timestamp: T) -> Result<Self>
1775 {
1776 self.template.set_date(Some(timestamp.into()))?;
1777 Ok(self)
1778 }
1779
1780 /// Builds the literal writer, returning the writer stack.
1781 ///
1782 /// The next step is to write the payload to the writer stack.
1783 ///
1784 /// # Examples
1785 ///
1786 /// ```
1787 /// # fn main() -> sequoia_openpgp::Result<()> {
1788 /// use std::io::Write;
1789 /// use sequoia_openpgp as openpgp;
1790 /// use openpgp::serialize::stream::{Message, LiteralWriter};
1791 ///
1792 /// let mut sink = vec![];
1793 /// {
1794 /// let message = Message::new(&mut sink);
1795 /// let mut message = LiteralWriter::new(message)
1796 /// // Customize the `LiteralWriter` here.
1797 /// .build()?;
1798 /// message.write_all(b"Hello world.")?;
1799 /// message.finalize()?;
1800 /// }
1801 /// assert_eq!(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.",
1802 /// sink.as_slice());
1803 /// # Ok(()) }
1804 /// ```
1805 pub fn build(mut self) -> Result<Message<'a>> {
1806 let level = self.inner.cookie_ref().level + 1;
1807
1808 // For historical reasons, signatures over literal data
1809 // packets only include the body without metadata or framing.
1810 // Therefore, we check whether the writer is a
1811 // Signer, and if so, we pop it off the stack and
1812 // store it in 'self.signature_writer'.
1813 let signer_above =
1814 matches!(self.inner.cookie_ref(), &Cookie {
1815 private: Private::Signer{..},
1816 ..
1817 });
1818
1819 if signer_above {
1820 let stack = self.inner.pop()?;
1821 // We know a signer has an inner stackable.
1822 let stack = stack.unwrap();
1823 self.signature_writer = Some(self.inner);
1824 self.inner = stack;
1825 }
1826
1827 // Not hashed by the signature_writer (see above).
1828 CTB::new(Tag::Literal).serialize(&mut self.inner)?;
1829
1830 // Neither is any framing added by the PartialBodyFilter.
1831 self.inner
1832 = PartialBodyFilter::new(Message::from(self.inner),
1833 Cookie::new(level)).into();
1834
1835 // Nor the headers.
1836 self.template.serialize_headers(&mut self.inner, false)?;
1837
1838 Ok(Message::from(Box::new(self)))
1839 }
1840}
1841
1842impl<'a> fmt::Debug for LiteralWriter<'a> {
1843 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1844 f.debug_struct("LiteralWriter")
1845 .field("inner", &self.inner)
1846 .finish()
1847 }
1848}
1849
1850impl<'a> Write for LiteralWriter<'a> {
1851 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1852 let written = self.inner.write(buf);
1853
1854 // Any successful written bytes needs to be hashed too.
1855 if let (&Ok(ref amount), &mut Some(ref mut sig))
1856 = (&written, &mut self.signature_writer) {
1857 sig.write_all(&buf[..*amount])?;
1858 };
1859 written
1860 }
1861
1862 fn flush(&mut self) -> io::Result<()> {
1863 self.inner.flush()
1864 }
1865}
1866
1867impl<'a> writer::Stackable<'a, Cookie> for LiteralWriter<'a> {
1868 fn into_inner(mut self: Box<Self>)
1869 -> Result<Option<writer::BoxStack<'a, Cookie>>> {
1870 let signer = self.signature_writer.take();
1871 let stack = self.inner
1872 .into_inner()?.unwrap(); // Peel off the PartialBodyFilter.
1873
1874 if let Some(mut signer) = signer {
1875 // We stashed away a Signer. Reattach it to the
1876 // stack and return it.
1877 signer.mount(stack);
1878 Ok(Some(signer))
1879 } else {
1880 Ok(Some(stack))
1881 }
1882 }
1883
1884 fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> {
1885 unreachable!("Only implemented by Signer")
1886 }
1887 /// Sets the inner stackable.
1888 fn mount(&mut self, _new: writer::BoxStack<'a, Cookie>) {
1889 unreachable!("Only implemented by Signer")
1890 }
1891 fn inner_ref(&self) -> Option<&(dyn writer::Stackable<'a, Cookie> + Send + Sync)> {
1892 Some(self.inner.as_ref())
1893 }
1894 fn inner_mut(&mut self) -> Option<&mut (dyn writer::Stackable<'a, Cookie> + Send + Sync)> {
1895 Some(self.inner.as_mut())
1896 }
1897 fn cookie_set(&mut self, cookie: Cookie) -> Cookie {
1898 self.inner.cookie_set(cookie)
1899 }
1900 fn cookie_ref(&self) -> &Cookie {
1901 self.inner.cookie_ref()
1902 }
1903 fn cookie_mut(&mut self) -> &mut Cookie {
1904 self.inner.cookie_mut()
1905 }
1906 fn position(&self) -> u64 {
1907 self.inner.position()
1908 }
1909}
1910
1911/// Compresses a message.
1912///
1913/// Writes a compressed data packet containing all packets written to
1914/// this writer.
1915pub struct Compressor<'a> {
1916 algo: CompressionAlgorithm,
1917 level: CompressionLevel,
1918 inner: writer::BoxStack<'a, Cookie>,
1919}
1920assert_send_and_sync!(Compressor<'_>);
1921
1922impl<'a> Compressor<'a> {
1923 /// Creates a new compressor using the default algorithm and
1924 /// compression level.
1925 ///
1926 /// To change the compression algorithm use [`Compressor::algo`].
1927 /// Use [`Compressor::level`] to change the compression level.
1928 ///
1929 /// [`Compressor::algo`]: Compressor::algo()
1930 /// [`Compressor::level`]: Compressor::level()
1931 ///
1932 /// # Examples
1933 ///
1934 /// ```
1935 /// # fn main() -> sequoia_openpgp::Result<()> {
1936 /// use std::io::Write;
1937 /// use sequoia_openpgp as openpgp;
1938 /// use openpgp::serialize::stream::{Message, Compressor, LiteralWriter};
1939 /// use openpgp::types::CompressionAlgorithm;
1940 ///
1941 /// # let mut sink = vec![];
1942 /// let message = Message::new(&mut sink);
1943 /// let message = Compressor::new(message)
1944 /// // Customize the `Compressor` here.
1945 /// # .algo(CompressionAlgorithm::Uncompressed)
1946 /// .build()?;
1947 /// let mut message = LiteralWriter::new(message).build()?;
1948 /// message.write_all(b"Hello world.")?;
1949 /// message.finalize()?;
1950 /// # Ok(()) }
1951 /// ```
1952 pub fn new(inner: Message<'a>) -> Self {
1953 Self {
1954 algo: Default::default(),
1955 level: Default::default(),
1956 inner: inner.into(),
1957 }
1958 }
1959
1960 /// Sets the compression algorithm.
1961 ///
1962 /// # Examples
1963 ///
1964 /// ```
1965 /// # fn main() -> sequoia_openpgp::Result<()> {
1966 /// use std::io::Write;
1967 /// use sequoia_openpgp as openpgp;
1968 /// use openpgp::serialize::stream::{Message, Compressor, LiteralWriter};
1969 /// use openpgp::types::CompressionAlgorithm;
1970 ///
1971 /// let mut sink = vec![];
1972 /// {
1973 /// let message = Message::new(&mut sink);
1974 /// let message = Compressor::new(message)
1975 /// .algo(CompressionAlgorithm::Uncompressed)
1976 /// .build()?;
1977 /// let mut message = LiteralWriter::new(message).build()?;
1978 /// message.write_all(b"Hello world.")?;
1979 /// message.finalize()?;
1980 /// }
1981 /// assert_eq!(b"\xc8\x15\x00\xcb\x12b\x00\x00\x00\x00\x00Hello world.",
1982 /// sink.as_slice());
1983 /// # Ok(()) }
1984 /// ```
1985 pub fn algo(mut self, algo: CompressionAlgorithm) -> Self {
1986 self.algo = algo;
1987 self
1988 }
1989
1990 /// Sets the compression level.
1991 ///
1992 /// # Examples
1993 ///
1994 /// ```
1995 /// # fn main() -> sequoia_openpgp::Result<()> {
1996 /// use std::io::Write;
1997 /// use sequoia_openpgp as openpgp;
1998 /// use openpgp::serialize::stream::{Message, Compressor, LiteralWriter};
1999 /// use openpgp::types::{CompressionAlgorithm, CompressionLevel};
2000 ///
2001 /// # let mut sink = vec![];
2002 /// let message = Message::new(&mut sink);
2003 /// let message = Compressor::new(message)
2004 /// # .algo(CompressionAlgorithm::Uncompressed)
2005 /// .level(CompressionLevel::fastest())
2006 /// .build()?;
2007 /// let mut message = LiteralWriter::new(message).build()?;
2008 /// message.write_all(b"Hello world.")?;
2009 /// message.finalize()?;
2010 /// # Ok(()) }
2011 /// ```
2012 pub fn level(mut self, level: CompressionLevel) -> Self {
2013 self.level = level;
2014 self
2015 }
2016
2017 /// Builds the compressor, returning the writer stack.
2018 ///
2019 /// The most useful filter to push to the writer stack next is the
2020 /// [`Signer`] or the [`LiteralWriter`]. Finally, literal data
2021 /// *must* be wrapped using the [`LiteralWriter`].
2022 ///
2023 ///
2024 /// # Examples
2025 ///
2026 /// ```
2027 /// # fn main() -> sequoia_openpgp::Result<()> {
2028 /// use std::io::Write;
2029 /// use sequoia_openpgp as openpgp;
2030 /// use openpgp::serialize::stream::{Message, Compressor, LiteralWriter};
2031 /// use openpgp::types::CompressionAlgorithm;
2032 ///
2033 /// # let mut sink = vec![];
2034 /// let message = Message::new(&mut sink);
2035 /// let message = Compressor::new(message)
2036 /// // Customize the `Compressor` here.
2037 /// # .algo(CompressionAlgorithm::Uncompressed)
2038 /// .build()?;
2039 /// let mut message = LiteralWriter::new(message).build()?;
2040 /// message.write_all(b"Hello world.")?;
2041 /// message.finalize()?;
2042 /// # Ok(()) }
2043 /// ```
2044 pub fn build(mut self) -> Result<Message<'a>> {
2045 let level = self.inner.cookie_ref().level + 1;
2046
2047 // Packet header.
2048 CTB::new(Tag::CompressedData).serialize(&mut self.inner)?;
2049 let inner: Message<'a>
2050 = PartialBodyFilter::new(Message::from(self.inner),
2051 Cookie::new(level));
2052
2053 Self::new_naked(inner, self.algo, self.level, level)
2054 }
2055
2056
2057 /// Creates a new compressor using the given algorithm.
2058 pub(crate) // For CompressedData::serialize.
2059 fn new_naked(mut inner: Message<'a>,
2060 algo: CompressionAlgorithm,
2061 compression_level: CompressionLevel,
2062 level: usize)
2063 -> Result<Message<'a>>
2064 {
2065 // Compressed data header.
2066 inner.as_mut().write_u8(algo.into())?;
2067
2068 // Create an appropriate filter.
2069 let inner: Message<'a> = match algo {
2070 CompressionAlgorithm::Uncompressed => {
2071 // Avoid warning about unused value if compiled
2072 // without any compression support.
2073 let _ = compression_level;
2074 writer::Identity::new(inner, Cookie::new(level))
2075 },
2076 #[cfg(feature = "compression-deflate")]
2077 CompressionAlgorithm::Zip =>
2078 writer::ZIP::new(inner, Cookie::new(level), compression_level),
2079 #[cfg(feature = "compression-deflate")]
2080 CompressionAlgorithm::Zlib =>
2081 writer::ZLIB::new(inner, Cookie::new(level), compression_level),
2082 #[cfg(feature = "compression-bzip2")]
2083 CompressionAlgorithm::BZip2 =>
2084 writer::BZ::new(inner, Cookie::new(level), compression_level),
2085 a =>
2086 return Err(Error::UnsupportedCompressionAlgorithm(a).into()),
2087 };
2088
2089 Ok(Message::from(Box::new(Self {
2090 algo,
2091 level: compression_level,
2092 inner: inner.into(),
2093 })))
2094 }
2095}
2096
2097impl<'a> fmt::Debug for Compressor<'a> {
2098 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2099 f.debug_struct("Compressor")
2100 .field("inner", &self.inner)
2101 .finish()
2102 }
2103}
2104
2105impl<'a> io::Write for Compressor<'a> {
2106 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
2107 self.inner.write(buf)
2108 }
2109
2110 fn flush(&mut self) -> io::Result<()> {
2111 self.inner.flush()
2112 }
2113}
2114
2115impl<'a> writer::Stackable<'a, Cookie> for Compressor<'a> {
2116 fn into_inner(self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> {
2117 Box::new(self.inner).into_inner()?.unwrap().into_inner()
2118 }
2119 fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> {
2120 unreachable!("Only implemented by Signer")
2121 }
2122 /// Sets the inner stackable.
2123 fn mount(&mut self, _new: writer::BoxStack<'a, Cookie>) {
2124 unreachable!("Only implemented by Signer")
2125 }
2126 fn inner_ref(&self) -> Option<&(dyn writer::Stackable<'a, Cookie> + Send + Sync)> {
2127 Some(self.inner.as_ref())
2128 }
2129 fn inner_mut(&mut self) -> Option<&mut (dyn writer::Stackable<'a, Cookie> + Send + Sync)> {
2130 Some(self.inner.as_mut())
2131 }
2132 fn cookie_set(&mut self, cookie: Cookie) -> Cookie {
2133 self.inner.cookie_set(cookie)
2134 }
2135 fn cookie_ref(&self) -> &Cookie {
2136 self.inner.cookie_ref()
2137 }
2138 fn cookie_mut(&mut self) -> &mut Cookie {
2139 self.inner.cookie_mut()
2140 }
2141 fn position(&self) -> u64 {
2142 self.inner.position()
2143 }
2144}
2145
2146/// A recipient of an encrypted message.
2147///
2148/// OpenPGP messages are encrypted with the subkeys of recipients,
2149/// identified by the keyid of said subkeys in the [`recipient`] field
2150/// of [`PKESK`] packets (see [Section 5.1 of RFC 9580]). The keyid
2151/// may be a wildcard (as returned by [`KeyID::wildcard()`]) to
2152/// obscure the identity of the recipient.
2153///
2154/// [`recipient`]: crate::packet::PKESK#method.recipient
2155/// [`PKESK`]: crate::packet::PKESK
2156/// [Section 5.1 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.1
2157/// [`KeyID::wildcard()`]: crate::KeyID::wildcard()
2158///
2159/// Note that several subkeys in a certificate may be suitable
2160/// encryption subkeys. OpenPGP does not specify what should happen
2161/// in this case. Some implementations arbitrarily pick one
2162/// encryption subkey, while others use all of them. This crate does
2163/// not dictate a policy, but allows for arbitrary policies. We do,
2164/// however, suggest to encrypt to all suitable subkeys.
2165#[derive(Debug)]
2166pub struct Recipient<'a> {
2167 handle: Option<KeyHandle>,
2168 features: Features,
2169 key: &'a Key<key::PublicParts, key::UnspecifiedRole>,
2170}
2171assert_send_and_sync!(Recipient<'_>);
2172
2173impl<'a, P> From<ValidSubordinateKeyAmalgamation<'a, P>>
2174 for Recipient<'a>
2175where
2176 P: key::KeyParts,
2177{
2178 fn from(ka: ValidSubordinateKeyAmalgamation<'a, P>) -> Self {
2179 let features = ka.valid_cert().features()
2180 .unwrap_or_else(Features::empty);
2181 let handle: KeyHandle = if features.supports_seipdv2() {
2182 ka.key().fingerprint().into()
2183 } else {
2184 ka.key().keyid().into()
2185 };
2186
2187 use crate::cert::Preferences;
2188 use crate::cert::amalgamation::ValidAmalgamation;
2189 Self::new(features, handle,
2190 ka.key().parts_as_public().role_as_unspecified())
2191 }
2192}
2193
2194impl<'a, P> From<ValidErasedKeyAmalgamation<'a, P>>
2195 for Recipient<'a>
2196where
2197 P: key::KeyParts,
2198{
2199 fn from(ka: ValidErasedKeyAmalgamation<'a, P>) -> Self {
2200 let features = ka.valid_cert().features()
2201 .unwrap_or_else(Features::empty);
2202 let handle: KeyHandle = if features.supports_seipdv2() {
2203 ka.key().fingerprint().into()
2204 } else {
2205 ka.key().keyid().into()
2206 };
2207
2208 use crate::cert::Preferences;
2209 use crate::cert::amalgamation::ValidAmalgamation;
2210 Self::new(features, handle,
2211 ka.key().parts_as_public().role_as_unspecified())
2212 }
2213}
2214
2215impl<'a> Recipient<'a> {
2216 /// Creates a new recipient with an explicit recipient keyid.
2217 ///
2218 /// Note: If you don't want to change the recipient keyid,
2219 /// `Recipient`s can be created from [`Key`] and
2220 /// [`ValidKeyAmalgamation`] using [`From`].
2221 ///
2222 /// [`Key`]: crate::packet::Key
2223 /// [`ValidKeyAmalgamation`]: crate::cert::amalgamation::key::ValidKeyAmalgamation
2224 /// [`From`]: std::convert::From
2225 ///
2226 /// # Examples
2227 ///
2228 /// ```
2229 /// # fn main() -> sequoia_openpgp::Result<()> {
2230 /// use std::io::Write;
2231 /// use sequoia_openpgp as openpgp;
2232 /// use openpgp::cert::prelude::*;
2233 /// use openpgp::serialize::stream::{
2234 /// Recipient, Message, Encryptor,
2235 /// };
2236 /// use openpgp::policy::StandardPolicy;
2237 /// # use openpgp::parse::Parse;
2238 ///
2239 /// let p = &StandardPolicy::new();
2240 ///
2241 /// let cert = Cert::from_bytes(
2242 /// # // We do some acrobatics here to abbreviate the Cert.
2243 /// "-----BEGIN PGP PUBLIC KEY BLOCK-----
2244 ///
2245 /// xjMEWlNvABYJKwYBBAHaRw8BAQdA+EC2pvebpEbzPA9YplVgVXzkIG5eK+7wEAez
2246 /// # lcBgLJrNMVRlc3R5IE1jVGVzdGZhY2UgKG15IG5ldyBrZXkpIDx0ZXN0eUBleGFt
2247 /// # cGxlLm9yZz7CkAQTFggAOBYhBDnRAKtn1b2MBAECBfs3UfFYfa7xBQJaU28AAhsD
2248 /// # BQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEPs3UfFYfa7xJHQBAO4/GABMWUcJ
2249 /// # 5D/DZ9b+6YiFnysSjCT/gILJgxMgl7uoAPwJherI1pAAh49RnPHBR1IkWDtwzX65
2250 /// # CJG8sDyO2FhzDs44BFpTbwASCisGAQQBl1UBBQEBB0B+A0GRHuBgdDX50T1nePjb
2251 /// # mKQ5PeqXJbWEtVrUtVJaPwMBCAfCeAQYFggAIBYhBDnRAKtn1b2MBAECBfs3UfFY
2252 /// # fa7xBQJaU28AAhsMAAoJEPs3UfFYfa7xzjIBANX2/FgDX3WkmvwpEHg/sn40zACM
2253 /// # W2hrBY5x0sZ8H7JlAP47mCfCuRVBqyaePuzKbxLJeLe2BpDdc0n2izMVj8t9Cg==
2254 /// # =QetZ
2255 /// # -----END PGP PUBLIC KEY BLOCK-----"
2256 /// # /*
2257 /// ...
2258 /// -----END PGP PUBLIC KEY BLOCK-----"
2259 /// # */
2260 /// )?;
2261 ///
2262 /// let recipients =
2263 /// cert.keys().with_policy(p, None).supported().alive().revoked(false)
2264 /// // Or `for_storage_encryption()`, for data at rest.
2265 /// .for_transport_encryption()
2266 /// // Make an anonymous recipient.
2267 /// .map(|ka| Recipient::new(ka.valid_cert().features(), None, ka.key()));
2268 ///
2269 /// # let mut sink = vec![];
2270 /// let message = Message::new(&mut sink);
2271 /// let message = Encryptor::for_recipients(message, recipients).build()?;
2272 /// # let _ = message;
2273 /// # Ok(()) }
2274 /// ```
2275 pub fn new<F, H, P, R>(features: F, handle: H, key: &'a Key<P, R>)
2276 -> Recipient<'a>
2277 where
2278 F: Into<Option<Features>>,
2279 H: Into<Option<KeyHandle>>,
2280 P: key::KeyParts,
2281 R: key::KeyRole,
2282 {
2283 Recipient {
2284 features: features.into().unwrap_or_else(Features::sequoia),
2285 handle: handle.into(),
2286 key: key.parts_as_public().role_as_unspecified(),
2287 }
2288 }
2289
2290 /// Gets the recipient keyid.
2291 ///
2292 /// # Examples
2293 ///
2294 /// ```
2295 /// # fn main() -> sequoia_openpgp::Result<()> {
2296 /// use std::io::Write;
2297 /// use sequoia_openpgp as openpgp;
2298 /// use openpgp::cert::prelude::*;
2299 /// use openpgp::serialize::stream::Recipient;
2300 /// use openpgp::policy::StandardPolicy;
2301 /// # use openpgp::parse::Parse;
2302 ///
2303 /// let p = &StandardPolicy::new();
2304 ///
2305 /// let cert = Cert::from_bytes(
2306 /// # // We do some acrobatics here to abbreviate the Cert.
2307 /// "-----BEGIN PGP PUBLIC KEY BLOCK-----
2308 ///
2309 /// xjMEWlNvABYJKwYBBAHaRw8BAQdA+EC2pvebpEbzPA9YplVgVXzkIG5eK+7wEAez
2310 /// # lcBgLJrNMVRlc3R5IE1jVGVzdGZhY2UgKG15IG5ldyBrZXkpIDx0ZXN0eUBleGFt
2311 /// # cGxlLm9yZz7CkAQTFggAOBYhBDnRAKtn1b2MBAECBfs3UfFYfa7xBQJaU28AAhsD
2312 /// # BQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEPs3UfFYfa7xJHQBAO4/GABMWUcJ
2313 /// # 5D/DZ9b+6YiFnysSjCT/gILJgxMgl7uoAPwJherI1pAAh49RnPHBR1IkWDtwzX65
2314 /// # CJG8sDyO2FhzDs44BFpTbwASCisGAQQBl1UBBQEBB0B+A0GRHuBgdDX50T1nePjb
2315 /// # mKQ5PeqXJbWEtVrUtVJaPwMBCAfCeAQYFggAIBYhBDnRAKtn1b2MBAECBfs3UfFY
2316 /// # fa7xBQJaU28AAhsMAAoJEPs3UfFYfa7xzjIBANX2/FgDX3WkmvwpEHg/sn40zACM
2317 /// # W2hrBY5x0sZ8H7JlAP47mCfCuRVBqyaePuzKbxLJeLe2BpDdc0n2izMVj8t9Cg==
2318 /// # =QetZ
2319 /// # -----END PGP PUBLIC KEY BLOCK-----"
2320 /// # /*
2321 /// ...
2322 /// -----END PGP PUBLIC KEY BLOCK-----"
2323 /// # */
2324 /// )?;
2325 ///
2326 /// let recipients =
2327 /// cert.keys().with_policy(p, None).supported().alive().revoked(false)
2328 /// // Or `for_storage_encryption()`, for data at rest.
2329 /// .for_transport_encryption()
2330 /// .map(Into::into)
2331 /// .collect::<Vec<Recipient>>();
2332 ///
2333 /// assert_eq!(recipients[0].key_handle().unwrap(),
2334 /// "8BD8 8E94 C0D2 0333".parse()?);
2335 /// # Ok(()) }
2336 /// ```
2337 pub fn key_handle(&self) -> Option<KeyHandle> {
2338 self.handle.clone()
2339 }
2340
2341 /// Sets the recipient key ID or fingerprint.
2342 ///
2343 /// When setting the recipient for a v6 key, either `None` or a
2344 /// fingerprint must be supplied. Returns
2345 /// [`Error::InvalidOperation`] if a key ID is given instead.
2346 ///
2347 /// # Examples
2348 ///
2349 /// ```
2350 /// # fn main() -> sequoia_openpgp::Result<()> {
2351 /// use std::io::Write;
2352 /// use sequoia_openpgp as openpgp;
2353 /// use openpgp::{KeyHandle, KeyID};
2354 /// use openpgp::cert::prelude::*;
2355 /// use openpgp::serialize::stream::{
2356 /// Recipient, Message, Encryptor,
2357 /// };
2358 /// use openpgp::policy::StandardPolicy;
2359 /// # use openpgp::parse::Parse;
2360 ///
2361 /// let p = &StandardPolicy::new();
2362 ///
2363 /// let cert = Cert::from_bytes(
2364 /// # // We do some acrobatics here to abbreviate the Cert.
2365 /// "-----BEGIN PGP PUBLIC KEY BLOCK-----
2366 ///
2367 /// xjMEWlNvABYJKwYBBAHaRw8BAQdA+EC2pvebpEbzPA9YplVgVXzkIG5eK+7wEAez
2368 /// # lcBgLJrNMVRlc3R5IE1jVGVzdGZhY2UgKG15IG5ldyBrZXkpIDx0ZXN0eUBleGFt
2369 /// # cGxlLm9yZz7CkAQTFggAOBYhBDnRAKtn1b2MBAECBfs3UfFYfa7xBQJaU28AAhsD
2370 /// # BQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEPs3UfFYfa7xJHQBAO4/GABMWUcJ
2371 /// # 5D/DZ9b+6YiFnysSjCT/gILJgxMgl7uoAPwJherI1pAAh49RnPHBR1IkWDtwzX65
2372 /// # CJG8sDyO2FhzDs44BFpTbwASCisGAQQBl1UBBQEBB0B+A0GRHuBgdDX50T1nePjb
2373 /// # mKQ5PeqXJbWEtVrUtVJaPwMBCAfCeAQYFggAIBYhBDnRAKtn1b2MBAECBfs3UfFY
2374 /// # fa7xBQJaU28AAhsMAAoJEPs3UfFYfa7xzjIBANX2/FgDX3WkmvwpEHg/sn40zACM
2375 /// # W2hrBY5x0sZ8H7JlAP47mCfCuRVBqyaePuzKbxLJeLe2BpDdc0n2izMVj8t9Cg==
2376 /// # =QetZ
2377 /// # -----END PGP PUBLIC KEY BLOCK-----"
2378 /// # /*
2379 /// ...
2380 /// -----END PGP PUBLIC KEY BLOCK-----"
2381 /// # */
2382 /// )?;
2383 ///
2384 /// let recipients =
2385 /// cert.keys().with_policy(p, None).supported().alive().revoked(false)
2386 /// // Or `for_storage_encryption()`, for data at rest.
2387 /// .for_transport_encryption()
2388 /// .map(|ka| Recipient::from(ka)
2389 /// // Set the recipient keyid to the wildcard id.
2390 /// .set_key_handle(None)
2391 /// .expect("always safe")
2392 /// // Same, but explicit. Don't do this.
2393 /// .set_key_handle(KeyHandle::KeyID(KeyID::wildcard()))
2394 /// .expect("safe for v4 recipient")
2395 /// );
2396 ///
2397 /// # let mut sink = vec![];
2398 /// let message = Message::new(&mut sink);
2399 /// let message = Encryptor::for_recipients(message, recipients).build()?;
2400 /// # let _ = message;
2401 /// # Ok(()) }
2402 /// ```
2403 pub fn set_key_handle<H>(mut self, handle: H) -> Result<Self>
2404 where
2405 H: Into<Option<KeyHandle>>,
2406 {
2407 let handle = handle.into();
2408 if self.key.version() == 6
2409 && matches!(handle, Some(KeyHandle::KeyID(_)))
2410 {
2411 return Err(Error::InvalidOperation(
2412 "need a fingerprint for v6 recipient key".into()).into());
2413 }
2414
2415 self.handle = handle;
2416 Ok(self)
2417 }
2418}
2419
2420/// Encrypts a message.
2421///
2422/// The stream will be encrypted using a generated session key, which
2423/// will be encrypted using the given passwords, and for all given
2424/// recipients.
2425///
2426/// An [`Recipient`] is an encryption-capable (sub)key. Note that a
2427/// certificate may have more than one encryption-capable subkey, and
2428/// even the primary key may be encryption-capable.
2429///
2430///
2431/// To encrypt for more than one certificate, iterate over the
2432/// certificates and select encryption-capable keys, making sure that
2433/// at least one key is selected from each certificate.
2434///
2435/// # Examples
2436///
2437/// This demonstrates encrypting for multiple certificates.
2438///
2439/// ```
2440/// # fn main() -> sequoia_openpgp::Result<()> {
2441/// # use std::io::Write;
2442/// # use sequoia_openpgp as openpgp;
2443/// # use openpgp::cert::prelude::*;
2444/// # use openpgp::parse::Parse;
2445/// use openpgp::serialize::stream::{
2446/// Message, Encryptor, LiteralWriter,
2447/// };
2448/// use openpgp::policy::StandardPolicy;
2449/// let p = &StandardPolicy::new();
2450///
2451/// # let (cert_0, _) =
2452/// # CertBuilder::general_purpose(Some("Mr. Pink ☮☮☮"))
2453/// # .generate()?;
2454/// # let (cert_1, _) =
2455/// # CertBuilder::general_purpose(Some("Mr. Pink ☮☮☮"))
2456/// # .generate()?;
2457/// let recipient_certs = vec![cert_0, cert_1];
2458/// let mut recipients = Vec::new();
2459/// for cert in recipient_certs.iter() {
2460/// // Make sure we add at least one subkey from every
2461/// // certificate.
2462/// let mut found_one = false;
2463/// for key in cert.keys().with_policy(p, None)
2464/// .supported().alive().revoked(false).for_transport_encryption()
2465/// {
2466/// recipients.push(key);
2467/// found_one = true;
2468/// }
2469///
2470/// if ! found_one {
2471/// return Err(anyhow::anyhow!("No suitable encryption subkey for {}",
2472/// cert));
2473/// }
2474/// }
2475/// # assert_eq!(recipients.len(), 2);
2476///
2477/// # let mut sink = vec![];
2478/// let message = Message::new(&mut sink);
2479/// let message = Encryptor::for_recipients(message, recipients).build()?;
2480/// let mut w = LiteralWriter::new(message).build()?;
2481/// w.write_all(b"Hello world.")?;
2482/// w.finalize()?;
2483/// # Ok(()) }
2484/// ```
2485pub struct Encryptor<'a, 'b>
2486where 'b: 'a
2487{
2488 inner: writer::BoxStack<'a, Cookie>,
2489 session_key: Option<SessionKey>,
2490 recipients: Vec<Recipient<'b>>,
2491 passwords: Vec<Password>,
2492 sym_algo: SymmetricAlgorithm,
2493 aead_algo: Option<AEADAlgorithm>,
2494 /// For the MDC packet.
2495 hash: crypto::hash::Context,
2496 cookie: Cookie,
2497}
2498assert_send_and_sync!(Encryptor<'_, '_>);
2499
2500impl<'a, 'b> Encryptor<'a, 'b> {
2501 /// Creates a new encryptor for the given recipients.
2502 ///
2503 /// To add more recipients, use [`Encryptor::add_recipients`]. To
2504 /// add passwords, use [`Encryptor::add_passwords`]. To change
2505 /// the symmetric encryption algorithm, use
2506 /// [`Encryptor::symmetric_algo`].
2507 ///
2508 /// # Examples
2509 ///
2510 /// ```
2511 /// # fn main() -> sequoia_openpgp::Result<()> {
2512 /// use std::io::Write;
2513 /// use sequoia_openpgp as openpgp;
2514 /// use openpgp::cert::prelude::*;
2515 /// use openpgp::serialize::stream::{
2516 /// Message, Encryptor, LiteralWriter,
2517 /// };
2518 /// use openpgp::policy::StandardPolicy;
2519 /// # use openpgp::parse::Parse;
2520 /// let p = &StandardPolicy::new();
2521 ///
2522 /// let cert = Cert::from_bytes(
2523 /// # // We do some acrobatics here to abbreviate the Cert.
2524 /// "-----BEGIN PGP PUBLIC KEY BLOCK-----
2525 ///
2526 /// xjMEWlNvABYJKwYBBAHaRw8BAQdA+EC2pvebpEbzPA9YplVgVXzkIG5eK+7wEAez
2527 /// # lcBgLJrNMVRlc3R5IE1jVGVzdGZhY2UgKG15IG5ldyBrZXkpIDx0ZXN0eUBleGFt
2528 /// # cGxlLm9yZz7CkAQTFggAOBYhBDnRAKtn1b2MBAECBfs3UfFYfa7xBQJaU28AAhsD
2529 /// # BQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEPs3UfFYfa7xJHQBAO4/GABMWUcJ
2530 /// # 5D/DZ9b+6YiFnysSjCT/gILJgxMgl7uoAPwJherI1pAAh49RnPHBR1IkWDtwzX65
2531 /// # CJG8sDyO2FhzDs44BFpTbwASCisGAQQBl1UBBQEBB0B+A0GRHuBgdDX50T1nePjb
2532 /// # mKQ5PeqXJbWEtVrUtVJaPwMBCAfCeAQYFggAIBYhBDnRAKtn1b2MBAECBfs3UfFY
2533 /// # fa7xBQJaU28AAhsMAAoJEPs3UfFYfa7xzjIBANX2/FgDX3WkmvwpEHg/sn40zACM
2534 /// # W2hrBY5x0sZ8H7JlAP47mCfCuRVBqyaePuzKbxLJeLe2BpDdc0n2izMVj8t9Cg==
2535 /// # =QetZ
2536 /// # -----END PGP PUBLIC KEY BLOCK-----"
2537 /// # /*
2538 /// ...
2539 /// -----END PGP PUBLIC KEY BLOCK-----"
2540 /// # */
2541 /// )?;
2542 ///
2543 /// let recipients =
2544 /// cert.keys().with_policy(p, None).supported().alive().revoked(false)
2545 /// // Or `for_storage_encryption()`, for data at rest.
2546 /// .for_transport_encryption();
2547 ///
2548 /// # let mut sink = vec![];
2549 /// let message = Message::new(&mut sink);
2550 /// let message = Encryptor::for_recipients(message, recipients).build()?;
2551 /// let mut w = LiteralWriter::new(message).build()?;
2552 /// w.write_all(b"Hello world.")?;
2553 /// w.finalize()?;
2554 /// # Ok(()) }
2555 /// ```
2556 pub fn for_recipients<R>(inner: Message<'a>, recipients: R) -> Self
2557 where R: IntoIterator,
2558 R::Item: Into<Recipient<'b>>,
2559 {
2560 Self {
2561 inner: inner.into(),
2562 session_key: None,
2563 recipients: recipients.into_iter().map(|r| r.into()).collect(),
2564 passwords: Vec::new(),
2565 sym_algo: Default::default(),
2566 aead_algo: Default::default(),
2567 hash: HashAlgorithm::SHA1.context().unwrap().for_digest(),
2568 cookie: Default::default(), // Will be fixed in build.
2569 }
2570 }
2571
2572 /// Creates a new encryptor for the given passwords.
2573 ///
2574 /// To add more passwords, use [`Encryptor::add_passwords`]. To
2575 /// add recipients, use [`Encryptor::add_recipients`]. To change
2576 /// the symmetric encryption algorithm, use
2577 /// [`Encryptor::symmetric_algo`].
2578 ///
2579 /// # Examples
2580 ///
2581 /// ```
2582 /// # fn main() -> sequoia_openpgp::Result<()> {
2583 /// use std::io::Write;
2584 /// use sequoia_openpgp as openpgp;
2585 /// use openpgp::serialize::stream::{
2586 /// Message, Encryptor, LiteralWriter,
2587 /// };
2588 ///
2589 /// # let mut sink = vec![];
2590 /// let message = Message::new(&mut sink);
2591 /// let message = Encryptor::with_passwords(
2592 /// message, Some("совершенно секретно")).build()?;
2593 /// let mut w = LiteralWriter::new(message).build()?;
2594 /// w.write_all(b"Hello world.")?;
2595 /// w.finalize()?;
2596 /// # Ok(()) }
2597 /// ```
2598 pub fn with_passwords<P>(inner: Message<'a>, passwords: P) -> Self
2599 where P: IntoIterator,
2600 P::Item: Into<Password>,
2601 {
2602 Self {
2603 inner: inner.into(),
2604 session_key: None,
2605 recipients: Vec::new(),
2606 passwords: passwords.into_iter().map(|p| p.into()).collect(),
2607 sym_algo: Default::default(),
2608 aead_algo: Default::default(),
2609 hash: HashAlgorithm::SHA1.context().unwrap().for_digest(),
2610 cookie: Default::default(), // Will be fixed in build.
2611 }
2612 }
2613
2614 /// Creates a new encryptor for the given algorithm and session
2615 /// key.
2616 ///
2617 /// Usually, the encryptor creates a session key and decrypts it
2618 /// for the given recipients and passwords. Using this function,
2619 /// the session key can be supplied instead. There are two main
2620 /// use cases for this:
2621 ///
2622 /// - Replying to an encrypted message usually requires the
2623 /// encryption (sub)keys for every recipient. If even one key
2624 /// is not available, it is not possible to encrypt the new
2625 /// session key. Rather than falling back to replying
2626 /// unencrypted, one can reuse the original message's session
2627 /// key that was encrypted for every recipient and reuse the
2628 /// original [`PKESK`]s.
2629 ///
2630 /// - Using the encryptor if the session key is transmitted or
2631 /// derived using a scheme not supported by Sequoia.
2632 ///
2633 /// To add more passwords, use [`Encryptor::add_passwords`]. To
2634 /// add recipients, use [`Encryptor::add_recipients`].
2635 ///
2636 /// # Examples
2637 ///
2638 /// This example demonstrates how to fall back to the original
2639 /// message's session key in order to encrypt a reply.
2640 ///
2641 /// ```
2642 /// # fn main() -> sequoia_openpgp::Result<()> {
2643 /// # use std::io::{self, Write};
2644 /// # use sequoia_openpgp as openpgp;
2645 /// # use openpgp::{KeyHandle, KeyID, Fingerprint, Result};
2646 /// # use openpgp::cert::prelude::*;
2647 /// # use openpgp::packet::prelude::*;
2648 /// # use openpgp::crypto::{KeyPair, SessionKey};
2649 /// # use openpgp::types::SymmetricAlgorithm;
2650 /// # use openpgp::parse::{Parse, stream::*};
2651 /// # use openpgp::serialize::{Serialize, stream::*};
2652 /// # use openpgp::policy::{Policy, StandardPolicy};
2653 /// # let p = &StandardPolicy::new();
2654 /// #
2655 /// // Generate two keys.
2656 /// let (alice, _) = CertBuilder::general_purpose(
2657 /// Some("Alice Lovelace <alice@example.org>")).generate()?;
2658 /// let (bob, _) = CertBuilder::general_purpose(
2659 /// Some("Bob Babbage <bob@example.org>")).generate()?;
2660 ///
2661 /// // Encrypt a message for both keys.
2662 /// let recipients = vec![&alice, &bob].into_iter().flat_map(|cert| {
2663 /// cert.keys().with_policy(p, None).supported().alive().revoked(false)
2664 /// .for_transport_encryption()
2665 /// });
2666 ///
2667 /// let mut original = vec![];
2668 /// let message = Message::new(&mut original);
2669 /// let message = Encryptor::for_recipients(message, recipients).build()?;
2670 /// let mut w = LiteralWriter::new(message).build()?;
2671 /// w.write_all(b"Original message")?;
2672 /// w.finalize()?;
2673 ///
2674 /// // Decrypt original message using Alice's key.
2675 /// let mut decryptor = DecryptorBuilder::from_bytes(&original)?
2676 /// .with_policy(p, None, Helper::new(alice))?;
2677 /// io::copy(&mut decryptor, &mut io::sink())?;
2678 /// let (algo, sk, pkesks) = decryptor.into_helper().recycling_bin.unwrap();
2679 ///
2680 /// // Compose the reply using the same session key.
2681 /// let mut reply = vec![];
2682 /// let mut message = Message::new(&mut reply);
2683 /// for p in pkesks { // Emit the stashed PKESK packets.
2684 /// Packet::from(p).serialize(&mut message)?;
2685 /// }
2686 /// let message = Encryptor::with_session_key(
2687 /// message, algo.unwrap_or_default(), sk)?
2688 /// .aead_algo(Default::default())
2689 /// .build()?;
2690 /// let mut w = LiteralWriter::new(message).build()?;
2691 /// w.write_all(b"Encrypted reply")?;
2692 /// w.finalize()?;
2693 ///
2694 /// // Check that Bob can decrypt it.
2695 /// let mut decryptor = DecryptorBuilder::from_bytes(&reply)?
2696 /// .with_policy(p, None, Helper::new(bob))?;
2697 /// io::copy(&mut decryptor, &mut io::sink())?;
2698 ///
2699 /// /// Decrypts the message preserving algo, session key, and PKESKs.
2700 /// struct Helper {
2701 /// key: Cert,
2702 /// recycling_bin: Option<(Option<SymmetricAlgorithm>, SessionKey, Vec<PKESK>)>,
2703 /// }
2704 ///
2705 /// # impl Helper {
2706 /// # fn new(key: Cert) -> Self {
2707 /// # Helper { key, recycling_bin: None, }
2708 /// # }
2709 /// # }
2710 /// #
2711 /// impl DecryptionHelper for Helper {
2712 /// fn decrypt(&mut self, pkesks: &[PKESK], _skesks: &[SKESK],
2713 /// sym_algo: Option<SymmetricAlgorithm>,
2714 /// decrypt: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
2715 /// -> Result<Option<Cert>>
2716 /// {
2717 /// let p = &StandardPolicy::new();
2718 /// let mut encryption_context = None;
2719 ///
2720 /// for pkesk in pkesks { // Try each PKESK until we succeed.
2721 /// for ka in self.key.keys().with_policy(p, None)
2722 /// .supported().unencrypted_secret()
2723 /// .key_handles(pkesk.recipient())
2724 /// .for_storage_encryption().for_transport_encryption()
2725 /// {
2726 /// let mut pair = ka.key().clone().into_keypair().unwrap();
2727 /// if pkesk.decrypt(&mut pair, sym_algo)
2728 /// .map(|(algo, session_key)| {
2729 /// let success = decrypt(algo, &session_key);
2730 /// if success {
2731 /// // Copy algor, session key, and PKESKs.
2732 /// encryption_context =
2733 /// Some((algo, session_key.clone(),
2734 /// pkesks.iter().cloned().collect()));
2735 /// }
2736 /// success
2737 /// })
2738 /// .unwrap_or(false)
2739 /// {
2740 /// break; // Decryption successful.
2741 /// }
2742 /// }
2743 /// }
2744 ///
2745 /// self.recycling_bin = encryption_context; // Store for the reply.
2746 /// Ok(Some(self.key.clone()))
2747 /// }
2748 /// }
2749 ///
2750 /// impl VerificationHelper for Helper {
2751 /// // ...
2752 /// # fn get_certs(&mut self, _ids: &[KeyHandle]) -> Result<Vec<Cert>> {
2753 /// # Ok(Vec::new()) // Lookup certificates here.
2754 /// # }
2755 /// # fn check(&mut self, structure: MessageStructure) -> Result<()> {
2756 /// # Ok(()) // Implement your verification policy here.
2757 /// # }
2758 /// }
2759 /// # Ok(()) }
2760 /// ```
2761 pub fn with_session_key(inner: Message<'a>,
2762 sym_algo: SymmetricAlgorithm,
2763 session_key: SessionKey)
2764 -> Result<Self>
2765 {
2766 let sym_key_size = sym_algo.key_size()?;
2767 if session_key.len() != sym_key_size {
2768 return Err(Error::InvalidArgument(
2769 format!("{} requires a {} bit key, but session key has {}",
2770 sym_algo, sym_key_size, session_key.len())).into());
2771 }
2772
2773 Ok(Self {
2774 inner: inner.into(),
2775 session_key: Some(session_key),
2776 recipients: Vec::new(),
2777 passwords: Vec::with_capacity(0),
2778 sym_algo,
2779 aead_algo: Default::default(),
2780 hash: HashAlgorithm::SHA1.context().unwrap().for_digest(),
2781 cookie: Default::default(), // Will be fixed in build.
2782 })
2783 }
2784
2785 /// Adds recipients.
2786 ///
2787 /// The resulting message can be encrypted by any recipient and
2788 /// with any password.
2789 ///
2790 /// # Examples
2791 ///
2792 /// ```
2793 /// # fn main() -> sequoia_openpgp::Result<()> {
2794 /// use std::io::Write;
2795 /// use sequoia_openpgp as openpgp;
2796 /// use openpgp::cert::prelude::*;
2797 /// use openpgp::serialize::stream::{
2798 /// Message, Encryptor, LiteralWriter,
2799 /// };
2800 /// use openpgp::policy::StandardPolicy;
2801 /// # use openpgp::parse::Parse;
2802 /// let p = &StandardPolicy::new();
2803 ///
2804 /// let cert = Cert::from_bytes(
2805 /// # // We do some acrobatics here to abbreviate the Cert.
2806 /// "-----BEGIN PGP PUBLIC KEY BLOCK-----
2807 ///
2808 /// mQENBFpxtsABCADZcBa1Q3ZLZnju18o0+t8LoQuIIeyeUQ0H45y6xUqyrD5HSkVM
2809 /// # VGQs6IHLq70mAizBJ4VznUVqVOh/NhOlapXi6/TKpjHvttdg45o6Pgqa0Kx64luT
2810 /// # ZY+TEKyILcdBdhr3CzsEILnQst5jadgMvU9fnT/EkJIvxtWPlUzU5R7nnALO626x
2811 /// # 2M5Pj3k0h3ZNHMmYQQtReX/RP/xUh2SfOYG6i/MCclIlee8BXHB9k0bW2NAX2W7H
2812 /// # rLDGPm1LzmyqxFGDvDvfPlYZ5nN2cbGsv3w75LDzv75kMhVnkZsrUjnHjVRzFq7q
2813 /// # fSIpxlvJMEMKSIJ/TFztQoOBO5OlBb5qzYPpABEBAAG0F+G8iM+BzrnPg8+Ezr/P
2814 /// # hM6tzrvOt8+CiQFUBBMBCAA+FiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsAC
2815 /// # GwMFCQPCZwAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQJH9tq8hJFP49hgf+
2816 /// # IKvec0RkD9EHSLFc6AKDm/knaI4AIH0isZTz9jRCF8H/j3h8QVUE+/0jtCcyvR6F
2817 /// # TGVSfO3pelDPYGIjDFI3aA6H/UlhZWzYRXZ+QQRrV0zwvLna3XjiW8ib3Ky+5bpQ
2818 /// # 0uVeee30u+U3SnaCL9QB4+UvwVvAxRuk49Z0Q8TsRrQyQNYpeZDN7uNrvA134cf6
2819 /// # 6pLUvzPG4lMLIvSXFuHou704EhT7NS3wAzFtjMrsLLieVqtbEi/kBaJTQSZQwjVB
2820 /// # sE/Z8lp1heKw/33Br3cB63n4cTf0FdoFywDBhCAMU7fKboU5xBpm5bQJ4ck6j6w+
2821 /// # BKG1FiQRR6PCUeb6GjxVOrkBDQRacbbAAQgAw538MMb/pRdpt7PTgBCedw+rU9fh
2822 /// # onZYKwmCO7wz5VrVf8zIVvWKxhX6fBTSAy8mxaYbeL/3woQ9Leuo8f0PQNs9zw1N
2823 /// # mdH+cnm2KQmL9l7/HQKMLgEAu/0C/q7ii/j8OMYitaMUyrwy+OzW3nCal/uJHIfj
2824 /// # bdKx29MbKgF/zaBs8mhTvf/Tu0rIVNDPEicwijDEolGSGebZxdGdHJA31uayMHDK
2825 /// # /mwySJViMZ8b+Lzc/dRgNbQoY6yjsjso7U9OZpQK1fooHOSQS6iLsSSsZLcGPD+7
2826 /// # m7j3jwq68SIJPMsu0O8hdjFWL4Cfj815CwptAxRGkp00CIusAabO7m8DzwARAQAB
2827 /// # iQE2BBgBCAAgFiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsACGwwACgkQJH9t
2828 /// # q8hJFP5rmQgAoYOUXolTiQmWipJTdMG/VZ5X7mL8JiBWAQ11K1o01cZCMlziyHnJ
2829 /// # xJ6Mqjb6wAFpYBtqysJG/vfjc/XEoKgfFs7+zcuEnt41xJQ6tl/L0VTxs+tEwjZu
2830 /// # Rp/owB9GCkqN9+xNEnlH77TLW1UisW+l0F8CJ2WFOj4lk9rcXcLlEdGmXfWIlVCb
2831 /// # 2/o0DD+HDNsF8nWHpDEy0mcajkgIUTvXQaDXKbccX6Wgep8dyBP7YucGmRPd9Z6H
2832 /// # bGeT3KvlJlH5kthQ9shsmT14gYwGMR6rKpNUXmlpetkjqUK7pGVaHGgJWUZ9QPGU
2833 /// # awwPdWWvZSyXJAPZ9lC5sTKwMJDwIxILug==
2834 /// # =lAie
2835 /// # -----END PGP PUBLIC KEY BLOCK-----"
2836 /// # /*
2837 /// ...
2838 /// -----END PGP PUBLIC KEY BLOCK-----"
2839 /// # */
2840 /// )?;
2841 ///
2842 /// let recipients =
2843 /// cert.keys().with_policy(p, None).supported().alive().revoked(false)
2844 /// // Or `for_storage_encryption()`, for data at rest.
2845 /// .for_transport_encryption();
2846 ///
2847 /// # let mut sink = vec![];
2848 /// let message = Message::new(&mut sink);
2849 /// let message =
2850 /// Encryptor::with_passwords(message, Some("совершенно секретно"))
2851 /// .add_recipients(recipients)
2852 /// .build()?;
2853 /// let mut message = LiteralWriter::new(message).build()?;
2854 /// message.write_all(b"Hello world.")?;
2855 /// message.finalize()?;
2856 /// # Ok(()) }
2857 /// ```
2858 pub fn add_recipients<R>(mut self, recipients: R) -> Self
2859 where R: IntoIterator,
2860 R::Item: Into<Recipient<'b>>,
2861 {
2862 for r in recipients {
2863 self.recipients.push(r.into());
2864 }
2865 self
2866 }
2867
2868 /// Adds passwords to encrypt with.
2869 ///
2870 /// The resulting message can be encrypted with any password and
2871 /// by any recipient.
2872 ///
2873 /// # Examples
2874 ///
2875 /// ```
2876 /// # fn main() -> sequoia_openpgp::Result<()> {
2877 /// use std::io::Write;
2878 /// use sequoia_openpgp as openpgp;
2879 /// use openpgp::cert::prelude::*;
2880 /// use openpgp::serialize::stream::{
2881 /// Message, Encryptor, LiteralWriter,
2882 /// };
2883 /// use openpgp::policy::StandardPolicy;
2884 /// # use openpgp::parse::Parse;
2885 /// let p = &StandardPolicy::new();
2886 ///
2887 /// let cert = Cert::from_bytes(
2888 /// # // We do some acrobatics here to abbreviate the Cert.
2889 /// "-----BEGIN PGP PUBLIC KEY BLOCK-----
2890 ///
2891 /// mQENBFpxtsABCADZcBa1Q3ZLZnju18o0+t8LoQuIIeyeUQ0H45y6xUqyrD5HSkVM
2892 /// # VGQs6IHLq70mAizBJ4VznUVqVOh/NhOlapXi6/TKpjHvttdg45o6Pgqa0Kx64luT
2893 /// # ZY+TEKyILcdBdhr3CzsEILnQst5jadgMvU9fnT/EkJIvxtWPlUzU5R7nnALO626x
2894 /// # 2M5Pj3k0h3ZNHMmYQQtReX/RP/xUh2SfOYG6i/MCclIlee8BXHB9k0bW2NAX2W7H
2895 /// # rLDGPm1LzmyqxFGDvDvfPlYZ5nN2cbGsv3w75LDzv75kMhVnkZsrUjnHjVRzFq7q
2896 /// # fSIpxlvJMEMKSIJ/TFztQoOBO5OlBb5qzYPpABEBAAG0F+G8iM+BzrnPg8+Ezr/P
2897 /// # hM6tzrvOt8+CiQFUBBMBCAA+FiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsAC
2898 /// # GwMFCQPCZwAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQJH9tq8hJFP49hgf+
2899 /// # IKvec0RkD9EHSLFc6AKDm/knaI4AIH0isZTz9jRCF8H/j3h8QVUE+/0jtCcyvR6F
2900 /// # TGVSfO3pelDPYGIjDFI3aA6H/UlhZWzYRXZ+QQRrV0zwvLna3XjiW8ib3Ky+5bpQ
2901 /// # 0uVeee30u+U3SnaCL9QB4+UvwVvAxRuk49Z0Q8TsRrQyQNYpeZDN7uNrvA134cf6
2902 /// # 6pLUvzPG4lMLIvSXFuHou704EhT7NS3wAzFtjMrsLLieVqtbEi/kBaJTQSZQwjVB
2903 /// # sE/Z8lp1heKw/33Br3cB63n4cTf0FdoFywDBhCAMU7fKboU5xBpm5bQJ4ck6j6w+
2904 /// # BKG1FiQRR6PCUeb6GjxVOrkBDQRacbbAAQgAw538MMb/pRdpt7PTgBCedw+rU9fh
2905 /// # onZYKwmCO7wz5VrVf8zIVvWKxhX6fBTSAy8mxaYbeL/3woQ9Leuo8f0PQNs9zw1N
2906 /// # mdH+cnm2KQmL9l7/HQKMLgEAu/0C/q7ii/j8OMYitaMUyrwy+OzW3nCal/uJHIfj
2907 /// # bdKx29MbKgF/zaBs8mhTvf/Tu0rIVNDPEicwijDEolGSGebZxdGdHJA31uayMHDK
2908 /// # /mwySJViMZ8b+Lzc/dRgNbQoY6yjsjso7U9OZpQK1fooHOSQS6iLsSSsZLcGPD+7
2909 /// # m7j3jwq68SIJPMsu0O8hdjFWL4Cfj815CwptAxRGkp00CIusAabO7m8DzwARAQAB
2910 /// # iQE2BBgBCAAgFiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsACGwwACgkQJH9t
2911 /// # q8hJFP5rmQgAoYOUXolTiQmWipJTdMG/VZ5X7mL8JiBWAQ11K1o01cZCMlziyHnJ
2912 /// # xJ6Mqjb6wAFpYBtqysJG/vfjc/XEoKgfFs7+zcuEnt41xJQ6tl/L0VTxs+tEwjZu
2913 /// # Rp/owB9GCkqN9+xNEnlH77TLW1UisW+l0F8CJ2WFOj4lk9rcXcLlEdGmXfWIlVCb
2914 /// # 2/o0DD+HDNsF8nWHpDEy0mcajkgIUTvXQaDXKbccX6Wgep8dyBP7YucGmRPd9Z6H
2915 /// # bGeT3KvlJlH5kthQ9shsmT14gYwGMR6rKpNUXmlpetkjqUK7pGVaHGgJWUZ9QPGU
2916 /// # awwPdWWvZSyXJAPZ9lC5sTKwMJDwIxILug==
2917 /// # =lAie
2918 /// # -----END PGP PUBLIC KEY BLOCK-----"
2919 /// # /*
2920 /// ...
2921 /// -----END PGP PUBLIC KEY BLOCK-----"
2922 /// # */
2923 /// )?;
2924 ///
2925 /// let recipients =
2926 /// cert.keys().with_policy(p, None).supported().alive().revoked(false)
2927 /// // Or `for_storage_encryption()`, for data at rest.
2928 /// .for_transport_encryption();
2929 ///
2930 /// # let mut sink = vec![];
2931 /// let message = Message::new(&mut sink);
2932 /// let message =
2933 /// Encryptor::for_recipients(message, recipients)
2934 /// .add_passwords(Some("совершенно секретно"))
2935 /// .build()?;
2936 /// let mut message = LiteralWriter::new(message).build()?;
2937 /// message.write_all(b"Hello world.")?;
2938 /// message.finalize()?;
2939 /// # Ok(()) }
2940 /// ```
2941 pub fn add_passwords<P>(mut self, passwords: P) -> Self
2942 where P: IntoIterator,
2943 P::Item: Into<Password>,
2944 {
2945 for p in passwords {
2946 self.passwords.push(p.into());
2947 }
2948 self
2949 }
2950
2951 /// Sets the symmetric algorithm to use.
2952 ///
2953 /// # Examples
2954 ///
2955 /// ```
2956 /// # fn main() -> sequoia_openpgp::Result<()> {
2957 /// use std::io::Write;
2958 /// use sequoia_openpgp as openpgp;
2959 /// use openpgp::types::SymmetricAlgorithm;
2960 /// use openpgp::serialize::stream::{
2961 /// Message, Encryptor, LiteralWriter,
2962 /// };
2963 ///
2964 /// # let mut sink = vec![];
2965 /// let message = Message::new(&mut sink);
2966 /// let message =
2967 /// Encryptor::with_passwords(message, Some("совершенно секретно"))
2968 /// .symmetric_algo(SymmetricAlgorithm::AES128)
2969 /// .build()?;
2970 /// let mut message = LiteralWriter::new(message).build()?;
2971 /// message.write_all(b"Hello world.")?;
2972 /// message.finalize()?;
2973 /// # Ok(()) }
2974 /// ```
2975 pub fn symmetric_algo(mut self, algo: SymmetricAlgorithm) -> Self {
2976 self.sym_algo = algo;
2977 self
2978 }
2979
2980 /// Enables AEAD and sets the AEAD algorithm to use.
2981 ///
2982 /// # Examples
2983 ///
2984 /// ```
2985 /// # fn main() -> sequoia_openpgp::Result<()> {
2986 /// use std::io::Write;
2987 /// use sequoia_openpgp as openpgp;
2988 /// use openpgp::types::AEADAlgorithm;
2989 /// use openpgp::serialize::stream::{
2990 /// Message, Encryptor, LiteralWriter,
2991 /// };
2992 ///
2993 /// # let mut sink = vec![];
2994 /// let message = Message::new(&mut sink);
2995 /// let message =
2996 /// Encryptor::with_passwords(message, Some("совершенно секретно"))
2997 /// .aead_algo(AEADAlgorithm::default())
2998 /// .build()?;
2999 /// let mut message = LiteralWriter::new(message).build()?;
3000 /// message.write_all(b"Hello world.")?;
3001 /// message.finalize()?;
3002 /// # Ok(()) }
3003 /// ```
3004 pub fn aead_algo(mut self, algo: AEADAlgorithm) -> Self {
3005 self.aead_algo = Some(algo);
3006 self
3007 }
3008
3009 // The default chunk size.
3010 //
3011 // A page, 3 per mille overhead.
3012 const AEAD_CHUNK_SIZE : usize = 4096;
3013
3014 /// Builds the encryptor, returning the writer stack.
3015 ///
3016 /// The most useful filters to push to the writer stack next are
3017 /// the [`Padder`] or [`Compressor`], and after that the
3018 /// [`Signer`]. Finally, literal data *must* be wrapped using the
3019 /// [`LiteralWriter`].
3020 ///
3021 /// [`Padder`]: padding::Padder
3022 ///
3023 /// # Examples
3024 ///
3025 /// ```
3026 /// # fn main() -> sequoia_openpgp::Result<()> {
3027 /// use std::io::Write;
3028 /// use sequoia_openpgp as openpgp;
3029 /// use openpgp::serialize::stream::{
3030 /// Message, Encryptor, LiteralWriter,
3031 /// };
3032 ///
3033 /// # let mut sink = vec![];
3034 /// let message = Message::new(&mut sink);
3035 /// let message =
3036 /// Encryptor::with_passwords(message, Some("совершенно секретно"))
3037 /// // Customize the `Encryptor` here.
3038 /// .build()?;
3039 ///
3040 /// // Optionally add a `Padder` or `Compressor` here.
3041 /// // Optionally add a `Signer` here.
3042 ///
3043 /// let mut message = LiteralWriter::new(message).build()?;
3044 /// message.write_all(b"Hello world.")?;
3045 /// message.finalize()?;
3046 /// # Ok(()) }
3047 /// ```
3048 pub fn build(mut self) -> Result<Message<'a>> {
3049 if self.recipients.len() + self.passwords.len() == 0
3050 && self.session_key.is_none()
3051 {
3052 return Err(Error::InvalidOperation(
3053 "Neither recipients, passwords, nor session key given".into()
3054 ).into());
3055 }
3056
3057 if self.aead_algo.is_none() {
3058 // See whether all recipients support SEIPDv2.
3059 if ! self.recipients.is_empty()
3060 && self.recipients.iter().all(|r| {
3061 r.features.supports_seipdv2()
3062 })
3063 {
3064 // This prefers OCB if supported. OCB is MTI.
3065 self.aead_algo = Some(AEADAlgorithm::const_default());
3066 }
3067 }
3068
3069 struct AEADParameters {
3070 algo: AEADAlgorithm,
3071 chunk_size: usize,
3072 salt: [u8; 32],
3073 }
3074
3075 let aead = if let Some(algo) = self.aead_algo {
3076 // Configure any armor writer above us.
3077 writer::Armorer::set_profile(&mut self, Profile::RFC9580);
3078
3079 let mut salt = [0u8; 32];
3080 crypto::random(&mut salt)?;
3081 Some(AEADParameters {
3082 algo,
3083 chunk_size: Self::AEAD_CHUNK_SIZE,
3084 salt,
3085 })
3086 } else {
3087 None
3088 };
3089
3090 let mut inner = self.inner;
3091 let level = inner.as_ref().cookie_ref().level + 1;
3092
3093 // Reuse existing session key or generate a new one.
3094 let sym_key_size = self.sym_algo.key_size()?;
3095 let sk = self.session_key.take()
3096 .map(|sk| Ok(sk))
3097 .unwrap_or_else(|| SessionKey::new(sym_key_size))?;
3098 if sk.len() != sym_key_size {
3099 return Err(Error::InvalidOperation(
3100 format!("{} requires a {} bit key, but session key has {}",
3101 self.sym_algo, sym_key_size, sk.len())).into());
3102 }
3103
3104 // Write the PKESK packet(s).
3105 for recipient in self.recipients.iter() {
3106 if aead.is_some() {
3107 let mut pkesk =
3108 PKESK6::for_recipient(&sk, recipient.key)?;
3109 pkesk.set_recipient(recipient.key_handle()
3110 .map(TryInto::try_into)
3111 .transpose()?);
3112 Packet::from(pkesk).serialize(&mut inner)?;
3113 } else {
3114 let mut pkesk =
3115 PKESK3::for_recipient(self.sym_algo, &sk, recipient.key)?;
3116 pkesk.set_recipient(recipient.key_handle().map(Into::into));
3117 Packet::PKESK(pkesk.into()).serialize(&mut inner)?;
3118 }
3119 }
3120
3121 // Write the SKESK packet(s).
3122 for password in self.passwords.iter() {
3123 if let Some(aead) = aead.as_ref() {
3124 let skesk = SKESK6::with_password(self.sym_algo,
3125 self.sym_algo,
3126 aead.algo,
3127 Default::default(),
3128 &sk, password).unwrap();
3129 Packet::SKESK(skesk.into()).serialize(&mut inner)?;
3130 } else {
3131 let skesk = SKESK4::with_password(self.sym_algo,
3132 self.sym_algo,
3133 Default::default(),
3134 &sk, password).unwrap();
3135 Packet::SKESK(skesk.into()).serialize(&mut inner)?;
3136 }
3137 }
3138
3139 if let Some(aead) = aead {
3140 // Write the SEIPDv2 packet.
3141 CTB::new(Tag::SEIP).serialize(&mut inner)?;
3142 let mut inner = PartialBodyFilter::new(Message::from(inner),
3143 Cookie::new(level));
3144 let seip = SEIP2::new(self.sym_algo, aead.algo,
3145 aead.chunk_size as u64, aead.salt)?;
3146 seip.serialize_headers(&mut inner)?;
3147
3148 use crate::crypto::aead::SEIPv2Schedule;
3149 let (message_key, schedule) = SEIPv2Schedule::new(
3150 &sk,
3151 seip.symmetric_algo(), seip.aead(), aead.chunk_size,
3152 seip.salt())?;
3153
3154 // Note: we have consumed self, and we are returning a
3155 // different encryptor here. self will be dropped, and
3156 // therefore, Self::emit_mdc will not be invoked.
3157
3158 writer::AEADEncryptor::new(
3159 inner,
3160 Cookie::new(level).set_private(Private::Encryptor {
3161 profile: Profile::RFC9580,
3162 }),
3163 seip.symmetric_algo(),
3164 seip.aead(),
3165 aead.chunk_size,
3166 schedule,
3167 message_key,
3168 )
3169 } else {
3170 // Write the SEIPDv1 packet.
3171 CTB::new(Tag::SEIP).serialize(&mut inner)?;
3172 let mut inner = PartialBodyFilter::new(Message::from(inner),
3173 Cookie::new(level));
3174 inner.write_all(&[1])?; // Version.
3175
3176 // Install encryptor.
3177 self.inner = writer::Encryptor::new(
3178 inner,
3179 Cookie::new(level),
3180 self.sym_algo,
3181 &sk,
3182 )?.into();
3183 self.cookie = Cookie::new(level)
3184 .set_private(Private::Encryptor {
3185 profile: Profile::RFC4880,
3186 });
3187
3188 // Write the initialization vector, and the quick-check
3189 // bytes. The hash for the MDC must include the
3190 // initialization vector, hence we must write this to
3191 // self after installing the encryptor at self.inner.
3192 let mut iv = vec![0; self.sym_algo.block_size()?];
3193 crypto::random(&mut iv)?;
3194 self.write_all(&iv)?;
3195 self.write_all(&iv[iv.len() - 2..])?;
3196
3197 Ok(Message::from(Box::new(self)))
3198 }
3199 }
3200
3201 /// Emits the MDC packet and recovers the original writer.
3202 ///
3203 /// Note: This is only invoked for SEIPDv1 messages, because
3204 /// Self::build consumes self, and will only return a writer stack
3205 /// with Self on top for SEIPDv1 messages. For SEIPDv2 messages,
3206 /// a different writer is returned.
3207 fn emit_mdc(mut self) -> Result<writer::BoxStack<'a, Cookie>> {
3208 let mut w = self.inner;
3209
3210 // Write the MDC, which must be the last packet inside the
3211 // encrypted packet stream. The hash includes the MDC's
3212 // CTB and length octet.
3213 let mut header = Vec::new();
3214 CTB::new(Tag::MDC).serialize(&mut header)?;
3215 BodyLength::Full(20).serialize(&mut header)?;
3216
3217 self.hash.update(&header);
3218 #[allow(deprecated)]
3219 Packet::MDC(MDC::from(self.hash.clone())).serialize(&mut w)?;
3220
3221 // Now recover the original writer. First, strip the
3222 // Encryptor.
3223 let w = w.into_inner()?.unwrap();
3224 // And the partial body filter.
3225 let w = w.into_inner()?.unwrap();
3226
3227 Ok(w)
3228 }
3229}
3230
3231impl<'a, 'b> fmt::Debug for Encryptor<'a, 'b>
3232 where 'b: 'a
3233{
3234 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3235 f.debug_struct("Encryptor")
3236 .field("inner", &self.inner)
3237 .finish()
3238 }
3239}
3240
3241impl<'a, 'b> Write for Encryptor<'a, 'b>
3242 where 'b: 'a
3243{
3244 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
3245 let written = self.inner.write(buf);
3246 if let Ok(amount) = written {
3247 self.hash.update(&buf[..amount]);
3248 }
3249 written
3250 }
3251
3252 fn flush(&mut self) -> io::Result<()> {
3253 self.inner.flush()
3254 }
3255}
3256
3257impl<'a, 'b> writer::Stackable<'a, Cookie> for Encryptor<'a, 'b>
3258 where 'b: 'a
3259{
3260 fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> {
3261 unreachable!("Only implemented by Signer")
3262 }
3263 /// Sets the inner stackable.
3264 fn mount(&mut self, _new: writer::BoxStack<'a, Cookie>) {
3265 unreachable!("Only implemented by Signer")
3266 }
3267 fn inner_ref(&self) -> Option<&(dyn writer::Stackable<'a, Cookie> + Send + Sync)> {
3268 Some(&self.inner)
3269 }
3270 fn inner_mut(&mut self) -> Option<&mut (dyn writer::Stackable<'a, Cookie> + Send + Sync)> {
3271 Some(&mut self.inner)
3272 }
3273 fn into_inner(self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> {
3274 Ok(Some(self.emit_mdc()?))
3275 }
3276 fn cookie_set(&mut self, cookie: Cookie) -> Cookie {
3277 ::std::mem::replace(&mut self.cookie, cookie)
3278 }
3279 fn cookie_ref(&self) -> &Cookie {
3280 &self.cookie
3281 }
3282 fn cookie_mut(&mut self) -> &mut Cookie {
3283 &mut self.cookie
3284 }
3285 fn position(&self) -> u64 {
3286 self.inner.position()
3287 }
3288}
3289
3290#[cfg(test)]
3291mod test {
3292 use std::io::Read;
3293 use crate::{Packet, PacketPile, Profile, packet::CompressedData};
3294 use crate::parse::{Parse, PacketParserResult, PacketParser};
3295 use super::*;
3296 use crate::types::DataFormat::Unicode as T;
3297 use crate::policy::Policy;
3298 use crate::policy::StandardPolicy as P;
3299
3300 #[test]
3301 fn arbitrary() {
3302 let mut o = vec![];
3303 {
3304 let m = Message::new(&mut o);
3305 let mut ustr = ArbitraryWriter::new(m, Tag::Literal).unwrap();
3306 ustr.write_all(b"u").unwrap(); // type
3307 ustr.write_all(b"\x00").unwrap(); // fn length
3308 ustr.write_all(b"\x00\x00\x00\x00").unwrap(); // date
3309 ustr.write_all(b"Hello world.").unwrap(); // body
3310 ustr.finalize().unwrap();
3311 }
3312
3313 let mut pp = PacketParser::from_bytes(&o).unwrap().unwrap();
3314 if let Packet::Literal(ref l) = pp.packet {
3315 assert_eq!(l.format(), DataFormat::Unicode);
3316 assert_eq!(l.filename(), None);
3317 assert_eq!(l.date(), None);
3318 } else {
3319 panic!("Unexpected packet type.");
3320 }
3321
3322 let mut body = vec![];
3323 pp.read_to_end(&mut body).unwrap();
3324 assert_eq!(&body, b"Hello world.");
3325
3326 // Make sure it is the only packet.
3327 let (_, ppr) = pp.recurse().unwrap();
3328 assert!(ppr.is_eof());
3329 }
3330
3331 // Create some crazy nesting structures, serialize the messages,
3332 // reparse them, and make sure we get the same result.
3333 #[test]
3334 fn stream_0() {
3335 // 1: CompressedData(CompressedData { algo: 0 })
3336 // 1: Literal(Literal { body: "one (3 bytes)" })
3337 // 2: Literal(Literal { body: "two (3 bytes)" })
3338 // 2: Literal(Literal { body: "three (5 bytes)" })
3339 let mut one = Literal::new(T);
3340 one.set_body(b"one".to_vec());
3341 let mut two = Literal::new(T);
3342 two.set_body(b"two".to_vec());
3343 let mut three = Literal::new(T);
3344 three.set_body(b"three".to_vec());
3345 let mut reference = Vec::new();
3346 reference.push(
3347 CompressedData::new(CompressionAlgorithm::Uncompressed)
3348 .push(one.into())
3349 .push(two.into())
3350 .into());
3351 reference.push(three.into());
3352
3353 let mut o = vec![];
3354 {
3355 let m = Message::new(&mut o);
3356 let c = Compressor::new(m)
3357 .algo(CompressionAlgorithm::Uncompressed).build().unwrap();
3358 let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
3359 write!(ls, "one").unwrap();
3360 let c = ls.finalize_one().unwrap().unwrap(); // Pop the LiteralWriter.
3361 let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
3362 write!(ls, "two").unwrap();
3363 let c = ls.finalize_one().unwrap().unwrap(); // Pop the LiteralWriter.
3364 let c = c.finalize_one().unwrap().unwrap(); // Pop the Compressor.
3365 let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
3366 write!(ls, "three").unwrap();
3367 ls.finalize().unwrap();
3368 }
3369
3370 let pile = PacketPile::from(reference);
3371 let pile2 = PacketPile::from_bytes(&o).unwrap();
3372 if pile != pile2 {
3373 eprintln!("REFERENCE...");
3374 pile.pretty_print();
3375 eprintln!("REPARSED...");
3376 pile2.pretty_print();
3377 panic!("Reparsed packet does not match reference packet!");
3378 }
3379 }
3380
3381 // Create some crazy nesting structures, serialize the messages,
3382 // reparse them, and make sure we get the same result.
3383 #[test]
3384 fn stream_1() {
3385 // 1: CompressedData(CompressedData { algo: 0 })
3386 // 1: CompressedData(CompressedData { algo: 0 })
3387 // 1: Literal(Literal { body: "one (3 bytes)" })
3388 // 2: Literal(Literal { body: "two (3 bytes)" })
3389 // 2: CompressedData(CompressedData { algo: 0 })
3390 // 1: Literal(Literal { body: "three (5 bytes)" })
3391 // 2: Literal(Literal { body: "four (4 bytes)" })
3392 let mut one = Literal::new(T);
3393 one.set_body(b"one".to_vec());
3394 let mut two = Literal::new(T);
3395 two.set_body(b"two".to_vec());
3396 let mut three = Literal::new(T);
3397 three.set_body(b"three".to_vec());
3398 let mut four = Literal::new(T);
3399 four.set_body(b"four".to_vec());
3400 let mut reference = Vec::new();
3401 reference.push(
3402 CompressedData::new(CompressionAlgorithm::Uncompressed)
3403 .push(CompressedData::new(CompressionAlgorithm::Uncompressed)
3404 .push(one.into())
3405 .push(two.into())
3406 .into())
3407 .push(CompressedData::new(CompressionAlgorithm::Uncompressed)
3408 .push(three.into())
3409 .push(four.into())
3410 .into())
3411 .into());
3412
3413 let mut o = vec![];
3414 {
3415 let m = Message::new(&mut o);
3416 let c0 = Compressor::new(m)
3417 .algo(CompressionAlgorithm::Uncompressed).build().unwrap();
3418 let c = Compressor::new(c0)
3419 .algo(CompressionAlgorithm::Uncompressed).build().unwrap();
3420 let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
3421 write!(ls, "one").unwrap();
3422 let c = ls.finalize_one().unwrap().unwrap();
3423 let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
3424 write!(ls, "two").unwrap();
3425 let c = ls.finalize_one().unwrap().unwrap();
3426 let c0 = c.finalize_one().unwrap().unwrap();
3427 let c = Compressor::new(c0)
3428 .algo(CompressionAlgorithm::Uncompressed).build().unwrap();
3429 let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
3430 write!(ls, "three").unwrap();
3431 let c = ls.finalize_one().unwrap().unwrap();
3432 let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
3433 write!(ls, "four").unwrap();
3434 ls.finalize().unwrap();
3435 }
3436
3437 let pile = PacketPile::from(reference);
3438 let pile2 = PacketPile::from_bytes(&o).unwrap();
3439 if pile != pile2 {
3440 eprintln!("REFERENCE...");
3441 pile.pretty_print();
3442 eprintln!("REPARSED...");
3443 pile2.pretty_print();
3444 panic!("Reparsed packet does not match reference packet!");
3445 }
3446 }
3447
3448 #[cfg(feature = "compression-bzip2")]
3449 #[test]
3450 fn stream_big() {
3451 let zeros = vec![0; 1024 * 1024 * 4];
3452 let mut o = vec![];
3453 {
3454 let m = Message::new(&mut o);
3455 let c = Compressor::new(m)
3456 .algo(CompressionAlgorithm::BZip2).build().unwrap();
3457 let mut ls = LiteralWriter::new(c).build().unwrap();
3458 // Write 64 megabytes of zeroes.
3459 for _ in 0 .. 16 {
3460 ls.write_all(&zeros).unwrap();
3461 }
3462 }
3463 assert!(o.len() < 1024);
3464 }
3465
3466 #[test]
3467 fn signature() {
3468 let p = &P::new();
3469 use crate::crypto::KeyPair;
3470 use std::collections::HashMap;
3471 use crate::Fingerprint;
3472
3473 let mut keys: HashMap<Fingerprint, key::UnspecifiedPublic> = HashMap::new();
3474 for tsk in &[
3475 Cert::from_bytes(crate::tests::key("testy-private.pgp")).unwrap(),
3476 Cert::from_bytes(crate::tests::key("testy-new-private.pgp")).unwrap(),
3477 ] {
3478 for key in tsk.keys().with_policy(p, crate::frozen_time())
3479 .for_signing().map(|ka| ka.key())
3480 {
3481 keys.insert(key.fingerprint(), key.clone());
3482 }
3483 }
3484
3485 let mut o = vec![];
3486 {
3487 let mut signers = keys.iter().map(|(_, key)| {
3488 key.clone().parts_into_secret().unwrap().into_keypair()
3489 .expect("expected unencrypted secret key")
3490 }).collect::<Vec<KeyPair>>();
3491
3492 let m = Message::new(&mut o);
3493 let mut signer = Signer::new(m, signers.pop().unwrap()).unwrap();
3494 for s in signers.into_iter() {
3495 signer = signer.add_signer(s).unwrap();
3496 }
3497 let signer = signer.build().unwrap();
3498 let mut ls = LiteralWriter::new(signer).build().unwrap();
3499 ls.write_all(b"Tis, tis, tis. Tis is important.").unwrap();
3500 let _ = ls.finalize().unwrap();
3501 }
3502
3503 let mut ppr = PacketParser::from_bytes(&o).unwrap();
3504 let mut good = 0;
3505 while let PacketParserResult::Some(mut pp) = ppr {
3506 if let Packet::Signature(sig) = &mut pp.packet {
3507 let key = keys.get(sig.issuer_fingerprints().next().unwrap())
3508 .unwrap();
3509 sig.verify_document(key).unwrap();
3510 good += 1;
3511 }
3512
3513 // Get the next packet.
3514 ppr = pp.recurse().unwrap().1;
3515 }
3516 assert_eq!(good, 2);
3517 }
3518
3519 #[test]
3520 fn encryptor() {
3521 let passwords = vec!["streng geheim".into(),
3522 "top secret".into()];
3523 let message = b"Hello world.";
3524
3525 // Write a simple encrypted message...
3526 let mut o = vec![];
3527 {
3528 let m = Message::new(&mut o);
3529 let encryptor = Encryptor::with_passwords(m, passwords.clone())
3530 .build().unwrap();
3531 let mut literal = LiteralWriter::new(encryptor).build()
3532 .unwrap();
3533 literal.write_all(message).unwrap();
3534 literal.finalize().unwrap();
3535 }
3536
3537 // ... and recover it...
3538 #[derive(Debug, PartialEq)]
3539 enum State {
3540 Start,
3541 Decrypted(Vec<(Option<SymmetricAlgorithm>, SessionKey)>),
3542 Deciphered,
3543 MDC,
3544 Done,
3545 }
3546
3547 // ... with every password.
3548 for password in &passwords {
3549 let mut state = State::Start;
3550 let mut ppr = PacketParser::from_bytes(&o).unwrap();
3551 while let PacketParserResult::Some(mut pp) = ppr {
3552 state = match state {
3553 // Look for the SKESK packet.
3554 State::Start =>
3555 if let Packet::SKESK(ref skesk) = pp.packet {
3556 match skesk.decrypt(password) {
3557 Ok((algo, key))
3558 => State::Decrypted(
3559 vec![(algo, key)]),
3560 Err(e) =>
3561 panic!("Decryption failed: {}", e),
3562 }
3563 } else {
3564 panic!("Unexpected packet: {:?}", pp.packet)
3565 },
3566
3567 // Look for the SEIP packet.
3568 State::Decrypted(mut keys) =>
3569 match pp.packet {
3570 Packet::SEIP(_) =>
3571 loop {
3572 if let Some((algo, key)) = keys.pop() {
3573 let r = pp.decrypt(algo, &key);
3574 if r.is_ok() {
3575 break State::Deciphered;
3576 }
3577 } else {
3578 panic!("seip decryption failed");
3579 }
3580 },
3581 Packet::SKESK(ref skesk) =>
3582 match skesk.decrypt(password) {
3583 Ok((algo, key)) => {
3584 keys.push((algo, key));
3585 State::Decrypted(keys)
3586 },
3587 Err(e) =>
3588 panic!("Decryption failed: {}", e),
3589 },
3590 _ =>
3591 panic!("Unexpected packet: {:?}", pp.packet),
3592 },
3593
3594 // Look for the literal data packet.
3595 State::Deciphered =>
3596 if let Packet::Literal(_) = pp.packet {
3597 let mut body = Vec::new();
3598 pp.read_to_end(&mut body).unwrap();
3599 assert_eq!(&body, message);
3600 State::MDC
3601 } else {
3602 panic!("Unexpected packet: {:?}", pp.packet)
3603 },
3604
3605 // Look for the MDC packet.
3606 #[allow(deprecated)]
3607 State::MDC =>
3608 if let Packet::MDC(ref mdc) = pp.packet {
3609 assert_eq!(mdc.digest(), mdc.computed_digest());
3610 State::Done
3611 } else {
3612 panic!("Unexpected packet: {:?}", pp.packet)
3613 },
3614
3615 State::Done =>
3616 panic!("Unexpected packet: {:?}", pp.packet),
3617 };
3618
3619 // Next?
3620 ppr = pp.recurse().unwrap().1;
3621 }
3622 assert_eq!(state, State::Done);
3623 }
3624 }
3625
3626 #[test]
3627 fn aead_eax() -> Result<()> {
3628 test_aead_messages(AEADAlgorithm::EAX)
3629 }
3630
3631 #[test]
3632 fn aead_ocb() -> Result<()> {
3633 test_aead_messages(AEADAlgorithm::OCB)
3634 }
3635
3636 #[test]
3637 fn aead_gcm() -> Result<()> {
3638 test_aead_messages(AEADAlgorithm::GCM)
3639 }
3640
3641 fn test_aead_messages(algo: AEADAlgorithm) -> Result<()> {
3642 test_aead_messages_v(algo, Profile::RFC4880)?;
3643 test_aead_messages_v(algo, Profile::RFC9580)?;
3644 Ok(())
3645 }
3646
3647 fn test_aead_messages_v(algo: AEADAlgorithm, profile: Profile)
3648 -> Result<()>
3649 {
3650 eprintln!("Testing with {:?}", profile);
3651
3652 if ! algo.is_supported() {
3653 eprintln!("Skipping because {} is not supported.", algo);
3654 return Ok(());
3655 }
3656
3657 // AEAD data is of the form:
3658 //
3659 // [ chunk1 ][ tag1 ] ... [ chunkN ][ tagN ][ tag ]
3660 //
3661 // All chunks are the same size except for the last chunk, which may
3662 // be shorter.
3663 //
3664 // In `Decryptor::read_helper`, we read a chunk and a tag worth of
3665 // data at a time. Because only the last chunk can be shorter, if
3666 // the amount read is less than `chunk_size + tag_size`, then we know
3667 // that we've read the last chunk.
3668 //
3669 // Unfortunately, this is not sufficient: if the last chunk is
3670 // `chunk_size - tag size` bytes large, then when we read it, we'll
3671 // read `chunk_size + tag_size` bytes, because we'll have also read
3672 // the final tag!
3673 //
3674 // Make sure we handle this situation correctly.
3675
3676 use std::cmp;
3677
3678 use crate::parse::{
3679 stream::{
3680 DecryptorBuilder,
3681 DecryptionHelper,
3682 VerificationHelper,
3683 MessageStructure,
3684 },
3685 };
3686 use crate::cert::prelude::*;
3687
3688 let (tsk, _) = CertBuilder::new()
3689 .set_cipher_suite(CipherSuite::Cv25519)
3690 .set_profile(profile)?
3691 .add_transport_encryption_subkey()
3692 .generate().unwrap();
3693
3694 struct Helper<'a> {
3695 policy: &'a dyn Policy,
3696 tsk: &'a Cert,
3697 }
3698 impl<'a> VerificationHelper for Helper<'a> {
3699 fn get_certs(&mut self, _ids: &[crate::KeyHandle])
3700 -> Result<Vec<Cert>> {
3701 Ok(Vec::new())
3702 }
3703 fn check(&mut self, _structure: MessageStructure) -> Result<()> {
3704 Ok(())
3705 }
3706 fn inspect(&mut self, pp: &PacketParser<'_>) -> Result<()> {
3707 assert!(! matches!(&pp.packet, Packet::Unknown(_)));
3708 eprintln!("Parsed {:?}", pp.packet);
3709 Ok(())
3710 }
3711 }
3712 impl<'a> DecryptionHelper for Helper<'a> {
3713 fn decrypt(&mut self, pkesks: &[PKESK], _skesks: &[SKESK],
3714 sym_algo: Option<SymmetricAlgorithm>,
3715 decrypt: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
3716 -> Result<Option<Cert>>
3717 {
3718 let mut keypair = self.tsk.keys().with_policy(self.policy, None)
3719 .for_transport_encryption()
3720 .map(|ka| ka.key()).next().unwrap()
3721 .clone().parts_into_secret().unwrap()
3722 .into_keypair().unwrap();
3723 pkesks[0].decrypt(&mut keypair, sym_algo)
3724 .map(|(algo, session_key)| decrypt(algo, &session_key));
3725 Ok(None)
3726 }
3727 }
3728
3729 let p = unsafe { &crate::policy::NullPolicy::new() };
3730
3731 for chunks in 0..3 {
3732 for msg_len in
3733 cmp::max(24, chunks * Encryptor::AEAD_CHUNK_SIZE) - 24
3734 ..chunks * Encryptor::AEAD_CHUNK_SIZE + 24
3735 {
3736 eprintln!("Encrypting message of size: {}", msg_len);
3737
3738 let mut content : Vec<u8> = Vec::new();
3739 for i in 0..msg_len {
3740 content.push(b'0' + ((i % 10) as u8));
3741 }
3742
3743 let mut msg = vec![];
3744 {
3745 let m = Message::new(&mut msg);
3746 let recipients = tsk
3747 .keys().with_policy(p, None)
3748 .for_storage_encryption().for_transport_encryption();
3749 let encryptor = Encryptor::for_recipients(m, recipients)
3750 .aead_algo(algo)
3751 .build().unwrap();
3752 let mut literal = LiteralWriter::new(encryptor).build()
3753 .unwrap();
3754 literal.write_all(&content).unwrap();
3755 literal.finalize().unwrap();
3756 }
3757
3758 for &read_len in &[
3759 37,
3760 Encryptor::AEAD_CHUNK_SIZE - 1,
3761 Encryptor::AEAD_CHUNK_SIZE,
3762 100 * Encryptor::AEAD_CHUNK_SIZE
3763 ] {
3764 for &do_err in &[ false, true ] {
3765 let mut msg = msg.clone();
3766 if do_err {
3767 let l = msg.len() - 1;
3768 if msg[l] == 0 {
3769 msg[l] = 1;
3770 } else {
3771 msg[l] = 0;
3772 }
3773 }
3774
3775 let h = Helper { policy: p, tsk: &tsk };
3776 // Note: a corrupted message is only guaranteed
3777 // to error out before it returns EOF.
3778 let mut v = match DecryptorBuilder::from_bytes(&msg)?
3779 .with_policy(p, None, h)
3780 {
3781 Ok(v) => v,
3782 Err(_) if do_err => continue,
3783 Err(err) => panic!("Decrypting message: {}", err),
3784 };
3785
3786 let mut buffer = Vec::new();
3787 buffer.resize(read_len, 0);
3788
3789 let mut decrypted_content = Vec::new();
3790 loop {
3791 match v.read(&mut buffer[..read_len]) {
3792 Ok(0) if do_err =>
3793 panic!("Expected an error, got EOF"),
3794 Ok(0) => break,
3795 Ok(len) =>
3796 decrypted_content.extend_from_slice(
3797 &buffer[..len]),
3798 Err(_) if do_err => break,
3799 Err(err) =>
3800 panic!("Decrypting data: {:?}", err),
3801 }
3802 }
3803
3804 if do_err {
3805 // If we get an error once, we should get
3806 // one again.
3807 for _ in 0..3 {
3808 assert!(v.read(&mut buffer[..read_len]).is_err());
3809 }
3810 }
3811
3812 // We only corrupted the final tag, so we
3813 // should get all the content.
3814 assert_eq!(msg_len, decrypted_content.len());
3815 assert_eq!(content, decrypted_content);
3816 }
3817 }
3818 }
3819 }
3820 Ok(())
3821 }
3822
3823 #[test]
3824 fn signature_at_time() {
3825 // Generates a signature with a specific Signature Creation
3826 // Time.
3827 use crate::cert::prelude::*;
3828 use crate::serialize::stream::{LiteralWriter, Message};
3829 use crate::crypto::KeyPair;
3830
3831 let p = &P::new();
3832
3833 let (cert, _) = CertBuilder::new()
3834 .add_signing_subkey()
3835 .set_cipher_suite(CipherSuite::Cv25519)
3836 .generate().unwrap();
3837
3838 // What we're going to sign with.
3839 let ka = cert.keys().with_policy(p, None).for_signing().next().unwrap();
3840
3841 // A timestamp later than the key's creation.
3842 let timestamp = ka.key().creation_time()
3843 + std::time::Duration::from_secs(14 * 24 * 60 * 60);
3844 assert!(ka.key().creation_time() < timestamp);
3845
3846 let mut o = vec![];
3847 {
3848 let signer_keypair : KeyPair =
3849 ka.key().clone().parts_into_secret().unwrap().into_keypair()
3850 .expect("expected unencrypted secret key");
3851
3852 let m = Message::new(&mut o);
3853 let signer = Signer::new(m, signer_keypair).unwrap();
3854 let signer = signer.creation_time(timestamp);
3855 let signer = signer.build().unwrap();
3856
3857 let mut ls = LiteralWriter::new(signer).build().unwrap();
3858 ls.write_all(b"Tis, tis, tis. Tis is important.").unwrap();
3859 let signer = ls.finalize_one().unwrap().unwrap();
3860 let _ = signer.finalize_one().unwrap().unwrap();
3861 }
3862
3863 let mut ppr = PacketParser::from_bytes(&o).unwrap();
3864 let mut good = 0;
3865 while let PacketParserResult::Some(mut pp) = ppr {
3866 if let Packet::Signature(sig) = &mut pp.packet {
3867 assert_eq!(sig.signature_creation_time(), Some(timestamp));
3868 sig.verify_document(ka.key()).unwrap();
3869 good += 1;
3870 }
3871
3872 // Get the next packet.
3873 ppr = pp.recurse().unwrap().1;
3874 }
3875 assert_eq!(good, 1);
3876 }
3877
3878 /// Checks that newlines are properly normalized when verifying
3879 /// text signatures.
3880 #[test]
3881 fn issue_530_signing() -> Result<()> {
3882 use std::io::Write;
3883 use crate::*;
3884 use crate::packet::signature;
3885 use crate::serialize::stream::{Message, Signer};
3886
3887 use crate::policy::StandardPolicy;
3888 use crate::{Result, Cert};
3889 use crate::parse::Parse;
3890 use crate::parse::stream::*;
3891
3892 let normalized_data = b"one\r\ntwo\r\nthree";
3893
3894 let p = &StandardPolicy::new();
3895 let cert: Cert =
3896 Cert::from_bytes(crate::tests::key("testy-new-private.pgp"))?;
3897
3898 for data in &[
3899 &b"one\r\ntwo\r\nthree"[..], // dos
3900 b"one\ntwo\nthree", // unix
3901 b"one\ntwo\r\nthree", // mixed
3902 b"one\r\ntwo\nthree",
3903 b"one\rtwo\rthree", // classic mac
3904 ] {
3905 eprintln!("{:?}", String::from_utf8(data.to_vec())?);
3906 let signing_keypair = cert.keys().secret()
3907 .with_policy(p, None).supported()
3908 .alive().revoked(false).for_signing().next().unwrap()
3909 .key().clone().into_keypair()?;
3910 let mut signature = vec![];
3911 {
3912 let message = Message::new(&mut signature);
3913 let mut message = Signer::with_template(
3914 message, signing_keypair,
3915 signature::SignatureBuilder::new(SignatureType::Text)
3916 )?.detached().build()?;
3917 message.write_all(data)?;
3918 message.finalize()?;
3919 }
3920
3921 struct Helper {}
3922 impl VerificationHelper for Helper {
3923 fn get_certs(&mut self, _ids: &[KeyHandle]) -> Result<Vec<Cert>>
3924 {
3925 Ok(vec![
3926 Cert::from_bytes(crate::tests::key("testy-new.pgp"))?])
3927 }
3928 fn check(&mut self, structure: MessageStructure) -> Result<()> {
3929 for (i, layer) in structure.iter().enumerate() {
3930 assert_eq!(i, 0);
3931 if let MessageLayer::SignatureGroup { results } = layer
3932 {
3933 assert_eq!(results.len(), 1);
3934 results[0].as_ref().unwrap();
3935 assert!(results[0].is_ok());
3936 return Ok(());
3937 } else {
3938 unreachable!();
3939 }
3940 }
3941 unreachable!()
3942 }
3943 }
3944
3945 let h = Helper {};
3946 let mut v = DetachedVerifierBuilder::from_bytes(&signature)?
3947 .with_policy(p, None, h)?;
3948
3949 v.verify_bytes(data)?;
3950 v.verify_bytes(normalized_data)?;
3951 }
3952
3953 Ok(())
3954 }
3955
3956 struct BadSigner;
3957
3958 impl crypto::Signer for BadSigner {
3959 fn public(&self) -> &Key<key::PublicParts, key::UnspecifiedRole> {
3960 panic!("public not impl")
3961 }
3962
3963 /// Returns a list of hashes that this signer accepts.
3964 fn acceptable_hashes(&self) -> &[HashAlgorithm] {
3965 &[]
3966 }
3967
3968 fn sign(&mut self, _hash_algo: HashAlgorithm, _digest: &[u8])
3969 -> Result<crypto::mpi::Signature> {
3970 panic!("sign not impl")
3971 }
3972 }
3973
3974 struct GoodSigner(Vec<HashAlgorithm>, Key<key::PublicParts, key::UnspecifiedRole>);
3975
3976 impl crypto::Signer for GoodSigner {
3977 fn public(&self) -> &Key<key::PublicParts, key::UnspecifiedRole> {
3978 &self.1
3979 }
3980
3981 /// Returns a list of hashes that this signer accepts.
3982 fn acceptable_hashes(&self) -> &[HashAlgorithm] {
3983 &self.0
3984 }
3985
3986 fn sign(&mut self, _hash_algo: HashAlgorithm, _digest: &[u8])
3987 -> Result<crypto::mpi::Signature> {
3988 unimplemented!()
3989 }
3990 }
3991
3992 impl Default for GoodSigner {
3993 fn default() -> Self {
3994 let p = &P::new();
3995
3996 let (cert, _) = CertBuilder::new().generate().unwrap();
3997
3998 let ka = cert.keys().with_policy(p, None).next().unwrap();
3999
4000 Self(vec![HashAlgorithm::default()], ka.key().clone())
4001 }
4002 }
4003
4004 #[test]
4005 fn overlapping_hashes() {
4006 let mut signature = vec![];
4007 let message = Message::new(&mut signature);
4008
4009 Signer::new(message, GoodSigner::default()).unwrap().build().unwrap();
4010 }
4011
4012 #[test]
4013 fn no_overlapping_hashes() {
4014 let mut signature = vec![];
4015 let message = Message::new(&mut signature);
4016
4017 if let Err(e) = Signer::new(message, BadSigner) {
4018 assert_eq!(e.downcast_ref::<Error>(), Some(&Error::NoAcceptableHash));
4019 } else {
4020 unreachable!();
4021 };
4022 }
4023
4024 #[test]
4025 fn no_overlapping_hashes_for_new_signer() {
4026 let mut signature = vec![];
4027 let message = Message::new(&mut signature);
4028
4029 let signer = Signer::new(message, GoodSigner::default()).unwrap();
4030 if let Err(e) = signer.add_signer(BadSigner) {
4031 assert_eq!(e.downcast_ref::<Error>(), Some(&Error::NoAcceptableHash));
4032 } else {
4033 unreachable!();
4034 };
4035 }
4036
4037 /// Tests that multiple signatures are in the correct order.
4038 #[test]
4039 fn issue_816() -> Result<()> {
4040 use crate::{
4041 packet::key::{Key4, PrimaryRole},
4042 types::Curve,
4043 KeyHandle,
4044 };
4045
4046 let signer_a =
4047 Key4::<_, PrimaryRole>::generate_ecc(true, Curve::Ed25519)?
4048 .into_keypair()?;
4049
4050 let signer_b =
4051 Key4::<_, PrimaryRole>::generate_ecc(true, Curve::Ed25519)?
4052 .into_keypair()?;
4053
4054 let mut sink = Vec::new();
4055 let message = Message::new(&mut sink);
4056 let message = Signer::new(message, signer_a)?
4057 .add_signer(signer_b)?
4058 .build()?;
4059 let mut message = LiteralWriter::new(message).build()?;
4060 message.write_all(b"Make it so, number one!")?;
4061 message.finalize()?;
4062
4063 let pp = crate::PacketPile::from_bytes(&sink)?;
4064 assert_eq!(pp.children().count(), 5);
4065
4066 let first_signer: KeyHandle =
4067 if let Packet::OnePassSig(ops) = pp.path_ref(&[0]).unwrap() {
4068 ops.issuer().into()
4069 } else {
4070 panic!("expected ops packet")
4071 };
4072
4073 let second_signer: KeyHandle =
4074 if let Packet::OnePassSig(ops) = pp.path_ref(&[1]).unwrap() {
4075 ops.issuer().into()
4076 } else {
4077 panic!("expected ops packet")
4078 };
4079
4080 assert!(matches!(pp.path_ref(&[2]).unwrap(), Packet::Literal(_)));
4081
4082 // OPS and Signature packets "bracket" the literal, i.e. the
4083 // last occurring ops packet is met by the first occurring
4084 // signature packet.
4085 if let Packet::Signature(sig) = pp.path_ref(&[3]).unwrap() {
4086 assert!(sig.get_issuers()[0].aliases(&second_signer));
4087 } else {
4088 panic!("expected sig packet")
4089 }
4090
4091 if let Packet::Signature(sig) = pp.path_ref(&[4]).unwrap() {
4092 assert!(sig.get_issuers()[0].aliases(&first_signer));
4093 } else {
4094 panic!("expected sig packet")
4095 }
4096
4097 Ok(())
4098 }
4099
4100 // Example copied from `Encryptor::aead_algo` and slightly
4101 // adjusted since the doctest from `Encryptor::aead_algo` does not
4102 // run. Additionally this test case utilizes
4103 // `AEADAlgorithm::const_default` to detect which algorithm to
4104 // use.
4105 #[test]
4106 fn experimental_aead_encryptor() -> Result<()> {
4107 use std::io::Write;
4108 use crate::types::AEADAlgorithm;
4109 use crate::policy::NullPolicy;
4110 use crate::serialize::stream::{
4111 Message, Encryptor, LiteralWriter,
4112 };
4113 use crate::parse::stream::{
4114 DecryptorBuilder, VerificationHelper,
4115 DecryptionHelper, MessageStructure,
4116 };
4117
4118 let mut sink = vec![];
4119 let message = Message::new(&mut sink);
4120 let message =
4121 Encryptor::with_passwords(message, Some("совершенно секретно"))
4122 .aead_algo(AEADAlgorithm::const_default())
4123 .build()?;
4124 let mut message = LiteralWriter::new(message).build()?;
4125 message.write_all(b"Hello world.")?;
4126 message.finalize()?;
4127
4128 struct Helper;
4129
4130 impl VerificationHelper for Helper {
4131 fn get_certs(&mut self, _ids: &[crate::KeyHandle]) -> Result<Vec<Cert>> where {
4132 Ok(Vec::new())
4133 }
4134
4135 fn check(&mut self, _structure: MessageStructure) -> Result<()> {
4136 Ok(())
4137 }
4138 }
4139
4140 impl DecryptionHelper for Helper {
4141 fn decrypt(&mut self, _: &[PKESK], skesks: &[SKESK],
4142 _sym_algo: Option<SymmetricAlgorithm>,
4143 decrypt: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
4144 -> Result<Option<Cert>>
4145 {
4146 skesks[0].decrypt(&"совершенно секретно".into())
4147 .map(|(algo, session_key)| decrypt(algo, &session_key))?;
4148 Ok(None)
4149 }
4150 }
4151
4152 let p = unsafe { &NullPolicy::new() };
4153 let mut v = DecryptorBuilder::from_bytes(&sink)?.with_policy(p, None, Helper)?;
4154 let mut content = vec![];
4155 v.read_to_end(&mut content)?;
4156 assert_eq!(content, b"Hello world.");
4157 Ok(())
4158 }
4159
4160 /// Signs using our set of public keys.
4161 #[test]
4162 fn signer() -> Result<()> {
4163 use crate::policy::StandardPolicy;
4164 use crate::parse::stream::{
4165 VerifierBuilder,
4166 test::VHelper,
4167 };
4168
4169 let p = StandardPolicy::new();
4170 for alg in &[
4171 "rsa", "dsa",
4172 "nistp256", "nistp384", "nistp521",
4173 "brainpoolP256r1", "brainpoolP384r1", "brainpoolP512r1",
4174 "secp256k1",
4175 ] {
4176 eprintln!("Test vector {:?}...", alg);
4177 let key = Cert::from_bytes(crate::tests::key(
4178 &format!("signing/{}.gpg", alg)))?;
4179 if let Some(k) = key.with_policy(&p, None).ok()
4180 .and_then(|vcert| vcert.keys().for_signing().supported().next())
4181 {
4182 use crate::crypto::mpi::PublicKey;
4183 match k.key().mpis() {
4184 PublicKey::ECDSA { curve, .. } |
4185 PublicKey::EdDSA { curve, .. }
4186 if ! curve.is_supported() => {
4187 eprintln!("Skipping {} because we don't support \
4188 the curve {}", alg, curve);
4189 continue;
4190 },
4191 _ => (),
4192 }
4193 } else {
4194 eprintln!("Skipping {} because we don't support the algorithm",
4195 alg);
4196 continue;
4197 }
4198
4199 let signing_keypair = key.keys().secret()
4200 .with_policy(&p, None).supported()
4201 .alive().revoked(false).for_signing()
4202 .nth(0).unwrap()
4203 .key().clone().into_keypair()?;
4204
4205 let mut sink = vec![];
4206 let message = Message::new(&mut sink);
4207 let message = Signer::new(message, signing_keypair)?
4208 .build()?;
4209 let mut message = LiteralWriter::new(message).build()?;
4210 message.write_all(b"Hello world.")?;
4211 message.finalize()?;
4212
4213 let h = VHelper::new(1, 0, 0, 0, vec![key]);
4214 let mut d = VerifierBuilder::from_bytes(&sink)?
4215 .with_policy(&p, None, h)?;
4216 assert!(d.message_processed());
4217
4218 let mut content = Vec::new();
4219 d.read_to_end(&mut content).unwrap();
4220 assert_eq!(&b"Hello world."[..], &content[..]);
4221 }
4222
4223 Ok(())
4224 }
4225
4226 /// Encrypts using public key cryptography.
4227 #[test]
4228 fn pk_encryptor() -> Result<()> {
4229 use crate::policy::StandardPolicy;
4230 use crate::parse::stream::{
4231 DecryptorBuilder,
4232 test::VHelper,
4233 };
4234
4235 let p = StandardPolicy::new();
4236 for path in [
4237 "rsa", "elg", "cv25519", "cv25519.unclamped",
4238 "nistp256", "nistp384", "nistp521",
4239 "brainpoolP256r1", "brainpoolP384r1", "brainpoolP512r1",
4240 "secp256k1",
4241 ].iter().map(|alg| format!("messages/encrypted/{}.sec.pgp", alg))
4242 .chain(vec![
4243 "crypto-refresh/v6-minimal-secret.key".into(),
4244 ].into_iter())
4245 {
4246 eprintln!("Test vector {:?}...", path);
4247 let key = Cert::from_bytes(crate::tests::file(&path))?;
4248 if let Some(k) =
4249 key.with_policy(&p, None)?.keys().subkeys().supported().next()
4250 {
4251 use crate::crypto::mpi::PublicKey;
4252 match k.key().mpis() {
4253 PublicKey::ECDH { curve, .. } if ! curve.is_supported() => {
4254 eprintln!("Skipping {} because we don't support \
4255 the curve {}", path, curve);
4256 continue;
4257 },
4258 _ => (),
4259 }
4260 } else {
4261 eprintln!("Skipping {} because we don't support the algorithm",
4262 path);
4263 continue;
4264 }
4265
4266 let recipients =
4267 key.with_policy(&p, None)?.keys().for_storage_encryption();
4268
4269 let mut sink = vec![];
4270 let message = Message::new(&mut sink);
4271 let message =
4272 Encryptor::for_recipients(message, recipients)
4273 .build()?;
4274 let mut message = LiteralWriter::new(message).build()?;
4275 message.write_all(b"Hello world.")?;
4276 message.finalize()?;
4277
4278 let h = VHelper::for_decryption(0, 0, 0, 0, Vec::new(),
4279 vec![key], Vec::new());
4280 let mut d = DecryptorBuilder::from_bytes(&sink)?
4281 .with_policy(&p, None, h)?;
4282 assert!(d.message_processed());
4283
4284 let mut content = Vec::new();
4285 d.read_to_end(&mut content).unwrap();
4286 assert_eq!(&b"Hello world."[..], &content[..]);
4287 }
4288
4289 Ok(())
4290 }
4291
4292 #[test]
4293 fn encryptor_lifetime()
4294 {
4295 // See https://gitlab.com/sequoia-pgp/sequoia/-/issues/1028
4296 //
4297 // Using Encryptor instead of Encryptor, we get the error:
4298 //
4299 // pub fn _encrypt_data<'a, B: AsRef<[u8]>, R>(data: B, recipients: R)
4300 // -- lifetime `'a` defined here
4301 //
4302 // let message = Message::new(&mut sink);
4303 // -------------^^^^^^^^^-
4304 // | |
4305 // | borrowed value does not live long enough
4306 // argument requires that `sink` is borrowed for `'a`
4307 //
4308 // }
4309 // - `sink` dropped here while still borrowed
4310 pub fn _encrypt_data<'a, B: AsRef<[u8]>, R>(data: B, recipients: R)
4311 -> anyhow::Result<Vec<u8>>
4312 where
4313 R: IntoIterator,
4314 R::Item: Into<Recipient<'a>>,
4315 {
4316 let mut sink = vec![];
4317 let message = Message::new(&mut sink);
4318 let armorer = Armorer::new(message).build()?;
4319 let encryptor = Encryptor::for_recipients(armorer, recipients).build()?;
4320 let mut writer = LiteralWriter::new(encryptor).build()?;
4321 writer.write_all(data.as_ref())?;
4322 writer.finalize()?;
4323
4324 Ok(sink)
4325 }
4326 }
4327
4328 /// Encrypts to a v4 and a v6 recipient using SEIPDv1.
4329 #[test]
4330 fn mixed_recipients_seipd1() -> Result<()> {
4331 let alice = CertBuilder::general_purpose(Some("alice"))
4332 .set_profile(Profile::RFC9580)?
4333 .generate()?.0;
4334 let bob = CertBuilder::general_purpose(Some("bob"))
4335 .set_profile(Profile::RFC4880)?
4336 .set_features(Features::empty().set_seipdv1())?
4337 .generate()?.0;
4338 mixed_recipients_intern(alice, bob, 1)
4339 }
4340
4341 /// Encrypts to a v4 and a v6 recipient using SEIPDv2.
4342 #[test]
4343 fn mixed_recipients_seipd2() -> Result<()> {
4344 let alice = CertBuilder::general_purpose(Some("alice"))
4345 .set_profile(Profile::RFC9580)?
4346 .generate()?.0;
4347 let bob = CertBuilder::general_purpose(Some("bob"))
4348 .set_profile(Profile::RFC4880)?
4349 .generate()?.0;
4350 mixed_recipients_intern(alice, bob, 2)
4351 }
4352
4353 fn mixed_recipients_intern(alice: Cert, bob: Cert, seipdv: u8)
4354 -> Result<()>
4355 {
4356 use crate::policy::StandardPolicy;
4357 use crate::parse::stream::{
4358 DecryptorBuilder,
4359 test::VHelper,
4360 };
4361
4362 let p = StandardPolicy::new();
4363 let recipients = [&alice, &bob].into_iter().flat_map(
4364 |c| c.keys().with_policy(&p, None).for_storage_encryption());
4365
4366 let mut sink = vec![];
4367 let message = Message::new(&mut sink);
4368 let message =
4369 Encryptor::for_recipients(message, recipients)
4370 .build()?;
4371 let mut message = LiteralWriter::new(message).build()?;
4372 message.write_all(b"Hello world.")?;
4373 message.finalize()?;
4374
4375 for key in [alice, bob] {
4376 eprintln!("Decrypting with key version {}",
4377 key.primary_key().key().version());
4378 let h = VHelper::for_decryption(0, 0, 0, 0, Vec::new(),
4379 vec![key], Vec::new());
4380 let mut d = DecryptorBuilder::from_bytes(&sink)?
4381 .with_policy(&p, None, h)?;
4382 assert!(d.message_processed());
4383
4384 let mut content = Vec::new();
4385 d.read_to_end(&mut content).unwrap();
4386 assert_eq!(&b"Hello world."[..], &content[..]);
4387
4388 use Packet::*;
4389 match seipdv {
4390 1 => d.helper_ref().packets.iter().for_each(
4391 |p| match p {
4392 PKESK(p) => assert_eq!(p.version(), 3),
4393 SKESK(p) => assert_eq!(p.version(), 4),
4394 SEIP(p) => assert_eq!(p.version(), 1),
4395 _ => (),
4396 }),
4397
4398 2 => d.helper_ref().packets.iter().for_each(
4399 |p| match p {
4400 PKESK(p) => assert_eq!(p.version(), 6),
4401 SKESK(p) => assert_eq!(p.version(), 6),
4402 SEIP(p) => assert_eq!(p.version(), 2),
4403 _ => (),
4404 }),
4405
4406 _ => unreachable!(),
4407 }
4408 }
4409
4410 Ok(())
4411 }
4412}