diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-09-17 09:01:30 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-09-17 09:10:00 +0200 |
commit | 7c47f04c8c84ba585e59d7257e9114e7e7b10a8c (patch) | |
tree | c174a2647938c76f1cf1946d37de1efe0c02f829 | |
parent | 7d7e3457add3d3fe30f28471a2de9b0adf1de6b9 (diff) |
openpgp: Marker packets must be ignored, adapt heuristics.
- Marker packets must be ignored everywhere. Add them to the
heuristics detecting base64 encoded OpenPGP data in the armor
decoder, and to the packet parser's resyncing code.
- Fixes #546.
-rw-r--r-- | openpgp/src/armor.rs | 4 | ||||
-rw-r--r-- | openpgp/src/parse.rs | 33 |
2 files changed, 35 insertions, 2 deletions
diff --git a/openpgp/src/armor.rs b/openpgp/src/armor.rs index 2b6a3400..0cd071d7 100644 --- a/openpgp/src/armor.rs +++ b/openpgp/src/armor.rs @@ -643,7 +643,9 @@ impl<'a> Reader<'a> { for &tag in &[ Tag::PKESK, Tag::SKESK, Tag::OnePassSig, Tag::Signature, Tag::PublicKey, Tag::SecretKey, - Tag::CompressedData, Tag::Literal ] { + Tag::CompressedData, Tag::Literal, + Tag::Marker, + ] { let mut ctb = [ 0u8; 1 ]; let mut o = [ 0u8; 4 ]; diff --git a/openpgp/src/parse.rs b/openpgp/src/parse.rs index a5769120..de43c1c4 100644 --- a/openpgp/src/parse.rs +++ b/openpgp/src/parse.rs @@ -2336,6 +2336,36 @@ impl Marker { php.fail("invalid marker") } } + + /// Returns whether the data is a marker packet. + fn plausible<T>(bio: &mut buffered_reader::Dup<T, Cookie>, header: &Header) + -> Result<()> + where T: BufferedReader<Cookie>, + { + if let &BodyLength::Full(len) = header.length() { + if len as usize != Marker::BODY.len() { + return Err(Error::MalformedPacket( + format!("Unexpected packet length {}", len)).into()); + } + } else { + return Err(Error::MalformedPacket( + format!("Unexpected body length encoding: {:?}", + header.length()).into()).into()); + } + + // Check the body. + let data = bio.data(Marker::BODY.len())?; + if data.len() < Marker::BODY.len() { + return Err(Error::MalformedPacket("Short read".into()).into()); + } + + if data == Marker::BODY { + Ok(()) + } else { + Err(Error::MalformedPacket("Invalid or unsupported data".into()) + .into()) + } + } } impl_parse_generic_packet!(Marker); @@ -3940,10 +3970,11 @@ impl <'a> PacketParser<'a> { Error::MalformedPacket("Can't make an educated case".into()).into()); match header.ctb().tag() { - Tag::Reserved | Tag::Marker + Tag::Reserved | Tag::Unknown(_) | Tag::Private(_) => Err(Error::MalformedPacket("Looks like garbage".into()).into()), + Tag::Marker => Marker::plausible(bio, &header), Tag::Signature => Signature::plausible(bio, &header), Tag::SecretKey => Key::plausible(bio, &header), |