diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-11-04 15:11:25 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-11-04 16:20:27 +0100 |
commit | 32b93364165ddc24d29ea7319db6a21b6fe5a515 (patch) | |
tree | 24c31c2afe783b86c3a81ed3fb9bccca4cf54407 | |
parent | 9edc6b6f7e9e05bfd4d6ac0573c2b81f934ebaae (diff) |
make stream::Message::finalize asyncjustus/fix-607
- For sop which only uses local keys, we do not need a runtime.
25 files changed, 138 insertions, 95 deletions
@@ -1794,6 +1794,7 @@ name = "sequoia-autocrypt" version = "0.20.0" dependencies = [ "base64 0.13.0", + "futures", "sequoia-openpgp", ] @@ -1947,6 +1948,7 @@ version = "0.20.0" dependencies = [ "anyhow", "chrono", + "futures", "sequoia-openpgp", "structopt", "thiserror", diff --git a/autocrypt/Cargo.toml b/autocrypt/Cargo.toml index 38ef8263..7ba107e4 100644 --- a/autocrypt/Cargo.toml +++ b/autocrypt/Cargo.toml @@ -23,6 +23,7 @@ maintenance = { status = "actively-developed" } [dependencies] sequoia-openpgp = { path = "../openpgp", version = "0.20", default-features = false } base64 = "0.13" +futures = "0.3" [features] default = ["sequoia-openpgp/default"] diff --git a/autocrypt/src/lib.rs b/autocrypt/src/lib.rs index 93ece361..6836483a 100644 --- a/autocrypt/src/lib.rs +++ b/autocrypt/src/lib.rs @@ -21,6 +21,8 @@ use std::path::Path; use std::fs::File; use std::str; +use futures::FutureExt; + use sequoia_openpgp as openpgp; use openpgp::armor; use openpgp::Error; @@ -502,7 +504,7 @@ impl AutocryptSetupMessage { self.cert.as_tsk().serialize(&mut w)?; let m = w.finalize()?; - m.finalize()?; + m.finalize().now_or_never().expect("no signing involved")?; } armor_writer.finalize()?; Ok(()) diff --git a/openpgp/examples/encrypt-for.rs b/openpgp/examples/encrypt-for.rs index 0b0bc998..c68ff77b 100644 --- a/openpgp/examples/encrypt-for.rs +++ b/openpgp/examples/encrypt-for.rs @@ -5,6 +5,7 @@ use std::env; use std::io; use anyhow::Context; +use futures::FutureExt; use sequoia_openpgp as openpgp; @@ -81,7 +82,7 @@ fn main() -> openpgp::Result<()> { // Finally, finalize the OpenPGP message by tearing down the // writer stack. - message.finalize()?; + message.finalize().now_or_never().unwrap()?; Ok(()) } diff --git a/openpgp/examples/generate-encrypt-decrypt.rs b/openpgp/examples/generate-encrypt-decrypt.rs index bc147827..7fe25c3e 100644 --- a/openpgp/examples/generate-encrypt-decrypt.rs +++ b/openpgp/examples/generate-encrypt-decrypt.rs @@ -1,6 +1,7 @@ /// Generates a key, then encrypts and decrypts a message. use std::io::{self, Write}; +use futures::FutureExt; use sequoia_openpgp as openpgp; @@ -69,7 +70,7 @@ fn encrypt(p: &dyn Policy, sink: &mut dyn Write, plaintext: &str, // Finalize the OpenPGP message to make sure that all data is // written. - message.finalize()?; + message.finalize().now_or_never().unwrap()?; Ok(()) } diff --git a/openpgp/examples/generate-sign-verify.rs b/openpgp/examples/generate-sign-verify.rs index ee7b67b2..ecfe52be 100644 --- a/openpgp/examples/generate-sign-verify.rs +++ b/openpgp/examples/generate-sign-verify.rs @@ -1,6 +1,7 @@ /// Generates a key, then signs and verifies a message. use std::io::{self, Write}; +use futures::FutureExt; use sequoia_openpgp as openpgp; @@ -66,7 +67,7 @@ fn sign(p: &dyn Policy, sink: &mut dyn Write, plaintext: &str, tsk: &openpgp::Ce // Finalize the OpenPGP message to make sure that all data is // written. - literal_writer.finalize()?; + literal_writer.finalize().now_or_never().unwrap()?; Ok(()) } diff --git a/openpgp/examples/notarize.rs b/openpgp/examples/notarize.rs index 22fbf301..fbaf14b7 100644 --- a/openpgp/examples/notarize.rs +++ b/openpgp/examples/notarize.rs @@ -5,6 +5,7 @@ use std::env; use std::io; use anyhow::Context; +use futures::FutureExt; use sequoia_openpgp as openpgp; @@ -101,7 +102,7 @@ fn main() -> openpgp::Result<()> { io::copy(&mut pp, &mut literal) .context("Failed to sign data")?; - message = literal.finalize_one() + message = literal.finalize_one().now_or_never().unwrap() .context("Failed to sign data")? .unwrap(); }, @@ -121,7 +122,7 @@ fn main() -> openpgp::Result<()> { } // Finally, teardown the stack to ensure all the data is written. - message.finalize() + message.finalize().now_or_never().unwrap() .context("Failed to write data")?; Ok(()) diff --git a/openpgp/examples/pad.rs b/openpgp/examples/pad.rs index b90b8982..9f3c3477 100644 --- a/openpgp/examples/pad.rs +++ b/openpgp/examples/pad.rs @@ -5,6 +5,7 @@ use std::env; use std::io; use anyhow::Context; +use futures::FutureExt; use sequoia_openpgp as openpgp; @@ -81,7 +82,7 @@ fn main() -> openpgp::Result<()> { // Finally, finalize the OpenPGP message by tearing down the // writer stack. - message.finalize()?; + message.finalize().now_or_never().unwrap()?; Ok(()) } diff --git a/openpgp/examples/sign-detached.rs b/openpgp/examples/sign-detached.rs index b8f7316b..123f8aa1 100644 --- a/openpgp/examples/sign-detached.rs +++ b/openpgp/examples/sign-detached.rs @@ -4,6 +4,7 @@ use std::env; use std::io; use anyhow::Context; +use futures::FutureExt; use rpassword; @@ -77,7 +78,7 @@ fn main() -> openpgp::Result<()> { .context("Failed to sign data")?; // Finally, teardown the stack to ensure all the data is written. - message.finalize() + message.finalize().now_or_never().unwrap() .context("Failed to write data")?; Ok(()) diff --git a/openpgp/examples/sign.rs b/openpgp/examples/sign.rs index 02feea96..f3deff83 100644 --- a/openpgp/examples/sign.rs +++ b/openpgp/examples/sign.rs @@ -4,6 +4,7 @@ use std::env; use std::io; use anyhow::Context; +use futures::FutureExt; use sequoia_openpgp as openpgp; @@ -79,7 +80,7 @@ fn main() -> openpgp::Result<()> { .context("Failed to sign data")?; // Finally, teardown the stack to ensure all the data is written. - message.finalize() + message.finalize().now_or_never().unwrap() .context("Failed to write data")?; Ok(()) diff --git a/openpgp/examples/wrap-literal.rs b/openpgp/examples/wrap-literal.rs index 3019cbd8..fe49ec37 100644 --- a/openpgp/examples/wrap-literal.rs +++ b/openpgp/examples/wrap-literal.rs @@ -7,6 +7,7 @@ use std::env; use std::io; use anyhow::Context; +use futures::FutureExt; use sequoia_openpgp as openpgp; @@ -38,7 +39,7 @@ fn main() -> openpgp::Result<()> { .context("Failed to sign data")?; // Finally, teardown the stack to ensure all the data is written. - message.finalize() + message.finalize().now_or_never().unwrap() .context("Failed to write data")?; Ok(()) diff --git a/openpgp/src/parse.rs b/openpgp/src/parse.rs index 715d9b03..5bed5257 100644 --- a/openpgp/src/parse.rs +++ b/openpgp/src/parse.rs @@ -5273,6 +5273,7 @@ impl<'a> PacketParser<'a> { #[cfg(test)] mod test { + use futures::FutureExt; use super::*; enum Data<'a> { @@ -6030,7 +6031,7 @@ mod test { signature::SignatureBuilder::new(SignatureType::Text) ).detached().build()?; message.write_all(data)?; - message.finalize()?; + message.finalize().now_or_never().unwrap()?; } struct Helper {}; diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index 3fee1267..2bfa7c49 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -2808,6 +2808,7 @@ impl<'a, H: VerificationHelper + DecryptionHelper> io::Read for Decryptor<'a, H> #[cfg(test)] mod test { + use futures::FutureExt; use super::*; use std::convert::TryFrom; use crate::parse::Parse; @@ -3200,7 +3201,7 @@ mod test { let mut ls = LiteralWriter::new(signer).build().unwrap(); ls.write_all(&mut vec![42u8; 3 * 1024 * 1024]).unwrap(); - ls.finalize().unwrap(); + ls.finalize().now_or_never().unwrap().unwrap(); } // Test Verifier. diff --git a/openpgp/src/serialize.rs b/openpgp/src/serialize.rs index a6d2e98c..6a084792 100644 --- a/openpgp/src/serialize.rs +++ b/openpgp/src/serialize.rs @@ -138,6 +138,8 @@ use std::io::{self, Write}; use std::cmp; use std::convert::{TryFrom, TryInto}; +use futures::FutureExt; + use super::*; mod cert; @@ -2158,7 +2160,7 @@ impl Marshal for CompressedData { let mut o = stream::Compressor::new_naked( o, self.algo(), Default::default(), 0)?; o.write_all(bytes)?; - o.finalize()?; + o.finalize().now_or_never().unwrap()?; }, Body::Structured(children) => { @@ -2177,7 +2179,7 @@ impl Marshal for CompressedData { (p as &dyn Marshal).serialize(&mut o)?; } - o.finalize()?; + o.finalize().now_or_never().unwrap()?; }, } Ok(()) diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs index 957c6963..87e587b0 100644 --- a/openpgp/src/serialize/stream.rs +++ b/openpgp/src/serialize/stream.rs @@ -282,8 +282,8 @@ impl<'a> Message<'a> { /// message.finalize()?; /// # Ok(()) } /// ``` - pub fn finalize_one(self) -> Result<Option<Message<'a>>> { - Ok(self.0.into_inner()?.map(|bs| Self::from(bs))) + pub async fn finalize_one(self) -> Result<Option<Message<'a>>> { + Ok(self.0.into_inner().await?.map(|bs| Self::from(bs))) } /// Finalizes the message. @@ -313,9 +313,9 @@ impl<'a> Message<'a> { /// message.finalize()?; /// # Ok(()) } /// ``` - pub fn finalize(self) -> Result<()> { + pub async fn finalize(self) -> Result<()> { let mut stack = self; - while let Some(s) = stack.finalize_one()? { + while let Some(s) = stack.finalize_one().await? { stack = s; } Ok(()) @@ -586,9 +586,10 @@ impl<'a> Write for ArbitraryWriter<'a> { } } +#[async_trait::async_trait(?Send)] impl<'a> writer::Stackable<'a, Cookie> for ArbitraryWriter<'a> { - fn into_inner(self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> { - Box::new(self.inner).into_inner() + async fn into_inner(self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> { + Box::new(self.inner).into_inner().await } fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> { unreachable!("Only implemented by Signer") @@ -1214,6 +1215,7 @@ impl<'a> Write for Signer<'a> { } } +#[async_trait::async_trait(?Send)] impl<'a> writer::Stackable<'a, Cookie> for Signer<'a> { fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> { Ok(self.inner.take()) @@ -1231,10 +1233,9 @@ impl<'a> writer::Stackable<'a, Cookie> for Signer<'a> { fn inner_ref(&self) -> Option<&dyn writer::Stackable<'a, Cookie>> { self.inner.as_ref().map(|r| r.as_ref()) } - fn into_inner(mut self: Box<Self>) + async fn into_inner(mut self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> { - // XXX: OH SHIT - futures::executor::block_on(self.emit_signatures())?; + self.emit_signatures().await?; Ok(self.inner.take()) } fn cookie_set(&mut self, cookie: Cookie) -> Cookie { @@ -1496,12 +1497,13 @@ impl<'a> Write for LiteralWriter<'a> { } } +#[async_trait::async_trait(?Send)] impl<'a> writer::Stackable<'a, Cookie> for LiteralWriter<'a> { - fn into_inner(mut self: Box<Self>) + async fn into_inner(mut self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> { let signer = self.signature_writer.take(); let stack = self.inner - .into_inner()?.unwrap(); // Peel off the PartialBodyFilter. + .into_inner().await?.unwrap(); // Peel off the PartialBodyFilter. if let Some(mut signer) = signer { // We stashed away a Signer. Reattach it to the @@ -1745,9 +1747,10 @@ impl<'a> io::Write for Compressor<'a> { } } +#[async_trait::async_trait(?Send)] impl<'a> writer::Stackable<'a, Cookie> for Compressor<'a> { - fn into_inner(self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> { - Box::new(self.inner).into_inner()?.unwrap().into_inner() + async fn into_inner(self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> { + Box::new(self.inner).into_inner().await?.unwrap().into_inner().await } fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> { unreachable!("Only implemented by Signer") @@ -2578,7 +2581,7 @@ impl<'a> Encryptor<'a> { } /// Emits the MDC packet and recovers the original writer. - fn emit_mdc(&mut self) -> Result<writer::BoxStack<'a, Cookie>> { + async fn emit_mdc(&mut self) -> Result<writer::BoxStack<'a, Cookie>> { if let Some(mut w) = self.inner.take() { // Write the MDC, which must be the last packet inside the // encrypted packet stream. The hash includes the MDC's @@ -2592,9 +2595,9 @@ impl<'a> Encryptor<'a> { // Now recover the original writer. First, strip the // Encryptor. - let w = w.into_inner()?.unwrap(); + let w = w.into_inner().await?.unwrap(); // And the partial body filter. - let w = w.into_inner()?.unwrap(); + let w = w.into_inner().await?.unwrap(); Ok(w) } else { @@ -2632,6 +2635,7 @@ impl<'a> Write for Encryptor<'a> { } } +#[async_trait::async_trait(?Send)] impl<'a> writer::Stackable<'a, Cookie> for Encryptor<'a> { fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> { unreachable!("Only implemented by Signer") @@ -2650,8 +2654,8 @@ impl<'a> writer::Stackable<'a, Cookie> for Encryptor<'a> { None } } - fn into_inner(mut self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> { - Ok(Some(self.emit_mdc()?)) + async fn into_inner(mut self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> { + Ok(Some(self.emit_mdc().await?)) } fn cookie_set(&mut self, cookie: Cookie) -> Cookie { ::std::mem::replace(&mut self.cookie, cookie) @@ -2669,6 +2673,7 @@ impl<'a> writer::Stackable<'a, Cookie> for Encryptor<'a> { #[cfg(test)] mod test { + use futures::FutureExt; use std::io::Read; use crate::{Packet, PacketPile, packet::CompressedData}; use crate::parse::{Parse, PacketParserResult, PacketParser}; @@ -2687,7 +2692,7 @@ mod test { ustr.write_all(b"\x00").unwrap(); // fn length ustr.write_all(b"\x00\x00\x00\x00").unwrap(); // date ustr.write_all(b"Hello world.").unwrap(); // body - ustr.finalize().unwrap(); + ustr.finalize().now_or_never().unwrap().unwrap(); } let mut pp = PacketParser::from_bytes(&o).unwrap().unwrap(); @@ -2737,14 +2742,14 @@ mod test { .algo(CompressionAlgorithm::Uncompressed).build().unwrap(); let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); write!(ls, "one").unwrap(); - let c = ls.finalize_one().unwrap().unwrap(); // Pop the LiteralWriter. + let c = ls.finalize_one().now_or_never().unwrap().unwrap().unwrap(); // Pop the LiteralWriter. let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); write!(ls, "two").unwrap(); - let c = ls.finalize_one().unwrap().unwrap(); // Pop the LiteralWriter. - let c = c.finalize_one().unwrap().unwrap(); // Pop the Compressor. + let c = ls.finalize_one().now_or_never().unwrap().unwrap().unwrap(); // Pop the LiteralWriter. + let c = c.finalize_one().now_or_never().unwrap().unwrap().unwrap(); // Pop the Compressor. let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); write!(ls, "three").unwrap(); - ls.finalize().unwrap(); + ls.finalize().now_or_never().unwrap().unwrap(); } let pile = PacketPile::from(reference); @@ -2799,19 +2804,19 @@ mod test { .algo(CompressionAlgorithm::Uncompressed).build().unwrap(); let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); write!(ls, "one").unwrap(); - let c = ls.finalize_one().unwrap().unwrap(); + let c = ls.finalize_one().now_or_never().unwrap().unwrap().unwrap(); let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); write!(ls, "two").unwrap(); - let c = ls.finalize_one().unwrap().unwrap(); - let c0 = c.finalize_one().unwrap().unwrap(); + let c = ls.finalize_one().now_or_never().unwrap().unwrap().unwrap(); + let c0 = c.finalize_one().now_or_never().unwrap().unwrap().unwrap(); let c = Compressor::new(c0) .algo(CompressionAlgorithm::Uncompressed).build().unwrap(); let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); write!(ls, "three").unwrap(); - let c = ls.finalize_one().unwrap().unwrap(); + let c = ls.finalize_one().now_or_never().unwrap().unwrap().unwrap(); let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); write!(ls, "four").unwrap(); - ls.finalize().unwrap(); + ls.finalize().now_or_never().unwrap().unwrap(); } let pile = PacketPile::from(reference); @@ -2877,7 +2882,7 @@ mod test { let signer = signer.build().unwrap(); let mut ls = LiteralWriter::new(signer).build().unwrap(); ls.write_all(b"Tis, tis, tis. Tis is important.").unwrap(); - let _ = ls.finalize().unwrap(); + let _ = ls.finalize().now_or_never().unwrap().unwrap(); } let mut ppr = PacketParser::from_bytes(&o).unwrap(); @@ -2911,7 +2916,7 @@ mod test { let mut literal = LiteralWriter::new(encryptor).build() .unwrap(); literal.write_all(message).unwrap(); - literal.finalize().unwrap(); + literal.finalize().now_or_never().unwrap().unwrap(); } // ... and recover it... @@ -3097,7 +3102,7 @@ mod test { let mut literal = LiteralWriter::new(encryptor).build() .unwrap(); literal.write_all(&content).unwrap(); - literal.finalize().unwrap(); + literal.finalize().now_or_never().unwrap().unwrap(); } for &read_len in &[ @@ -3201,8 +3206,8 @@ mod test { let mut ls = LiteralWriter::new(signer).build().unwrap(); ls.write_all(b"Tis, tis, tis. Tis is important.").unwrap(); - let signer = ls.finalize_one().unwrap().unwrap(); - let _ = signer.finalize_one().unwrap().unwrap(); + let signer = ls.finalize_one().now_or_never().unwrap().unwrap().unwrap(); + let _ = signer.finalize_one().now_or_never().unwrap().unwrap().unwrap(); } let mut ppr = PacketParser::from_bytes(&o).unwrap(); @@ -3261,7 +3266,7 @@ mod test { signature::SignatureBuilder::new(SignatureType::Text) ).detached().build()?; message.write_all(data)?; - message.finalize()?; + message.finalize().now_or_never().unwrap()?; } struct Helper {}; diff --git a/openpgp/src/serialize/stream/padding.rs b/openpgp/src/serialize/stream/padding.rs index b1750b07..de4277e1 100644 --- a/openpgp/src/serialize/stream/padding.rs +++ b/openpgp/src/serialize/stream/padding.rs @@ -218,9 +218,10 @@ impl<'a, P: Fn(u64) -> u64 + 'a> io::Write for Padder<'a, P> { } } +#[async_trait::async_trait(?Send)] impl<'a, P: Fn(u64) -> u64 + 'a> writer::Stackable<'a, Cookie> for Padder<'a, P> { - fn into_inner(self: Box<Self>) + async fn into_inner(self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> { // Make a note of the amount of data written to this filter. let uncompressed_size = self.position(); @@ -228,7 +229,7 @@ impl<'a, P: Fn(u64) -> u64 + 'a> writer::Stackable<'a, Cookie> for Padder<'a, P> // Pop-off us and the compression filter, leaving only our // partial body encoder on the stack. This finalizes the // compression. - let mut pb_writer = Box::new(self.inner).into_inner()?.unwrap(); + let mut pb_writer = Box::new(self.inner).into_inner().await?.unwrap(); // Compressed size is what we've actually written out, modulo // partial body encoding. @@ -263,7 +264,7 @@ impl<'a, P: Fn(u64) -> u64 + 'a> writer::Stackable<'a, Cookie> for Padder<'a, P> amount -= n as u64; } - pb_writer.into_inner() + pb_writer.into_inner().await } fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> { unreachable!("Only implemented by Signer") @@ -335,6 +336,7 @@ fn log2(x: u64) -> usize { #[cfg(test)] mod test { + use futures::FutureExt; use super::*; #[test] @@ -408,7 +410,7 @@ mod test { let padder = Padder::new(message, padme).unwrap(); let mut w = LiteralWriter::new(padder).build().unwrap(); w.write_all(&msg).unwrap(); - w.finalize().unwrap(); + w.finalize().now_or_never().unwrap().unwrap(); } let m = crate::Message::from_bytes(&padded).unwrap(); @@ -431,7 +433,7 @@ mod test { let padder = Padder::new(message, padme).unwrap(); let mut w = LiteralWriter::new(padder).build().unwrap(); |