summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2022-04-28 12:57:54 +0200
committerJustus Winter <justus@sequoia-pgp.org>2022-04-28 13:22:47 +0200
commit583f781a0fb66b503c492540510eb747c6f47247 (patch)
tree88a7b8d3267bb4dd6d623fbbd516ce3951e89c0e
parent31a9ae094eeb41e720119f92a8afeb1a6123a01e (diff)
openpgp: Rework handing of unknown compression algorithms.
- Currently, if we don't understand a compression algorithm, parsing a compressed data packet fails and it is turned into an Unknown packet. This is rather unfortunate, and deviates from what we do for the encryption containers. - Encryption containers are either not decrypted, in which case they have a Body::Unprocessed, decrypted with Body::Processed, or decrypted and parsed Body::Structured. - Likewise, if we don't understand a compression algorithm, we should simply return a compressed data packet with an unprocessed body. This change does exactly that. - Fixes #830.
-rw-r--r--openpgp/src/parse.rs25
-rw-r--r--openpgp/src/serialize.rs21
2 files changed, 19 insertions, 27 deletions
diff --git a/openpgp/src/parse.rs b/openpgp/src/parse.rs
index 45bdd7b1..386c27b5 100644
--- a/openpgp/src/parse.rs
+++ b/openpgp/src/parse.rs
@@ -2555,6 +2555,9 @@ impl CompressedData {
let algo: CompressionAlgorithm =
php_try!(php.parse_u8("algo")).into();
+ let recursion_depth = php.recursion_depth();
+ let mut pp = php.ok(Packet::CompressedData(CompressedData::new(algo)))?;
+
#[allow(unreachable_patterns)]
match algo {
CompressionAlgorithm::Uncompressed => (),
@@ -2563,16 +2566,15 @@ impl CompressedData {
| CompressionAlgorithm::Zlib => (),
#[cfg(feature = "compression-bzip2")]
CompressionAlgorithm::BZip2 => (),
- CompressionAlgorithm::Unknown(_)
- | CompressionAlgorithm::Private(_) =>
- return php.fail("unknown compression algorithm"),
- _ =>
- return php.fail("unsupported compression algorithm"),
+ _ => {
+ // We don't know or support this algorithm. Return a
+ // CompressedData packet without pushing a filter, so
+ // that it has an opaque body.
+ t!("Algorithm {} unknown or unsupported.", algo);
+ return Ok(pp.set_encrypted(true));
+ },
}
- let recursion_depth = php.recursion_depth();
- let mut pp = php.ok(Packet::CompressedData(CompressedData::new(algo)))?;
-
t!("Pushing a decompressor for {}, recursion depth = {:?}.",
algo, recursion_depth);
@@ -4699,8 +4701,6 @@ impl <'a> PacketParser<'a> {
}
}
},
- // self.encrypted should always be false.
- Packet::CompressedData(_) => unreachable!(),
// Packets that don't recurse.
Packet::Unknown(_) | Packet::Signature(_) | Packet::OnePassSig(_)
| Packet::PublicKey(_) | Packet::PublicSubkey(_)
@@ -4708,7 +4708,8 @@ impl <'a> PacketParser<'a> {
| Packet::Marker(_) | Packet::Trust(_)
| Packet::UserID(_) | Packet::UserAttribute(_)
| Packet::Literal(_) | Packet::PKESK(_) | Packet::SKESK(_)
- | Packet::SEIP(_) | Packet::MDC(_) | Packet::AED(_) => {
+ | Packet::SEIP(_) | Packet::MDC(_) | Packet::AED(_)
+ | Packet::CompressedData(_) => {
// Drop through.
t!("A {:?} packet is not a container, not recursing.",
self.packet.tag());
@@ -4805,7 +4806,7 @@ impl <'a> PacketParser<'a> {
Packet::Literal(p) => set_or_extend(rest, p.container_mut(), false),
Packet::Unknown(p) => set_or_extend(rest, p.container_mut(), false),
Packet::CompressedData(p) =>
- set_or_extend(rest, p.deref_mut(), true),
+ set_or_extend(rest, p.deref_mut(), ! self.encrypted),
Packet::SEIP(p) =>
set_or_extend(rest, p.deref_mut(), ! self.encrypted),
Packet::AED(p) =>
diff --git a/openpgp/src/serialize.rs b/openpgp/src/serialize.rs
index afbf1646..7588fb4b 100644
--- a/openpgp/src/serialize.rs
+++ b/openpgp/src/serialize.rs
@@ -3130,6 +3130,12 @@ mod test {
// 3. Get the first packet.
let po = pile.descendants().next();
if let Some(&Packet::CompressedData(ref cd)) = po {
+ if ! cd.algo().is_supported() {
+ eprintln!("Skipping {} because {} is not supported.",
+ filename, cd.algo());
+ continue;
+ }
+
// 4. Serialize the container.
let buffer =
(&Packet::CompressedData(cd.clone()) as &dyn MarshalInto)
@@ -3162,21 +3168,6 @@ mod test {
assert_eq!(pile, pile2);
}
} else {
- // XXX: We should always parse the packet into a
- // compressed data packet, even if we don't understand
- // the algorithm. See
- // https://gitlab.com/sequoia-pgp/sequoia/-/issues/830.
- // In the mean time, as a workaround, we check whether
- // we support the algorithm. Drop this once #830 is
- // addressed.
- if let Some(Packet::Unknown(u)) = po {
- // The first octet is the compression algorithm.
- let algo: CompressionAlgorithm = u.body()[0].into();
- if ! algo.is_supported() {
- continue;
- }
- }
-
panic!("Expected a compressed data data packet.");
}
}