From 38a4d2b4ff4fc4512b31a4ff4e4ddd8a6b3c7503 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Fri, 6 Sep 2019 13:47:50 +0200 Subject: openpgp: Rework streaming encryptor. - Instead of giving a set of TPKs to the encryptor, hand in a set of recipients, which are (keyid, key)-tuples, conveniently created from key queries over TPKs. This simplifies the encryptor, and makes the key selection explicit. - Drop the EncryptionMode type. - As a nice side effect, we can now generate encrypted messages with wildcard recipient addresses. --- tool/src/commands/mod.rs | 23 +++++++++++++++++++---- tool/src/sq-usage.rs | 4 ++++ tool/src/sq.rs | 12 ++++++++++++ tool/src/sq_cli.rs | 10 ++++++++++ 4 files changed, 45 insertions(+), 4 deletions(-) (limited to 'tool') diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs index 0db911ce..2fc31b6a 100644 --- a/tool/src/commands/mod.rs +++ b/tool/src/commands/mod.rs @@ -24,7 +24,7 @@ use crate::openpgp::parse::stream::{ MessageStructure, MessageLayer, }; use crate::openpgp::serialize::stream::{ - Message, Signer, LiteralWriter, Encryptor, EncryptionMode, + Message, Signer, LiteralWriter, Encryptor, Recipient, Compressor, }; use crate::openpgp::serialize::padding::{ @@ -89,6 +89,7 @@ pub fn encrypt(store: &mut store::Store, input: &mut io::Read, output: &mut io::Write, npasswords: usize, recipients: Vec<&str>, mut tpks: Vec, signers: Vec, + mode: KeyFlags, compression: &str) -> Result<()> { for r in recipients { @@ -107,8 +108,23 @@ pub fn encrypt(store: &mut store::Store, let mut signers = get_signing_keys(&signers)?; - // Build a vector of references to hand to Encryptor. + // Build a vector of references to hand to Signer. let recipients: Vec<&openpgp::TPK> = tpks.iter().collect(); + + // Build a vector of recipients to hand to Encryptor. + let mut recipient_subkeys: Vec = Vec::new(); + for tpk in tpks.iter() { + let mut count = 0; + for (_, _, key) in tpk.keys_valid().key_flags(mode.clone()) { + recipient_subkeys.push(key.into()); + count += 1; + } + if count == 0 { + return Err(failure::format_err!( + "Key {} has no suitable encryption key", tpk)); + } + } + let passwords_: Vec<&openpgp::crypto::Password> = passwords.iter().collect(); @@ -118,8 +134,7 @@ pub fn encrypt(store: &mut store::Store, // We want to encrypt a literal data packet. let mut sink = Encryptor::new(message, &passwords_, - &recipients, - EncryptionMode::AtRest, + recipient_subkeys, None, None) .context("Failed to create encryptor")?; diff --git a/tool/src/sq-usage.rs b/tool/src/sq-usage.rs index c5580112..e06ea6b5 100644 --- a/tool/src/sq-usage.rs +++ b/tool/src/sq-usage.rs @@ -78,6 +78,10 @@ //! OPTIONS: //! --compression Selects compression scheme to use [default: pad] [possible values: none, //! pad, zip, zlib, bzip2] +//! --mode Selects what kind of keys are considered for encryption. Transport select +//! subkeys marked as suitable for transport encryption, rest selects those +//! for encrypting data at rest, and all selects all encryption-capable +//! subkeys [default: all] [possible values: transport, rest, all] //! -o, --output Sets the output file to use //! -r, --recipient