summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--guide/src/chapter_02.md48
-rw-r--r--ipc/tests/gpg-agent.rs11
-rw-r--r--openpgp-ffi/src/serialize.rs34
-rw-r--r--openpgp/examples/encrypt-for.rs14
-rw-r--r--openpgp/examples/generate-encrypt-decrypt.rs12
-rw-r--r--openpgp/examples/pad.rs13
-rw-r--r--openpgp/src/autocrypt.rs5
-rw-r--r--openpgp/src/serialize/stream.rs229
-rw-r--r--tool/src/commands/mod.rs22
9 files changed, 243 insertions, 145 deletions
diff --git a/guide/src/chapter_02.md b/guide/src/chapter_02.md
index d00fa669..acc2cb2e 100644
--- a/guide/src/chapter_02.md
+++ b/guide/src/chapter_02.md
@@ -50,7 +50,7 @@ fn main() {
# fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::TPK)
# -> openpgp::Result<()> {
# // Build a vector of recipients to hand to Encryptor.
-# let recipients =
+# let mut recipients =
# recipient.keys_valid()
# .key_flags(KeyFlags::default()
# .set_encrypt_at_rest(true)
@@ -62,10 +62,12 @@ fn main() {
# let message = Message::new(sink);
#
# // We want to encrypt a literal data packet.
-# let encryptor = Encryptor::new(message,
-# &[], // No symmetric encryption.
-# &recipients,
-# None, None)?;
+# let mut encryptor = Encryptor::for_recipient(
+# message, recipients.pop().expect("No encryption key found"));
+# for r in recipients {
+# encryptor = encryptor.add_recipient(r)
+# }
+# let encryptor = encryptor.build().expect("Failed to create encryptor");
#
# // Emit a literal data packet.
# let mut literal_writer = LiteralWriter::new(encryptor).build()?;
@@ -191,7 +193,7 @@ fn generate() -> openpgp::Result<openpgp::TPK> {
# fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::TPK)
# -> openpgp::Result<()> {
# // Build a vector of recipients to hand to Encryptor.
-# let recipients =
+# let mut recipients =
# recipient.keys_valid()
# .key_flags(KeyFlags::default()
# .set_encrypt_at_rest(true)
@@ -203,10 +205,12 @@ fn generate() -> openpgp::Result<openpgp::TPK> {
# let message = Message::new(sink);
#
# // We want to encrypt a literal data packet.
-# let encryptor = Encryptor::new(message,
-# &[], // No symmetric encryption.
-# &recipients,
-# None, None)?;
+# let mut encryptor = Encryptor::for_recipient(
+# message, recipients.pop().expect("No encryption key found"));
+# for r in recipients {
+# encryptor = encryptor.add_recipient(r)
+# }
+# let encryptor = encryptor.build().expect("Failed to create encryptor");
#
# // Emit a literal data packet.
# let mut literal_writer = LiteralWriter::new(encryptor).build()?;
@@ -332,7 +336,7 @@ implements [`io::Write`], and we simply write the plaintext to it.
fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::TPK)
-> openpgp::Result<()> {
// Build a vector of recipients to hand to Encryptor.
- let recipients =
+ let mut recipients =
recipient.keys_valid()
.key_flags(KeyFlags::default()
.set_encrypt_at_rest(true)
@@ -344,10 +348,12 @@ fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::TPK)
let message = Message::new(sink);
// We want to encrypt a literal data packet.
- let encryptor = Encryptor::new(message,
- &[], // No symmetric encryption.
- &recipients,
- None, None)?;
+ let mut encryptor = Encryptor::for_recipient(
+ message, recipients.pop().expect("No encryption key found"));
+ for r in recipients {
+ encryptor = encryptor.add_recipient(r)
+ }
+ let encryptor = encryptor.build().expect("Failed to create encryptor");
// Emit a literal data packet.
let mut literal_writer = LiteralWriter::new(encryptor).build()?;
@@ -487,7 +493,7 @@ Decrypted data can be read from this using [`io::Read`].
# fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::TPK)
# -> openpgp::Result<()> {
# // Build a vector of recipients to hand to Encryptor.
-# let recipients =
+# let mut recipients =
# recipient.keys_valid()
# .key_flags(KeyFlags::default()
# .set_encrypt_at_rest(true)
@@ -499,10 +505,12 @@ Decrypted data can be read from this using [`io::Read`].
# let message = Message::new(sink);
#
# // We want to encrypt a literal data packet.
-# let encryptor = Encryptor::new(message,
-# &[], // No symmetric encryption.
-# &recipients,
-# None, None)?;
+# let mut encryptor = Encryptor::for_recipient(
+# message, recipients.pop().expect("No encryption key found"));
+# for r in recipients {
+# encryptor = encryptor.add_recipient(r)
+# }
+# let encryptor = encryptor.build().expect("Failed to create encryptor");
#
# // Emit a literal data packet.
# let mut literal_writer = LiteralWriter::new(encryptor).build()?;
diff --git a/ipc/tests/gpg-agent.rs b/ipc/tests/gpg-agent.rs
index 2dd5bb2b..01adcc6f 100644
--- a/ipc/tests/gpg-agent.rs
+++ b/ipc/tests/gpg-agent.rs
@@ -207,21 +207,18 @@ fn decrypt() {
let mut message = Vec::new();
{
- // Build a vector of recipients to hand to Encryptor.
- let recipients =
+ let recipient =
tpk.keys_valid().key_flags(
KeyFlags::default().set_encrypt_for_transport(true))
.map(|(_, _, key)| key.into())
- .collect::<Vec<Recipient>>();
+ .nth(0).unwrap();
// Start streaming an OpenPGP message.
let message = Message::new(&mut message);
// We want to encrypt a literal data packet.
- let encryptor = Encryptor::new(message,
- &[], // No symmetric encryption.
- recipients,
- None, None).unwrap();
+ let encryptor =
+ Encryptor::for_recipient(message, recipient).build().unwrap();
// Emit a literal data packet.
let mut literal_writer = LiteralWriter::new(
diff --git a/openpgp-ffi/src/serialize.rs b/openpgp-ffi/src/serialize.rs
index 7046b667..d5d7afa6 100644
--- a/openpgp-ffi/src/serialize.rs
+++ b/openpgp-ffi/src/serialize.rs
@@ -309,6 +309,8 @@ fn pgp_recipients_from_key_iter<'a>(
/// which will be encrypted using the given passwords, and all
/// encryption-capable subkeys of the given TPKs.
///
+/// The recipients are consumed.
+///
/// The stream is encrypted using `cipher_algo`. Pass 0 for the
/// default (which is what you usually want).
#[::sequoia_ffi_macros::extern_fn] #[no_mangle]
@@ -316,7 +318,7 @@ pub extern "C" fn pgp_encryptor_new<'a>
(errp: Option<&mut *mut crate::error::Error>,
inner: *mut writer::Stack<'a, Cookie>,
passwords: Option<&*const c_char>, passwords_len: size_t,
- recipients: Option<&*const Recipient<'a>>, recipients_len: size_t,
+ recipients: Option<&*mut Recipient<'a>>, recipients_len: size_t,
cipher_algo: u8,
aead_algo: u8)
-> *mut writer::Stack<'a, Cookie>
@@ -341,7 +343,7 @@ pub extern "C" fn pgp_encryptor_new<'a>
slice::from_raw_parts(recipients, recipients_len)
};
for recipient in recipients {
- recipients_.push(recipient.ref_raw());
+ recipients_.push(recipient.move_from_raw());
}
};
let cipher_algo : Option<SymmetricAlgorithm> = if cipher_algo == 0 {
@@ -354,9 +356,27 @@ pub extern "C" fn pgp_encryptor_new<'a>
} else {
Some(aead_algo.into())
};
- ffi_try_box!(Encryptor::new(*inner,
- passwords_.iter().collect::<Vec<_>>(),
- recipients_,
- cipher_algo,
- aead_algo))
+ if passwords_.len() + recipients_.len() == 0 {
+ ffi_try!(Err(failure::format_err!(
+ "Neither recipient nor password given")));
+ }
+
+ let mut encryptor = if let Some(p) = passwords_.pop() {
+ Encryptor::with_password(*inner, p)
+ } else {
+ Encryptor::for_recipient(*inner, recipients_.pop().unwrap())
+ };
+ for p in passwords_ {
+ encryptor = encryptor.add_password(p);
+ }
+ for r in recipients_ {
+ encryptor = encryptor.add_recipient(r);
+ }
+ if let Some(algo) = cipher_algo {
+ encryptor = encryptor.sym_algo(algo);
+ }
+ if let Some(algo) = aead_algo {
+ encryptor = encryptor.aead_algo(algo);
+ }
+ ffi_try_box!(encryptor.build())
}
diff --git a/openpgp/examples/encrypt-for.rs b/openpgp/examples/encrypt-for.rs
index 3076c7a4..82f636d9 100644
--- a/openpgp/examples/encrypt-for.rs
+++ b/openpgp/examples/encrypt-for.rs
@@ -35,7 +35,7 @@ fn main() {
}).collect();
// Build a vector of recipients to hand to Encryptor.
- let recipients =
+ let mut recipients =
tpks.iter()
.flat_map(|tpk| tpk.keys_valid().key_flags(mode.clone()))
.map(|(_, _, key)| key.into())
@@ -51,11 +51,13 @@ fn main() {
let message = Message::new(sink);
// We want to encrypt a literal data packet.
- let encryptor = Encryptor::new(message,
- &[], // No symmetric encryption.
- &recipients,
- None, None)
- .expect("Failed to create encryptor");
+ let mut encryptor = Encryptor::for_recipient(
+ message, recipients.pop().expect("No encryption key found"));
+ for r in recipients {
+ encryptor = encryptor.add_recipient(r)
+ }
+ let encryptor = encryptor.build().expect("Failed to create encryptor");
+
let mut literal_writer = LiteralWriter::new(encryptor).build()
.expect("Failed to create literal writer");
diff --git a/openpgp/examples/generate-encrypt-decrypt.rs b/openpgp/examples/generate-encrypt-decrypt.rs
index f8eeb05f..d20219ab 100644
--- a/openpgp/examples/generate-encrypt-decrypt.rs
+++ b/openpgp/examples/generate-encrypt-decrypt.rs
@@ -41,7 +41,7 @@ fn generate() -> openpgp::Result<openpgp::TPK> {
fn encrypt(sink: &mut dyn Write, plaintext: &str, recipient: &openpgp::TPK)
-> openpgp::Result<()> {
// Build a vector of recipients to hand to Encryptor.
- let recipients =
+ let mut recipients =
recipient.keys_valid()
.key_flags(KeyFlags::default()
.set_encrypt_at_rest(true)
@@ -53,10 +53,12 @@ fn encrypt(sink: &mut dyn Write, plaintext: &str, recipient: &openpgp::TPK)
let message = Message::new(sink);
// We want to encrypt a literal data packet.
- let encryptor = Encryptor::new(message,
- &[], // No symmetric encryption.
- &recipients,
- None, None)?;
+ let mut encryptor = Encryptor::for_recipient(
+ message, recipients.pop().expect("No encryption key found"));
+ for r in recipients {
+ encryptor = encryptor.add_recipient(r)
+ }
+ let encryptor = encryptor.build().expect("Failed to create encryptor");
// Emit a literal data packet.
let mut literal_writer = LiteralWriter::new(encryptor).build()?;
diff --git a/openpgp/examples/pad.rs b/openpgp/examples/pad.rs
index 76d4ebc0..6a3d7c96 100644
--- a/openpgp/examples/pad.rs
+++ b/openpgp/examples/pad.rs
@@ -37,7 +37,7 @@ fn main() {
}).collect();
// Build a vector of recipients to hand to Encryptor.
- let recipients =
+ let mut recipients =
tpks.iter()
.flat_map(|tpk| tpk.keys_valid().key_flags(mode.clone()))
.map(|(_, _, key)| Recipient::new(KeyID::wildcard(), key))
@@ -53,11 +53,12 @@ fn main() {
let message = Message::new(sink);
// We want to encrypt a literal data packet.
- let encryptor = Encryptor::new(message,
- &[], // No symmetric encryption.
- &recipients,
- None, None)
- .expect("Failed to create encryptor");
+ let mut encryptor = Encryptor::for_recipient(
+ message, recipients.pop().expect("No encryption key found"));
+ for r in recipients {
+ encryptor = encryptor.add_recipient(r)
+ }
+ let encryptor = encryptor.build().expect("Failed to create encryptor");
let padder = Padder::new(encryptor, padme)
.expect("Failed to create padder");
diff --git a/openpgp/src/autocrypt.rs b/openpgp/src/autocrypt.rs
index 4f7596bb..d283ca1d 100644
--- a/openpgp/src/autocrypt.rs
+++ b/openpgp/src/autocrypt.rs
@@ -467,9 +467,8 @@ impl AutocryptSetupMessage {
// Passphrase-Format header with value numeric9x4
let m = Message::new(w);
- let w = Encryptor::new(m,
- vec![ self.passcode.as_ref().unwrap() ],
- &[], None, None)?;
+ let w = Encryptor::with_password(m, self.passcode.clone().unwrap())
+ .build()?;
let mut w = LiteralWriter::new(w).build()?;
diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs
index 50313108..22f7e44c 100644
--- a/openpgp/src/serialize/stream.rs
+++ b/openpgp/src/serialize/stream.rs
@@ -9,7 +9,6 @@
//!
//! [encryption example]: struct.Encryptor.html#example
-use std::borrow::Borrow;
use std::fmt;
use std::io::{self, Write};
use time;
@@ -910,6 +909,10 @@ impl<'a> Recipient<'a> {
/// Encrypts a packet stream.
pub struct Encryptor<'a> {
inner: Option<writer::BoxStack<'a, Cookie>>,
+ recipients: Vec<Recipient<'a>>,
+ passwords: Vec<Password>,
+ sym_algo: SymmetricAlgorithm,
+ aead_algo: Option<AEADAlgorithm>,
hash: crypto::hash::Context,
cookie: Cookie,
}
@@ -979,46 +982,109 @@ impl<'a> Encryptor<'a> {
/// ).unwrap();
///
/// // Build a vector of recipients to hand to Encryptor.
- /// let recipients =
+ /// let recipient =
/// tpk.keys_valid()
/// .key_flags(KeyFlags::default()
/// .set_encrypt_at_rest(true)
/// .set_encrypt_for_transport(true))
/// .map(|(_, _, key)| key.into())
- /// .collect::<Vec<_>>();
+ /// .nth(0).unwrap();
///
/// let mut o = vec![];
/// let message = Message::new(&mut o);
- /// let encryptor = Encryptor::new(message,
- /// &["совершенно секретно".into()],
- /// &recipients, None, None)
- /// .expect("Failed to create encryptor");
+ /// let encryptor =
+ /// Encryptor::for_recipient(message, recipient)
+ /// .build().expect("Failed to create encryptor");
/// let mut w = LiteralWriter::new(encryptor).build()?;
/// w.write_all(b"Hello world.")?;
/// w.finalize()?;
/// # Ok(())
/// # }
/// ```
- pub fn new<'r, P, R, C, A>(inner: writer::Stack<'a, Cookie>,
- passwords: P, recipients: R,
- cipher_algo: C, aead_algo: A)
- -> Result<writer::Stack<'a, Cookie>>
- where P: IntoIterator,
- P::Item: Borrow<Password>,
- R: IntoIterator,
- R::Item: Borrow<Recipient<'r>>,
- C: Into<Option<SymmetricAlgorithm>>,
- A: Into<Option<AEADAlgorithm>>,
- {
- let passwords = passwords.into_iter().collect::<Vec<_>>();
- let passwords_ref = passwords.iter().map(|r| r.borrow()).collect();
- let recipients = recipients.into_iter().collect::<Vec<_>>();
- let recipients_ref = recipients.iter().map(|r| r.borrow()).collect();
- Self::make(inner,
- passwords_ref,
- recipients_ref,
- cipher_algo.into().unwrap_or_default(),
- aead_algo.into())
+ pub fn for_recipient(inner: writer::Stack<'a, Cookie>,
+ recipient: Recipient<'a>) -> Self {
+ Self {
+ inner: Some(inner.into()),
+ recipients: vec![recipient],
+ passwords: Vec::new(),
+ sym_algo: Default::default(),
+ aead_algo: Default::default(),
+ hash: HashAlgorithm::SHA1.context().unwrap(),
+ cookie: Default::default(), // Will be fixed in build.
+ }
+ }
+
+ /// Creates a new encryptor.
+ ///
+ /// The stream will be encrypted using a generated session key,
+ /// which will be encrypted using the given passwords, and all
+ /// encryption-capable subkeys of the given TPKs.
+ ///
+ /// Unless otherwise specified, the stream is encrypted using
+ /// AES256. If `aead_algo` is `None`, a `SEIP` packet is emitted,
+ /// otherwise the given AEAD algorithm is used.
+ ///
+ /// Key preferences of the recipients are not honored.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::io::Write;
+ /// extern crate sequoia_openpgp as openpgp;
+ /// use openpgp::constants::KeyFlags;
+ /// use openpgp::serialize::stream::{
+ /// Message, Encryptor, LiteralWriter,
+ /// };
+ /// # use openpgp::Result;
+ /// # use openpgp::parse::Parse;
+ /// # fn main() { f().unwrap(); }
+ /// # fn f() -> Result<()> {
+ /// let mut o = vec![];
+ /// let message = Message::new(&mut o);
+ /// let encryptor =
+ /// Encryptor::with_password(message, "совершенно секретно".into())
+ /// .build().expect("Failed to create encryptor");
+ /// let mut w = LiteralWriter::new(encryptor).build()?;
+ /// w.write_all(b"Hello world.")?;
+ /// w.finalize()?;
+ /// # Ok(())
+ /// # }
+ /// ```
+ pub fn with_password(inner: writer::Stack<'a, Cookie>,
+ password: Password) -> Self {
+ Self {
+ inner: Some(inner.into()),
+ recipients: Vec::new(),
+ passwords: vec![password],
+ sym_algo: Default::default(),
+ aead_algo: Default::default(),
+ hash: HashAlgorithm::SHA1.context().unwrap(),
+ cookie: Default::default(), // Will be fixed in build.
+ }
+ }
+
+ /// Adds a recipient.
+ pub fn add_recipient(mut self, recipient: Recipient<'a>) -> Self {
+ self.recipients.push(recipient);
+ self
+ }
+
+ /// Adds a password.
+ pub fn add_password(mut self, password: Password) -> Self {
+ self.passwords.push(password);
+ self
+ }
+
+ /// Sets the symmetric algorithm to use.
+ pub fn sym_algo(mut self, algo: SymmetricAlgorithm) -> Self {
+ self.sym_algo = algo;
+ self
+ }
+
+ /// Enables AEAD and sets the AEAD algorithm to use.
+ pub fn aead_algo(mut self, algo: AEADAlgorithm) -> Self {
+ self.aead_algo = Some(algo);
+ self
}
// The default chunk size.
@@ -1026,17 +1092,10 @@ impl<'a> Encryptor<'a> {
// A page, 3 per mille overhead.
const AEAD_CHUNK_SIZE : usize = 4096;
- fn make(mut inner: writer::Stack<'a, Cookie>,
- passwords: Vec<&Password>,
- recipients: Vec<&Recipient>,
- algo: SymmetricAlgorithm,
- aead_algo: Option<AEADAlgorithm>)
- -> Result<writer::Stack<'a, Cookie>>
- {
- if recipients.len() + passwords.len() == 0 {
- return Err(Error::InvalidArgument(
- "Neither recipient keys nor passwords given".into()).into());
- }
+ /// Finalizes the encryptor, returning the writer stack.
+ pub fn build(mut self) -> Result<writer::Stack<'a, Cookie>> {
+ assert!(self.recipients.len() + self.passwords.len() > 0,
+ "The constructors add at least one recipient or password");
struct AEADParameters {
algo: AEADAlgorithm,
@@ -1044,7 +1103,7 @@ impl<'a> Encryptor<'a> {
nonce: Box<[u8]>,
}
- let aead = if let Some(algo) = aead_algo {
+ let aead = if let Some(algo) = self.aead_algo {
let mut nonce = vec![0; algo.iv_size()?];
crypto::random(&mut nonce);
Some(AEADParameters {
@@ -1056,38 +1115,41 @@ impl<'a> Encryptor<'a> {
None
};
+ let mut inner = self.inner.take().expect("Added in constructors");
let level = inner.as_ref().cookie_ref().level + 1;
// Generate a session key.
- let sk = SessionKey::new(algo.key_size()?);
+ let sk = SessionKey::new(self.sym_algo.key_size()?);
// Write the PKESK packet(s).
- for recipient in recipients {
- let recipient = recipient.borrow();
- let mut pkesk = PKESK3::for_recipient(algo, &sk, recipient.key)?;
+ for recipient in self.recipients.iter() {
+ let mut pkesk =
+ PKESK3::for_recipient(self.sym_algo, &sk, recipient.key)?;
pkesk.set_recipient(recipient.keyid.clone());
Packet::PKESK(pkesk.into()).serialize(&mut inner)?;
}
// Write the SKESK packet(s).
- for password in passwords {
+ for password in self.passwords.iter() {
if let Some(aead) = aead.as_ref() {
- let skesk = SKESK5::with_password(algo, aead.algo,
+ let skesk = SKESK5::with_password(self.sym_algo, aead.algo,
Default::default(),
&sk, password).unwrap();
Packet::SKESK(skesk.into()).serialize(&mut inner)?;
} else {
- let skesk = SKESK4::with_password(algo, Default::default(),
+ let skesk = SKESK4::with_password(self.sym_algo,
+ Default::default(),
&sk, password).unwrap();
Packet::SKESK(skesk.into()).serialize(&mut inner)?;
}
}
- let encryptor = if let Some(aead) = aead {
+ if let Some(aead) = aead {
// Write the AED packet.
CTB::new(Tag::AED).serialize(&mut inner)?;
- let mut inner = PartialBodyFilter::new(inner, Cookie::new(level));
- let aed = AED1::new(algo, aead.algo, aead.chunk_size, aead.nonce)?;
+ let mut inner = PartialBodyFilter::new(writer::Stack::from(inner),
+ Cookie::new(level));
+ let aed = AED1::new(self.sym_algo, aead.algo, aead.chunk_size, aead.nonce)?;
aed.serialize_headers(&mut inner)?;
writer::AEADEncryptor::new(
@@ -1098,38 +1160,34 @@ impl<'a> Encryptor<'a> {
aed.chunk_size(),
aed.iv(),
&sk,
- )?
+ )
} else {
// Write the SEIP packet.
CTB::new(Tag::SEIP).serialize(&mut inner)?;
- let mut inner = PartialBodyFilter::new(inner, Cookie::new(level));
+ let mut inner = PartialBodyFilter::new(writer::Stack::from(inner),
+ Cookie::new(level));
inner.write_all(&[1])?; // Version.
- let encryptor = writer::Encryptor::new(
+ // Install encryptor.
+ self.inner = Some(writer::Encryptor::new(
inner.into(),
Cookie::new(level),
- algo,
+ self.sym_algo,
&sk,
- )?;
-
- // The hash for the MDC must include the initialization
- // vector, hence we build the object here.
- let mut encryptor = writer::Stack::from(Box::new(Self{
- inner: Some(encryptor.into()),
- hash: HashAlgorithm::SHA1.context().unwrap(),
- cookie: Cookie::new(level),
- }));
-
- // Write the initialization vector, and the quick-check bytes.
- let mut iv = vec![0; algo.block_size()?];
+ )?.into());
+ self.cookie = Cookie::new(level);
+
+ // Write the initialization vector, and the quick-check
+ // bytes. The hash for the MDC must include the
+ // initialization vector, hence we must write this to
+ // self after installing the encryptor at self.inner.
+ let mut iv = vec![0; self.sym_algo.block_size()?];
crypto::random(&mut iv);
- encryptor.write_all(&iv)?;
- encryptor.write_all(&iv[iv.len() - 2..])?;
-
- encryptor
- };
+ self.write_all(&iv)?;
+ self.write_all(&iv[iv.len() - 2..])?;
- Ok(encryptor)
+ Ok(writer::Stack::from(Box::new(self)))
+ }
}
/// Emits the MDC packet and recovers the original writer.
@@ -1462,10 +1520,9 @@ mod test {
let mut o = vec![];
{
let m = Message::new(&mut o);
- let encryptor = Encryptor::new(
- m, &passwords,
- &[], None, None)
- .unwrap();
+ let encryptor = Encryptor::with_password(m, passwords[0].clone())
+ .add_password(passwords[1].clone())
+ .build().unwrap();
let mut literal = LiteralWriter::new(encryptor).build()
.unwrap();
literal.write_all(message).unwrap();
@@ -1599,15 +1656,6 @@ mod test {
.add_encryption_subkey()
.generate().unwrap();
- // Build a vector of recipients to hand to Encryptor.
- let recipients =
- tsk.keys_all()
- .key_flags(KeyFlags::default()
- .set_encrypt_at_rest(true)
- .set_encrypt_for_transport(true))
- .map(|(_, _, key)| key.into())
- .collect::<Vec<_>>();
-
struct Helper<'a> {
tsk: &'a TPK,
};
@@ -1651,9 +1699,16 @@ mod test {
let mut msg = vec![];
{
let m = Message::new(&mut msg);
- let encryptor = Encryptor::new(
- m, &[], &recipients, None, AEADAlgorithm::EAX)
- .unwrap();
+ let recipient =
+ tsk.keys_all()
+ .key_flags(KeyFlags::default()
+ .set_encrypt_at_rest(true)
+ .set_encrypt_for_transport(true))
+ .map(|(_, _, key)| key.into())
+ .nth(0).unwrap();
+ let encryptor = Encryptor::for_recipient(m, recipient)
+ .aead_algo(AEADAlgorithm::EAX)
+ .build().unwrap();
let mut literal = LiteralWriter::new(encryptor).build()
.unwrap();
literal.write_all(&content).unwrap();
diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs
index f164e3a2..4450c8d6 100644
--- a/tool/src/commands/mod.rs
+++ b/tool/src/commands/mod.rs
@@ -105,6 +105,11 @@ pub fn encrypt(mapping: &mut store::Mapping,
}))?.into());
}
+ if tpks.len() + passwords.len() == 0 {
+ return Err(failure::format_err!(
+ "Neither recipient nor password given"));
+ }
+
let mut signers = get_signing_keys(&signers)?;