From 505f45f8077ac92b4ae5fa6cde88a10a3be15af3 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Tue, 19 Nov 2019 17:32:46 +0100 Subject: openpgp: Use the builder pattern for stream::LiteralWriter. - See #375. --- openpgp/examples/encrypt-for.rs | 2 +- openpgp/examples/generate-encrypt-decrypt.rs | 2 +- openpgp/examples/generate-sign-verify.rs | 2 +- openpgp/examples/notarize.rs | 2 +- openpgp/examples/pad.rs | 2 +- openpgp/examples/sign.rs | 2 +- openpgp/examples/wrap-literal.rs | 2 +- openpgp/src/autocrypt.rs | 3 +- openpgp/src/parse/stream.rs | 2 +- openpgp/src/serialize/padding.rs | 11 +-- openpgp/src/serialize/stream.rs | 116 ++++++++++++++------------- 11 files changed, 72 insertions(+), 74 deletions(-) (limited to 'openpgp') diff --git a/openpgp/examples/encrypt-for.rs b/openpgp/examples/encrypt-for.rs index 7b1f48e7..3076c7a4 100644 --- a/openpgp/examples/encrypt-for.rs +++ b/openpgp/examples/encrypt-for.rs @@ -56,7 +56,7 @@ fn main() { &recipients, None, None) .expect("Failed to create encryptor"); - let mut literal_writer = LiteralWriter::new(encryptor, None, None, None) + let mut literal_writer = LiteralWriter::new(encryptor).build() .expect("Failed to create literal writer"); // Copy stdin to our writer stack to encrypt the data. diff --git a/openpgp/examples/generate-encrypt-decrypt.rs b/openpgp/examples/generate-encrypt-decrypt.rs index f24eba1f..f8eeb05f 100644 --- a/openpgp/examples/generate-encrypt-decrypt.rs +++ b/openpgp/examples/generate-encrypt-decrypt.rs @@ -59,7 +59,7 @@ fn encrypt(sink: &mut dyn Write, plaintext: &str, recipient: &openpgp::TPK) None, None)?; // Emit a literal data packet. - let mut literal_writer = LiteralWriter::new(encryptor, None, None, None)?; + let mut literal_writer = LiteralWriter::new(encryptor).build()?; // Encrypt the data. literal_writer.write_all(plaintext.as_bytes())?; diff --git a/openpgp/examples/generate-sign-verify.rs b/openpgp/examples/generate-sign-verify.rs index e22e5760..98e94f21 100644 --- a/openpgp/examples/generate-sign-verify.rs +++ b/openpgp/examples/generate-sign-verify.rs @@ -50,7 +50,7 @@ fn sign(sink: &mut dyn Write, plaintext: &str, tsk: &openpgp::TPK) let signer = Signer::new(message, keypair).build()?; // Emit a literal data packet. - let mut literal_writer = LiteralWriter::new(signer, None, None, None)?; + let mut literal_writer = LiteralWriter::new(signer).build()?; // Sign the data. literal_writer.write_all(plaintext.as_bytes())?; diff --git a/openpgp/examples/notarize.rs b/openpgp/examples/notarize.rs index c627d4f1..d17aec44 100644 --- a/openpgp/examples/notarize.rs +++ b/openpgp/examples/notarize.rs @@ -87,7 +87,7 @@ fn main() { // Then, create a literal writer to wrap the data in a // literal message packet. let mut literal = - LiteralWriter::new(signer, None, None, None) + LiteralWriter::new(signer).build() .expect("Failed to create literal writer"); // Copy all the data. diff --git a/openpgp/examples/pad.rs b/openpgp/examples/pad.rs index eaaaeba8..76d4ebc0 100644 --- a/openpgp/examples/pad.rs +++ b/openpgp/examples/pad.rs @@ -62,7 +62,7 @@ fn main() { let padder = Padder::new(encryptor, padme) .expect("Failed to create padder"); - let mut literal_writer = LiteralWriter::new(padder, None, None, None) + let mut literal_writer = LiteralWriter::new(padder).build() .expect("Failed to create literal writer"); // Copy stdin to our writer stack to encrypt the data. diff --git a/openpgp/examples/sign.rs b/openpgp/examples/sign.rs index 2304865f..523c9e26 100644 --- a/openpgp/examples/sign.rs +++ b/openpgp/examples/sign.rs @@ -64,7 +64,7 @@ fn main() { // Then, create a literal writer to wrap the data in a literal // message packet. - let mut literal = LiteralWriter::new(signer, None, None, None) + let mut literal = LiteralWriter::new(signer).build() .expect("Failed to create literal writer"); // Copy all the data. diff --git a/openpgp/examples/wrap-literal.rs b/openpgp/examples/wrap-literal.rs index d3eed376..567ba3b5 100644 --- a/openpgp/examples/wrap-literal.rs +++ b/openpgp/examples/wrap-literal.rs @@ -28,7 +28,7 @@ fn main() { // Then, create a literal writer to wrap the data in a literal // message packet. - let mut literal = LiteralWriter::new(message, None, None, None) + let mut literal = LiteralWriter::new(message).build() .expect("Failed to create literal writer"); // Copy all the data. diff --git a/openpgp/src/autocrypt.rs b/openpgp/src/autocrypt.rs index 93661166..4f7596bb 100644 --- a/openpgp/src/autocrypt.rs +++ b/openpgp/src/autocrypt.rs @@ -471,8 +471,7 @@ impl AutocryptSetupMessage { vec![ self.passcode.as_ref().unwrap() ], &[], None, None)?; - let mut w = LiteralWriter::new(w, None, - /* filename*/ None, /* date */ None)?; + let mut w = LiteralWriter::new(w).build()?; // The inner message is an ASCII-armored encoded TPK. let mut w = armor::Writer::new( diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index fff01171..e1678d10 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -1905,7 +1905,7 @@ mod test { let m = Message::new(&mut buf); let signer = Signer::new(m, keypair).build().unwrap(); - let mut ls = LiteralWriter::new(signer, None, None, None).unwrap(); + let mut ls = LiteralWriter::new(signer).build().unwrap(); ls.write_all(&mut vec![42u8; 30 * 1024 * 1024]).unwrap(); ls.finalize().unwrap(); diff --git a/openpgp/src/serialize/padding.rs b/openpgp/src/serialize/padding.rs index 0c9c4ee0..d30374a0 100644 --- a/openpgp/src/serialize/padding.rs +++ b/openpgp/src/serialize/padding.rs @@ -102,7 +102,7 @@ use crate::constants::{ /// let message = Message::new(&mut unpadded); /// // XXX: Insert Encryptor here. /// // XXX: Insert Signer here. -/// let mut w = LiteralWriter::new(message, None, None, None)?; +/// let mut w = LiteralWriter::new(message).build()?; /// w.write_all(b"Hello world.")?; /// w.finalize()?; /// } @@ -113,7 +113,7 @@ use crate::constants::{ /// // XXX: Insert Encryptor here. /// let padder = Padder::new(message, padme)?; /// // XXX: Insert Signer here. -/// let mut w = LiteralWriter::new(padder, None, None, None)?; +/// let mut w = LiteralWriter::new(padder).build()?; /// w.write_all(b"Hello world.")?; /// w.finalize()?; /// } @@ -341,9 +341,7 @@ mod test { { let message = Message::new(&mut padded); let padder = Padder::new(message, padme).unwrap(); - let mut w = - LiteralWriter::new(padder, None, None, None) - .unwrap(); + let mut w = LiteralWriter::new(padder).build().unwrap(); w.write_all(&msg).unwrap(); w.finalize().unwrap(); } @@ -366,8 +364,7 @@ mod test { { let message = Message::new(&mut padded); let padder = Padder::new(message, padme).unwrap(); - let mut w = LiteralWriter::new(padder, None, None, None) - .unwrap(); + let mut w = LiteralWriter::new(padder).build().unwrap(); w.write_all(MSG).unwrap(); w.finalize().unwrap(); } diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs index 38c14fa7..201df920 100644 --- a/openpgp/src/serialize/stream.rs +++ b/openpgp/src/serialize/stream.rs @@ -240,7 +240,7 @@ impl<'a> Signer<'a> { /// { /// let message = Message::new(&mut o); /// let signer = Signer::new(message, signing_keypair).build()?; - /// let mut ls = LiteralWriter::new(signer, None, None, None)?; + /// let mut ls = LiteralWriter::new(signer).build()?; /// ls.write_all(b"Make it so, number one!")?; /// ls.finalize()?; /// } @@ -544,7 +544,7 @@ impl<'a> writer::Stackable<'a, Cookie> for Signer<'a> { /// let mut o = vec![]; /// { /// let message = Message::new(&mut o); -/// let mut w = LiteralWriter::new(message, None, None, None)?; +/// let mut w = LiteralWriter::new(message).build()?; /// w.write_all(b"Hello world.")?; /// w.finalize()?; /// } @@ -553,47 +553,52 @@ impl<'a> writer::Stackable<'a, Cookie> for Signer<'a> { /// # } /// ``` pub struct LiteralWriter<'a> { + template: Literal, inner: writer::BoxStack<'a, Cookie>, signature_writer: Option>, } impl<'a> LiteralWriter<'a> { /// Creates a new literal writer. + pub fn new(inner: writer::Stack<'a, Cookie>) -> Self { + LiteralWriter { + template: Literal::new(DataFormat::default()), + inner: writer::BoxStack::from(inner), + signature_writer: None, + } + } + + /// Sets the data format. + pub fn format(mut self, format: DataFormat) -> Self { + self.template.set_format(format); + self + } + + /// Sets the filename. + /// + /// The standard does not specify the encoding. Filenames must + /// not be longer than 255 bytes. + pub fn filename>(mut self, filename: B) -> Result { + self.template.set_filename_from_bytes(filename.as_ref())?; + Ok(self) + } + + /// Sets the data format. + pub fn date(mut self, timestamp: time::Tm) -> Result + { + self.template.set_date(Some(timestamp)); + Ok(self) + } + + /// Finalizes the literal writer, returning the writer stack. /// /// `format`, `filename`, and `date` will be emitted as part of /// the literal packets headers. Note that these headers will not /// be authenticated by signatures (but will be authenticated by a /// SEIP/MDC container), and are therefore unreliable and should /// not be trusted. - /// - /// If `date` is `None`, then the earliest representable time will - /// be used as a dummy value. - pub fn new<'f, D, F, T>(inner: writer::Stack<'a, Cookie>, - format: D, filename: F, date: T) - -> Result> - where D: Into>, - F: Into>, - T: Into> - { - Self::make(inner, - format.into().unwrap_or_default(), - filename.into(), date.into()) - } - - fn make(inner: writer::Stack<'a, Cookie>, - format: DataFormat, - filename: Option<&[u8]>, - date: Option) - -> Result> { - let mut inner = writer::BoxStack::from(inner); - let level = inner.cookie_ref().level + 1; - - let mut template = Literal::new(format); - template.set_date(date); - - if let Some(f) = filename { - template.set_filename_from_bytes(f)?; - } + pub fn build(mut self) -> Result> { + let level = self.inner.cookie_ref().level + 1; // For historical reasons, signatures over literal data // packets only include the body without metadata or framing. @@ -604,35 +609,32 @@ impl<'a> LiteralWriter<'a> { if let &Cookie { private: Private::Signer{..}, .. - } = inner.cookie_ref() { + } = self.inner.cookie_ref() { true } else { false }; - let mut signature_writer = None; if signer_above { - let stack = inner.pop()?; + let stack = self.inner.pop()?; // We know a signer has an inner stackable. let stack = stack.unwrap(); - signature_writer = Some(inner); - inner = stack; + self.signature_writer = Some(self.inner); + self.inner = stack; } // Not hashed by the signature_writer (see above). - CTB::new(Tag::Literal).serialize(&mut inner)?; + CTB::new(Tag::Literal).serialize(&mut self.inner)?; // Neither is any framing added by the PartialBodyFilter. - let mut inner - = PartialBodyFilter::new(writer::Stack::from(inner), Cookie::new(level)); + self.inner + = PartialBodyFilter::new(writer::Stack::from(self.inner), + Cookie::new(level)).into(); // Nor the headers. - template.serialize_headers(&mut inner, false)?; + self.template.serialize_headers(&mut self.inner, false)?; - Ok(writer::Stack::from(Box::new(Self { - inner: inner.into(), - signature_writer: signature_writer, - }))) + Ok(writer::Stack::from(Box::new(self))) } } @@ -726,7 +728,7 @@ impl<'a> writer::Stackable<'a, Cookie> for LiteralWriter<'a> { /// let message = Message::new(&mut o); /// let w = Compressor::new(message, /// CompressionAlgorithm::Uncompressed, None)?; -/// let mut w = LiteralWriter::new(w, None, None, None)?; +/// let mut w = LiteralWriter::new(w).build()?; /// w.write_all(b"Hello world.")?; /// w.finalize()?; /// } @@ -966,7 +968,7 @@ impl<'a> Encryptor<'a> { /// &["совершенно секретно".into()], /// &recipients, None, None) /// .expect("Failed to create encryptor"); - /// let mut w = LiteralWriter::new(encryptor, None, None, None)?; + /// let mut w = LiteralWriter::new(encryptor).build()?; /// w.write_all(b"Hello world.")?; /// w.finalize()?; /// # Ok(()) @@ -1266,14 +1268,14 @@ mod test { let m = Message::new(&mut o); let c = Compressor::new( m, CompressionAlgorithm::Uncompressed, None).unwrap(); - let mut ls = LiteralWriter::new(c, T, None, None).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 mut ls = LiteralWriter::new(c, T, None, None).unwrap(); + 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 mut ls = LiteralWriter::new(c, T, None, None).unwrap(); + let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); write!(ls, "three").unwrap(); } @@ -1327,19 +1329,19 @@ mod test { m, CompressionAlgorithm::Uncompressed, None).unwrap(); let c = Compressor::new( c0, CompressionAlgorithm::Uncompressed, None).unwrap(); - let mut ls = LiteralWriter::new(c, T, None, None).unwrap(); + let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); write!(ls, "one").unwrap(); let c = ls.finalize_one().unwrap().unwrap(); - let mut ls = LiteralWriter::new(c, T, None, None).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 = Compressor::new( c0, CompressionAlgorithm::Uncompressed, None).unwrap(); - let mut ls = LiteralWriter::new(c, T, None, None).unwrap(); + let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); write!(ls, "three").unwrap(); let c = ls.finalize_one().unwrap().unwrap(); - let mut ls = LiteralWriter::new(c, T, None, None).unwrap(); + let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); write!(ls, "four").unwrap(); } @@ -1363,7 +1365,7 @@ mod test { let m = Message::new(&mut o); let c = Compressor::new(m, CompressionAlgorithm::BZip2, None).unwrap(); - let mut ls = LiteralWriter::new(c, None, None, None).unwrap(); + let mut ls = LiteralWriter::new(c).build().unwrap(); // Write 64 megabytes of zeroes. for _ in 0 .. 16 { ls.write_all(&zeros).unwrap(); @@ -1402,7 +1404,7 @@ mod test { signer = signer.add_signer(s); } let signer = signer.build().unwrap(); - let mut ls = LiteralWriter::new(signer, None, None, None).unwrap(); + 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(); @@ -1439,7 +1441,7 @@ mod test { m, &passwords, &[], None, None) .unwrap(); - let mut literal = LiteralWriter::new(encryptor, None, None, None) + let mut literal = LiteralWriter::new(encryptor).build() .unwrap(); literal.write_all(message).unwrap(); } @@ -1627,7 +1629,7 @@ mod test { let encryptor = Encryptor::new( m, &[], &recipients, None, AEADAlgorithm::EAX) .unwrap(); - let mut literal = LiteralWriter::new(encryptor, None, None, None) + let mut literal = LiteralWriter::new(encryptor).build() .unwrap(); literal.write_all(&content).unwrap(); // literal.finalize().unwrap(); -- cgit v1.2.3