diff options
Diffstat (limited to 'openpgp/src/serialize/stream.rs')
-rw-r--r-- | openpgp/src/serialize/stream.rs | 116 |
1 files changed, 59 insertions, 57 deletions
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<writer::BoxStack<'a, Cookie>>, } 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<B: AsRef<[u8]>>(mut self, filename: B) -> Result<Self> { + 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> + { + 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<writer::Stack<'a, Cookie>> - where D: Into<Option<DataFormat>>, - F: Into<Option<&'f [u8]>>, - T: Into<Option<time::Tm>> - { - 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<time::Tm>) - -> Result<writer::Stack<'a, Cookie>> { - 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<writer::Stack<'a, Cookie>> { + 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(); |