summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-09-02 13:56:34 +0200
committerJustus Winter <justus@sequoia-pgp.org>2019-09-02 15:38:57 +0200
commit341d518d86d9b0c4237e56da6b88d87edc2c5f36 (patch)
tree186450f5f2153dbd69a005f870e8dfb7568bbca9
parentfe65f0052adbb3ebee7f20edbc83ec4396d46b53 (diff)
openpgp: Disable compression when padding.
- Previously, the deflate encoder expanded some input, correlating resulting message size with compressibility, or other properties of the input. Avoid that by disabling compression. With the DEFLATE encoding, this creates a negligible, but predictable overhead linear in the size of the message. - Add a test. Improve doctest.
-rw-r--r--openpgp/src/serialize/padding.rs48
1 files changed, 42 insertions, 6 deletions
diff --git a/openpgp/src/serialize/padding.rs b/openpgp/src/serialize/padding.rs
index b9928b69..02583730 100644
--- a/openpgp/src/serialize/padding.rs
+++ b/openpgp/src/serialize/padding.rs
@@ -91,17 +91,27 @@ use crate::constants::{
/// # f().unwrap();
/// # fn f() -> Result<()> {
///
-/// let mut o = vec![];
+/// let mut unpadded = vec![];
/// {
-/// let message = Message::new(&mut o);
+/// let message = Message::new(&mut unpadded);
/// // XXX: Insert Encryptor here.
-/// let w = Padder::new(message, padme)?;
/// // XXX: Insert Signer here.
-/// let mut w = LiteralWriter::new(w, DataFormat::Text, None, None)?;
+/// let mut w = LiteralWriter::new(message, DataFormat::Text, None, None)?;
/// w.write_all(b"Hello world.")?;
/// w.finalize()?;
/// }
-/// assert_eq!(o.len(), 28);
+///
+/// let mut padded = vec![];
+/// {
+/// let message = Message::new(&mut padded);
+/// // XXX: Insert Encryptor here.
+/// let padder = Padder::new(message, padme)?;
+/// // XXX: Insert Signer here.
+/// let mut w = LiteralWriter::new(padder, DataFormat::Text, None, None)?;
+/// w.write_all(b"Hello world.")?;
+/// w.finalize()?;
+/// }
+/// assert!(unpadded.len() < padded.len());
/// # Ok(())
/// # }
pub struct Padder<'a, P: Fn(u64) -> u64 + 'a> {
@@ -127,7 +137,8 @@ impl<'a, P: Fn(u64) -> u64 + 'a> Padder<'a, P> {
// Create an appropriate filter.
let inner: writer::Stack<'a, Cookie> =
- writer::ZLIB::new(inner, Cookie::new(level), None);
+ writer::ZLIB::new(inner, Cookie::new(level),
+ writer::CompressionLevel::none());
Ok(writer::Stack::from(Box::new(Self {
inner: inner.into(),
@@ -335,4 +346,29 @@ mod test {
let m = crate::Message::from_bytes(&padded).unwrap();
assert_eq!(m.body().unwrap().body().unwrap(), &msg[..]);
}
+
+ /// Asserts that no actual compression is done.
+ ///
+ /// We want to avoid having the size of the data stream depend on
+ /// the data's compressibility, therefore it is best to disable
+ /// the compression.
+ #[test]
+ fn no_compression() {
+ use std::io::Write;
+ use crate::constants::DataFormat;
+ use crate::serialize::stream::*;
+ const MSG: &[u8] = b"@@@@@@@@@@@@@@";
+ let mut padded = vec![];
+ {
+ let message = Message::new(&mut padded);
+ let padder = Padder::new(message, padme).unwrap();
+ let mut w = LiteralWriter::new(padder, DataFormat::Text, None, None)
+ .unwrap();
+ w.write_all(MSG).unwrap();
+ w.finalize().unwrap();
+ }
+
+ assert!(padded.windows(MSG.len()).any(|ch| ch == MSG),
+ "Could not find uncompressed message");
+ }
}