summaryrefslogtreecommitdiffstats
path: root/openpgp/src/serialize/stream.rs
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-10-22 16:29:33 +0200
committerJustus Winter <justus@sequoia-pgp.org>2020-10-22 16:43:51 +0200
commitc677bae2a7d0875c430eb641ec7601398ced9b14 (patch)
tree138ee348861d82b6a355b24186e803dad7b73bb9 /openpgp/src/serialize/stream.rs
parent5ff30d8ed398fc6c3e973773043c8211214db63c (diff)
openpgp: Improve documentation on how to encrypt for multiple certs.
Diffstat (limited to 'openpgp/src/serialize/stream.rs')
-rw-r--r--openpgp/src/serialize/stream.rs61
1 files changed, 61 insertions, 0 deletions
diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs
index 0cd1902a..422e0382 100644
--- a/openpgp/src/serialize/stream.rs
+++ b/openpgp/src/serialize/stream.rs
@@ -2005,6 +2005,67 @@ impl<'a> Recipient<'a> {
/// The stream will be encrypted using a generated session key, which
/// will be encrypted using the given passwords, and for all given
/// recipients.
+///
+/// An [`Recipient`] is an encryption-capable (sub)key. Note that a
+/// certificate may have more than one encryption-capable subkey, and
+/// even the primary key may be encryption-capable.
+///
+/// [`Recipient`]: struct.Recipient.html
+///
+/// To encrypt for more than one certificate, iterate over the
+/// certificates and select encryption-capable keys, making sure that
+/// at least one key is selected from each certificate.
+///
+/// # Examples
+///
+/// This demonstrates encrypting for multiple certificates.
+///
+/// ```
+/// # fn main() -> sequoia_openpgp::Result<()> {
+/// # use std::io::Write;
+/// # use sequoia_openpgp as openpgp;
+/// # use openpgp::cert::prelude::*;
+/// # use openpgp::parse::Parse;
+/// use openpgp::serialize::stream::{
+/// Message, Encryptor, LiteralWriter,
+/// };
+/// use openpgp::policy::StandardPolicy;
+/// let p = &StandardPolicy::new();
+///
+/// # let (cert_0, _) =
+/// # CertBuilder::general_purpose(None, Some("Mr. Pink ☮☮☮"))
+/// # .generate()?;
+/// # let (cert_1, _) =
+/// # CertBuilder::general_purpose(None, Some("Mr. Pink ☮☮☮"))
+/// # .generate()?;
+/// let recipient_certs = vec![cert_0, cert_1];
+/// let mut recipients = Vec::new();
+/// for cert in recipient_certs.iter() {
+/// // Make sure we add at least one subkey from every
+/// // certificate.
+/// let mut found_one = false;
+/// for key in cert.keys().with_policy(p, None)
+/// .supported().alive().revoked(false).for_transport_encryption()
+/// {
+/// recipients.push(key);
+/// found_one = true;
+/// }
+///
+/// if ! found_one {
+/// return Err(anyhow::anyhow!("No suitable encryption subkey for {}",
+/// cert));
+/// }
+/// }
+/// # assert_eq!(recipients.len(), 2);
+///
+/// # let mut sink = vec![];
+/// let message = Message::new(&mut sink);
+/// let message = Encryptor::for_recipients(message, recipients).build()?;
+/// let mut w = LiteralWriter::new(message).build()?;
+/// w.write_all(b"Hello world.")?;
+/// w.finalize()?;
+/// # Ok(()) }
+/// ```
pub struct Encryptor<'a> {
// XXX: Opportunity for optimization. Previously, this writer
// implemented `Drop`, so we could not move the inner writer out