From 1dfa3f2c03895c72e447164703b140262d5b630a Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Tue, 3 Nov 2020 22:27:25 +0100 Subject: openpgp: Make stream::Padder use the builder pattern. - Split Padder::new() into new and build. - Adjust code in dependent projects (sop and sq). - Fixes #600. --- openpgp/examples/pad.rs | 2 +- openpgp/src/serialize/stream.rs | 2 +- openpgp/src/serialize/stream/padding.rs | 59 +++++++++++++++++++++++++-------- openpgp/src/types/compression_level.rs | 2 +- sop/src/main.rs | 2 +- sq/src/commands/mod.rs | 2 +- 6 files changed, 50 insertions(+), 19 deletions(-) diff --git a/openpgp/examples/pad.rs b/openpgp/examples/pad.rs index b90b8982..48489abd 100644 --- a/openpgp/examples/pad.rs +++ b/openpgp/examples/pad.rs @@ -70,7 +70,7 @@ fn main() -> openpgp::Result<()> { .build().context("Failed to create encryptor")?; let message = Padder::new(message, padme) - .context("Failed to create padder")?; + .build().context("Failed to create padder")?; let mut message = LiteralWriter::new(message).build() .context("Failed to create literal writer")?; diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs index 422e0382..00adcc32 100644 --- a/openpgp/src/serialize/stream.rs +++ b/openpgp/src/serialize/stream.rs @@ -114,7 +114,7 @@ //! let message = Armorer::new(message).build()?; //! let message = Encryptor::for_recipients(message, recipients).build()?; //! // Reduce metadata leakage by concealing the message size. -//! let message = Padder::new(message, padme)?; +//! let message = Padder::new(message, padme).build()?; //! let message = Signer::new(message, signing_keypair) //! // Prevent Surreptitious Forwarding. //! .add_intended_recipient(&recipient) diff --git a/openpgp/src/serialize/stream/padding.rs b/openpgp/src/serialize/stream/padding.rs index b1750b07..350dc418 100644 --- a/openpgp/src/serialize/stream/padding.rs +++ b/openpgp/src/serialize/stream/padding.rs @@ -131,7 +131,7 @@ use crate::types::{ /// { /// let message = Message::new(&mut padded); /// // XXX: Insert Encryptor here. -/// let message = Padder::new(message, padme)?; +/// let message = Padder::new(message, padme).build()?; /// // XXX: Insert Signer here. /// let mut message = LiteralWriter::new(message).build()?; /// message.write_all(b"Hello world.")?; @@ -163,20 +163,54 @@ impl<'a, P: Fn(u64) -> u64 + 'a> Padder<'a, P> { /// [`LiteralWriter`]: ../struct.LiteralWriter.html /// /// ``` - /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { + /// # fn main() -> sequoia_openpgp::Result<()> { /// use sequoia_openpgp as openpgp; /// use openpgp::serialize::stream::padding::{Padder, padme}; /// /// # let message = openpgp::serialize::stream::Message::new(vec![]); - /// let message = Padder::new(message, padme)?; + /// let message = Padder::new(message, padme).build()?; /// // Optionally add a `Signer` here. /// // Add a `LiteralWriter` here. /// # let _ = message; /// # Ok(()) } /// ``` - pub fn new(inner: Message<'a>, p: P) - -> Result> { - let mut inner = writer::BoxStack::from(inner); + pub fn new(inner: Message<'a>, p: P) -> Self { + Self { + inner: writer::BoxStack::from(inner).into(), + policy: p, + } + } + + /// Builds the padder, returning the writer stack. + /// + /// # Examples + /// + /// This example illustrates the use of `Padder` with the [Padmé] + /// policy. + /// + /// [Padmé]: fn.padme.html + /// + /// The most useful filter to push to the writer stack next is the + /// [`Signer`] or the [`LiteralWriter`]. Finally, literal data + /// *must* be wrapped using the [`LiteralWriter`]. + /// + /// [`Signer`]: ../struct.Signer.html + /// [`LiteralWriter`]: ../struct.LiteralWriter.html + /// + /// ``` + /// # fn main() -> sequoia_openpgp::Result<()> { + /// use sequoia_openpgp as openpgp; + /// use openpgp::serialize::stream::padding::{Padder, padme}; + /// + /// # let message = openpgp::serialize::stream::Message::new(vec![]); + /// let message = Padder::new(message, padme).build()?; + /// // Optionally add a `Signer` here. + /// // Add a `LiteralWriter` here. + /// # let _ = message; + /// # Ok(()) } + /// ``` + pub fn build(mut self) -> Result> { + let mut inner = self.inner; let level = inner.cookie_ref().level + 1; // Packet header. @@ -189,14 +223,11 @@ impl<'a, P: Fn(u64) -> u64 + 'a> Padder<'a, P> { inner.as_mut().write_u8(CompressionAlgorithm::Zip.into())?; // Create an appropriate filter. - let inner: Message<'a> = + self.inner = writer::ZIP::new(inner, Cookie::new(level), - CompressionLevel::none()); + CompressionLevel::none()).into(); - Ok(Message::from(Box::new(Self { - inner: inner.into(), - policy: p, - }))) + Ok(Message::from(Box::new(self))) } } @@ -405,7 +436,7 @@ mod test { let mut padded = vec![]; { let message = Message::new(&mut padded); - let padder = Padder::new(message, padme).unwrap(); + let padder = Padder::new(message, padme).build().unwrap(); let mut w = LiteralWriter::new(padder).build().unwrap(); w.write_all(&msg).unwrap(); w.finalize().unwrap(); @@ -428,7 +459,7 @@ mod test { let mut padded = vec![]; { let message = Message::new(&mut padded); - let padder = Padder::new(message, padme).unwrap(); + let padder = Padder::new(message, padme).build().unwrap(); let mut w = LiteralWriter::new(padder).build().unwrap(); w.write_all(MSG).unwrap(); w.finalize().unwrap(); diff --git a/openpgp/src/types/compression_level.rs b/openpgp/src/types/compression_level.rs index 695919ed..59627c48 100644 --- a/openpgp/src/types/compression_level.rs +++ b/openpgp/src/types/compression_level.rs @@ -41,7 +41,7 @@ use crate::{ /// .level(CompressionLevel::fastest()) /// .build()?; /// -/// let message = Padder::new(message, padme)?; +/// let message = Padder::new(message, padme).build()?; /// /// let mut message = LiteralWriter::new(message).build()?; /// message.write_all(b"Hello world.")?; diff --git a/sop/src/main.rs b/sop/src/main.rs index 7a53811f..22dbeec7 100644 --- a/sop/src/main.rs +++ b/sop/src/main.rs @@ -313,7 +313,7 @@ fn real_main() -> Result<()> { .context("Failed to create encryptor")?; // Pad the message. - let mut message = Padder::new(message, padme)?; + let mut message = Padder::new(message, padme).build()?; // Maybe sign the message. if let Some(s) = signers.pop() { diff --git a/sq/src/commands/mod.rs b/sq/src/commands/mod.rs index fbf96657..8b542c66 100644 --- a/sq/src/commands/mod.rs +++ b/sq/src/commands/mod.rs @@ -130,7 +130,7 @@ pub fn encrypt<'a>(policy: &'a dyn Policy, match compression { "none" => (), - "pad" => sink = Padder::new(sink, padme)?, + "pad" => sink = Padder::new(sink, padme).build()?, "zip" => sink = Compressor::new(sink).algo(CompressionAlgorithm::Zip).build()?, "zlib" => sink = -- cgit v1.2.3