diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-04-21 13:26:14 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-04-21 13:48:51 +0200 |
commit | 5ad22d3e48c70679b9da54223130734bef3d407b (patch) | |
tree | fcd9afe235d04e48ee999491744987e24fa5cfc6 /tool/src | |
parent | 367623a430f7a02186c3b0031ef26815befe4023 (diff) |
sq: Use the new armoring filter.
Diffstat (limited to 'tool/src')
-rw-r--r-- | tool/src/commands/mod.rs | 17 | ||||
-rw-r--r-- | tool/src/commands/sign.rs | 39 | ||||
-rw-r--r-- | tool/src/sq.rs | 86 |
3 files changed, 37 insertions, 105 deletions
diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs index a2c2e8cb..b1de8fa8 100644 --- a/tool/src/commands/mod.rs +++ b/tool/src/commands/mod.rs @@ -85,13 +85,13 @@ fn get_signing_keys(certs: &[openpgp::Cert], p: &dyn Policy, Ok(keys) } -pub fn encrypt(policy: &dyn Policy, - input: &mut dyn io::Read, output: &mut dyn io::Write, - npasswords: usize, recipients: &[openpgp::Cert], - signers: Vec<openpgp::Cert>, - mode: openpgp::types::KeyFlags, compression: &str, - time: Option<SystemTime>) - -> Result<()> { +pub fn encrypt<'a>(policy: &'a dyn Policy, + input: &mut dyn io::Read, message: Message<'a>, + npasswords: usize, recipients: &'a [openpgp::Cert], + signers: Vec<openpgp::Cert>, + mode: openpgp::types::KeyFlags, compression: &str, + time: Option<SystemTime>) + -> Result<()> { let mut passwords: Vec<crypto::Password> = Vec::with_capacity(npasswords); for n in 0..npasswords { let nprompt = format!("Enter password {}: ", n + 1); @@ -126,9 +126,6 @@ pub fn encrypt(policy: &dyn Policy, } } - // Stream an OpenPGP message. - let message = Message::new(output); - // We want to encrypt a literal data packet. let mut encryptor = Encryptor::for_recipients(message, recipient_subkeys); diff --git a/tool/src/commands/sign.rs b/tool/src/commands/sign.rs index a91ea54b..9bc2af4d 100644 --- a/tool/src/commands/sign.rs +++ b/tool/src/commands/sign.rs @@ -15,13 +15,12 @@ use crate::openpgp::parse::{ }; use crate::openpgp::serialize::Serialize; use crate::openpgp::serialize::stream::{ - Message, Signer, LiteralWriter, + Message, Armorer, Signer, LiteralWriter, }; use crate::openpgp::policy::Policy; use crate::{ create_or_stdout, create_or_stdout_pgp, - Writer, }; pub fn sign(policy: &dyn Policy, @@ -45,7 +44,7 @@ fn sign_data(policy: &dyn Policy, secrets: Vec<openpgp::Cert>, detached: bool, binary: bool, append: bool, time: Option<SystemTime>, force: bool) -> Result<()> { - let (output, prepend_sigs, tmp_path): + let (mut output, prepend_sigs, tmp_path): (Box<dyn io::Write>, Vec<Signature>, Option<PathBuf>) = if detached && append && output_path.is_some() { // First, read the existing signatures. @@ -78,32 +77,32 @@ fn sign_data(policy: &dyn Policy, (create_or_stdout(output_path, force)?, Vec::new(), None) }; - let mut output = Writer::from(output); + let mut keypairs = super::get_signing_keys(&secrets, policy, time)?; + if keypairs.is_empty() { + return Err(anyhow::anyhow!("No signing keys found")); + } + + // Stream an OpenPGP message. + // The sink may be a NamedTempFile. Carefully keep a reference so + // that we can rename it. + let mut message = Message::new(&mut output); if ! binary { - output = output.armor( - if detached { + message = Armorer::new(message) + .kind(if detached { armor::Kind::Signature } else { armor::Kind::Message - }, - Vec::new())?; - } - - let mut keypairs = super::get_signing_keys(&secrets, policy, time)?; - if keypairs.is_empty() { - return Err(anyhow::anyhow!("No signing keys found")); + }) + .build()?; } // When extending a detached signature, prepend any existing // signatures first. for sig in prepend_sigs.into_iter() { - Packet::Signature(sig).serialize(&mut output)?; + Packet::Signature(sig).serialize(&mut message)?; } - // Stream an OpenPGP message. - let sink = Message::new(&mut output); - - let mut signer = Signer::new(sink, keypairs.pop().unwrap()); + let mut signer = Signer::new(message, keypairs.pop().unwrap()); for s in keypairs { signer = signer.add_signer(s); if let Some(time) = time { @@ -131,16 +130,12 @@ fn sign_data(policy: &dyn Policy, writer.finalize() .context("Failed to sign")?; - // The sink may be a NamedTempFile. Carefully keep a reference so - // that we can rename it. - let tmp = output.finalize()?; if let Some(path) = tmp_path { // Atomically replace the old file. fs::rename(path, output_path.expect("must be Some if tmp_path is Some"))?; } - drop(tmp); Ok(()) } diff --git a/tool/src/sq.rs b/tool/src/sq.rs index 03e87956..5e1a59bc 100644 --- a/tool/src/sq.rs +++ b/tool/src/sq.rs @@ -29,7 +29,7 @@ use sequoia_autocrypt as autocrypt; use crate::openpgp::fmt::hex; use crate::openpgp::types::KeyFlags; use crate::openpgp::parse::Parse; -use crate::openpgp::serialize::Serialize; +use crate::openpgp::serialize::{Serialize, stream::{Message, Armorer}}; use crate::openpgp::cert::prelude::*; use crate::openpgp::policy::StandardPolicy as P; use sequoia_core::{Context, NetworkPolicy}; @@ -70,75 +70,16 @@ fn create_or_stdout(f: Option<&str>, force: bool) } } -// XXX: This is a candidate for inclusion in the library. -enum Writer<T: Write> { - Binary { - inner: T, - }, - Armored { - inner: openpgp::armor::Writer<T>, - }, -} - -impl<T: Write> From<T> for Writer<T> { - fn from(inner: T) -> Self { - Writer::Binary { inner } - } -} - -impl<T: Write> From<openpgp::armor::Writer<T>> for Writer<T> { - fn from(inner: openpgp::armor::Writer<T>) -> Self { - Writer::Armored { inner } - } -} - -impl<T: Write> Writer<T> { - pub fn armor(self, kind: openpgp::armor::Kind, headers: Vec<(&str, &str)>) - -> openpgp::Result<Self> - { - match self { - Writer::Binary { inner } => - Ok(openpgp::armor::Writer::with_headers(inner, kind, headers)? - .into()), - Writer::Armored { .. } => - Err(openpgp::Error::InvalidOperation("already armored".into()) - .into()), - } - } - - pub fn finalize(self) -> std::io::Result<T> { - match self { - Writer::Binary { inner } => Ok(inner), - Writer::Armored { inner } => inner.finalize(), - } - } -} - -impl<T: Write> Write for Writer<T> { - fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { - match self { - Writer::Binary { inner } => inner.write(buf), - Writer::Armored { inner } => inner.write(buf), - } - } - fn flush(&mut self) -> std::io::Result<()> { - match self { - Writer::Binary { inner } => inner.flush(), - Writer::Armored { inner } => inner.flush(), - } - } -} - -fn create_or_stdout_pgp(f: Option<&str>, force: bool, - binary: bool, kind: armor::Kind) - -> Result<Writer<Box<dyn Write>>> +fn create_or_stdout_pgp<'a>(f: Option<&str>, force: bool, + binary: bool, kind: armor::Kind) + -> Result<Message<'a>> { let sink = create_or_stdout(f, force)?; - let mut sink = Writer::from(sink); + let mut message = Message::new(sink); if ! binary { - sink = sink.armor(kind, Vec::new())?; + message = Armorer::new(message).kind(kind).build()?; } - Ok(sink) + Ok(message) } fn load_certs<'a, I>(files: I) -> openpgp::Result<Vec<Cert>> @@ -270,11 +211,6 @@ fn main() -> Result<()> { m.is_present("dump"), m.is_present("hex"))?; }, ("encrypt", Some(m)) => { - let mut input = open_or_stdin(m.value_of("input"))?; - let mut output = - create_or_stdout_pgp(m.value_of("output"), force, - m.is_present("binary"), - armor::Kind::Message)?; let mapping = Mapping::open(&ctx, realm_name, mapping_name) .context("Failed to open the mapping")?; let mut recipients = m.values_of("recipient-key-file") @@ -286,6 +222,11 @@ fn main() -> Result<()> { .context("No such key found")?.cert()?); } } + let mut input = open_or_stdin(m.value_of("input"))?; + let output = + create_or_stdout_pgp(m.value_of("output"), force, + m.is_present("binary"), + armor::Kind::Message)?; let additional_secrets = m.values_of("signer-key-file") .map(load_certs) .unwrap_or(Ok(vec![]))?; @@ -306,13 +247,12 @@ fn main() -> Result<()> { } else { None }; - commands::encrypt(policy, &mut input, &mut output, + commands::encrypt(policy, &mut input, output, m.occurrences_of("symmetric") as usize, &recipients, additional_secrets, mode, m.value_of("compression").expect("has default"), time.into())?; - output.finalize()?; }, ("sign", Some(m)) => { let mut input = open_or_stdin(m.value_of("input"))?; |