diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2022-02-15 13:47:28 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2022-03-28 14:08:09 +0200 |
commit | b41958f99f24022f0f71e67bb57ab4def74267ca (patch) | |
tree | 4fe3fe4b964310d3852620b8e83ed3bf95e36b19 /openpgp/src | |
parent | f66d98e0fac7320af3e918bbb69f09b130df3d63 (diff) |
openpgp: Explicit SEIP packet version in the message parser.
- In order to deal with version 2 SEIP packets, we first need to be
explicit about the packet version in the message parser.
- Rename the token and grammar rules, pass in a version to
MessageParser::push.
Diffstat (limited to 'openpgp/src')
-rw-r--r-- | openpgp/src/message/grammar.lalrpop | 10 | ||||
-rw-r--r-- | openpgp/src/message/lexer.rs | 4 | ||||
-rw-r--r-- | openpgp/src/message/mod.rs | 105 | ||||
-rw-r--r-- | openpgp/src/parse.rs | 8 | ||||
-rw-r--r-- | openpgp/src/parse/packet_parser_builder.rs | 3 | ||||
-rw-r--r-- | openpgp/src/parse/stream.rs | 5 |
6 files changed, 79 insertions, 56 deletions
diff --git a/openpgp/src/message/grammar.lalrpop b/openpgp/src/message/grammar.lalrpop index ede7049b..f98b3786 100644 --- a/openpgp/src/message/grammar.lalrpop +++ b/openpgp/src/message/grammar.lalrpop @@ -16,9 +16,9 @@ CompressedData: () = { COMPRESSED_DATA Message POP }; -SeipPart: () = { - SEIP Message MDC POP, - SEIP OPAQUE_CONTENT POP, +Seipv1Part: () = { + SEIPv1 Message MDC POP, + SEIPv1 OPAQUE_CONTENT POP, } AedPart: () = { @@ -32,7 +32,7 @@ EncryptedPart: () = { }; EncryptionContainer: () = { - SeipPart, + Seipv1Part, AedPart, }; @@ -68,7 +68,7 @@ extern { COMPRESSED_DATA => lexer::Token::CompressedData, SKESK => lexer::Token::SKESK, PKESK => lexer::Token::PKESK, - SEIP => lexer::Token::SEIP, + SEIPv1 => lexer::Token::SEIPv1, MDC => lexer::Token::MDC, AED => lexer::Token::AED, OPS => lexer::Token::OPS, diff --git a/openpgp/src/message/lexer.rs b/openpgp/src/message/lexer.rs index e32f58ed..7289d748 100644 --- a/openpgp/src/message/lexer.rs +++ b/openpgp/src/message/lexer.rs @@ -25,8 +25,8 @@ pub enum Token { SKESK, /// An PK-ESK packet. PKESK, - /// A SEIP packet. - SEIP, + /// A version 1 SEIP packet. + SEIPv1, /// An MDC packet. MDC, /// An AED packet. diff --git a/openpgp/src/message/mod.rs b/openpgp/src/message/mod.rs index 9e734aa4..1834373b 100644 --- a/openpgp/src/message/mod.rs +++ b/openpgp/src/message/mod.rs @@ -194,7 +194,7 @@ impl MessageValidator { /// Unlike `push_token`, this function does not automatically /// account for changes in the depth. If you use this function /// directly, you must push any required `Token::Pop` tokens. - pub fn push(&mut self, tag: Tag, path: &[usize]) { + pub fn push(&mut self, tag: Tag, version: Option<u8>, path: &[usize]) { if self.error.is_some() { return; } @@ -204,7 +204,7 @@ impl MessageValidator { Tag::CompressedData => Token::CompressedData, Tag::SKESK => Token::SKESK, Tag::PKESK => Token::PKESK, - Tag::SEIP => Token::SEIP, + Tag::SEIP if version == Some(1) => Token::SEIPv1, Tag::MDC => Token::MDC, Tag::AED => Token::AED, Tag::OnePassSig => Token::OPS, @@ -447,7 +447,7 @@ impl TryFrom<PacketPile> for Message { {:?} packet (at {:?}) not expected: {}", u.tag(), path, u.error()))) .into()), - _ => v.push(packet.tag(), &path), + _ => v.push(packet.tag(), packet.version(), &path), } match packet { @@ -544,32 +544,32 @@ mod tests { result: true, }, TestVector { - s: &[SEIP, Literal, MDC, Pop], + s: &[SEIPv1, Literal, MDC, Pop], result: true, }, TestVector { - s: &[CompressedData, SEIP, Literal, MDC, Pop, Pop], + s: &[CompressedData, SEIPv1, Literal, MDC, Pop, Pop], result: true, }, TestVector { - s: &[CompressedData, SEIP, CompressedData, Literal, + s: &[CompressedData, SEIPv1, CompressedData, Literal, Pop, MDC, Pop, Pop], result: true, }, TestVector { - s: &[SEIP, MDC, Pop], + s: &[SEIPv1, MDC, Pop], result: false, }, TestVector { - s: &[SKESK, SEIP, Literal, MDC, Pop], + s: &[SKESK, SEIPv1, Literal, MDC, Pop], result: true, }, TestVector { - s: &[PKESK, SEIP, Literal, MDC, Pop], + s: &[PKESK, SEIPv1, Literal, MDC, Pop], result: true, }, TestVector { - s: &[SKESK, SKESK, SEIP, Literal, MDC, Pop], + s: &[SKESK, SKESK, SEIPv1, Literal, MDC, Pop], result: true, }, @@ -616,7 +616,7 @@ mod tests { result: false, }, TestVector { - s: &[OPS, OPS, SEIP, OPS, SEIP, Literal, MDC, Pop, + s: &[OPS, OPS, SEIPv1, OPS, SEIPv1, Literal, MDC, Pop, SIG, MDC, Pop, SIG, SIG], result: true, }, @@ -634,11 +634,11 @@ mod tests { result: true, }, TestVector { - s: &[SEIP, CompressedData, OpaqueContent, Pop, MDC, Pop], + s: &[SEIPv1, CompressedData, OpaqueContent, Pop, MDC, Pop], result: true, }, TestVector { - s: &[SEIP, OpaqueContent, Pop], + s: &[SEIPv1, OpaqueContent, Pop], result: true, }, ]; @@ -667,86 +667,101 @@ mod tests { use crate::packet::Tag::*; struct TestVector<'a> { - s: &'a [(Tag, isize)], + s: &'a [(Tag, Option<u8>, isize)], result: bool, } let test_vectors = [ TestVector { - s: &[(Literal, 0)][..], + s: &[(Literal, None, 0)][..], result: true, }, TestVector { - s: &[(CompressedData, 0), (Literal, 1)], + s: &[(CompressedData, None, 0), (Literal, None, 1)], result: true, }, TestVector { - s: &[(CompressedData, 0), (CompressedData, 1), (Literal, 2)], + s: &[(CompressedData, None, 0), (CompressedData, None, 1), + (Literal, None, 2)], result: true, }, TestVector { - s: &[(SEIP, 0), (Literal, 1), (MDC, 1)], + s: &[(SEIP, Some(1), 0), (Literal, None, 1), (MDC, None, 1)], result: true, }, TestVector { - s: &[(CompressedData, 0), (SEIP, 1), (Literal, 2), (MDC, 2)], + s: &[(CompressedData, None, 0), (SEIP, Some(1), 1), + (Literal, None, 2), (MDC, None, 2)], result: true, }, TestVector { - s: &[(CompressedData, 0), (SEIP, 1), - (CompressedData, 2), (Literal, 3), (MDC, 2)], + s: &[(CompressedData, None, 0), (SEIP, Some(1), 1), + (CompressedData, None, 2), (Literal, None, 3), + (MDC, None, 2)], result: true, }, TestVector { - s: &[(CompressedData, 0), (SEIP, 1), - (CompressedData, 2), (Literal, 3), (MDC, 3)], + s: &[(CompressedData, None, 0), (SEIP, Some(1), 1), + (CompressedData, None, 2), (Literal, None, 3), + (MDC, None, 3)], result: false, }, TestVector { - s: &[(SEIP, 0), (MDC, 0)], + s: &[(SEIP, Some(1), 0), (MDC, None, 0)], result: false, }, TestVector { - s: &[(SKESK, 0), (SEIP, 0), (Literal, 1), (MDC, 1)], + s: &[(SKESK, None, 0), (SEIP, Some(1), 0), (Literal, None, 1), + (MDC, None, 1)], result: true, }, TestVector { - s: &[(PKESK, 0), (SEIP, 0), (Literal, 1), (MDC, 1)], + s: &[(PKESK, None, 0), (SEIP, Some(1), 0), (Literal, None, 1), + (MDC, None, 1)], result: true, }, TestVector { - s: &[(PKESK, 0), (SEIP, 0), (CompressedData, 1), (Literal, 2), - (MDC, 1)], + s: &[(PKESK, None, 0), (SEIP, Some(1), 0), + (CompressedData, None, 1), (Literal, None, 2), + (MDC, None, 1)], result: true, }, TestVector { - s: &[(SKESK, 0), (SKESK, 0), (SEIP, 0), (Literal, 1), (MDC, 1)], + s: &[(SKESK, None, 0), (SKESK, None, 0), (SEIP, Some(1), 0), + (Literal, None, 1), (MDC, None, 1)], result: true, }, TestVector { - s: &[(OnePassSig, 0), (Literal, 0), (Signature, 0)], + s: &[(OnePassSig, None, 0), (Literal, None, 0), + (Signature, None, 0)], result: true, }, TestVector { - s: &[(OnePassSig, 0), (CompressedData, 0), (Literal, 1), - (Signature, 0)], + s: &[(OnePassSig, None, 0), (CompressedData, None, 0), + (Literal, None, 1), + (Signature, None, 0)], result: true, }, TestVector { - s: &[(OnePassSig, 0), (OnePassSig, 0), (Literal, 0), - (Signature, 0), (Signature, 0)], + s: &[(OnePassSig, None, 0), (OnePassSig, None, 0), + (Literal, None, 0), + (Signature, None, 0), (Signature, None, 0)], result: true, }, TestVector { - s: &[(OnePassSig, 0), (OnePassSig, 0), (Literal, 0), - (Signature, 0)], + s: &[(OnePassSig, None, 0), (OnePassSig, None, 0), + (Literal, None, 0), + (Signature, None, 0)], result: false, }, TestVector { - s: &[(OnePassSig, 0), (OnePassSig, 0), (SEIP, 0), - (OnePassSig, 1), (SEIP, 1), (Literal, 2), (MDC, 2), - (Signature, 1), (MDC, 1), (Signature, 0), (Signature, 0)], + s: &[(OnePassSig, None, 0), (OnePassSig, None, 0), + (SEIP, Some(1), 0), + (OnePassSig, None, 1), (SEIP, Some(1), 1), + (Literal, None, 2), (MDC, None, 2), + (Signature, None, 1), (MDC, None, 1), (Signature, None, 0), + (Signature, None, 0)], result: true, }, @@ -756,16 +771,18 @@ mod tests { // that version to report that newer software is necessary // to process the message.", section 5.8 of RFC4880. TestVector { - s: &[(Marker, 0), - (OnePassSig, 0), (Literal, 0), (Signature, 0)], + s: &[(Marker, None, 0), + (OnePassSig, None, 0), (Literal, None, 0), + (Signature, None, 0)], result: true, }, ]; for v in &test_vectors { let mut l = MessageValidator::new(); - for (token, depth) in v.s.iter() { + for (token, version, depth) in v.s.iter() { l.push(*token, + *version, &(0..1 + *depth) .map(|x| x as usize) .collect::<Vec<_>>()[..]); @@ -1208,7 +1225,7 @@ mod tests { use crate::packet::Tag; let mut l = MessageValidator::new(); - l.push(Tag::Literal, &[0]); + l.push(Tag::Literal, None, &[0]); l.finish(); assert!(matches!(l.check(), MessageValidity::Message)); @@ -1238,7 +1255,7 @@ mod tests { // Simple one-literal message. let mut l = MessageValidator::new(); - l.push(Tag::Literal, &[0]); + l.push(Tag::Literal, None, &[0]); assert!(matches!(l.check(), MessageValidity::MessagePrefix)); l.finish(); diff --git a/openpgp/src/parse.rs b/openpgp/src/parse.rs index 81549c50..a3514680 100644 --- a/openpgp/src/parse.rs +++ b/openpgp/src/parse.rs @@ -4592,7 +4592,9 @@ impl <'a> PacketParser<'a> { }, ParserResult::Success(mut pp) => { let path = pp.path().to_vec(); - pp.state.message_validator.push(pp.packet.tag(), &path); + pp.state.message_validator.push( + pp.packet.tag(), pp.packet.version(), + &path); pp.state.keyring_validator.push(pp.packet.tag()); pp.state.cert_validator.push(pp.packet.tag()); @@ -4680,7 +4682,9 @@ impl <'a> PacketParser<'a> { self.packet.tag(), pp.packet.tag()); pp.state.message_validator.push( - pp.packet.tag(), &path); + pp.packet.tag(), + pp.packet.version(), + &path); pp.state.keyring_validator.push(pp.packet.tag()); pp.state.cert_validator.push(pp.packet.tag()); diff --git a/openpgp/src/parse/packet_parser_builder.rs b/openpgp/src/parse/packet_parser_builder.rs index 24b9a13b..e23767a0 100644 --- a/openpgp/src/parse/packet_parser_builder.rs +++ b/openpgp/src/parse/packet_parser_builder.rs @@ -444,7 +444,8 @@ impl<'a> PacketParserBuilder<'a> { match PacketParser::parse(Box::new(self.bio), state, vec![ 0 ])? { ParserResult::Success(mut pp) => { // We successfully parsed the first packet's header. - pp.state.message_validator.push(pp.packet.tag(), &[0]); + pp.state.message_validator.push( + pp.packet.tag(), pp.packet.version(), &[0]); pp.state.keyring_validator.push(pp.packet.tag()); pp.state.cert_validator.push(pp.packet.tag()); Ok(PacketParserResult::Some(pp)) diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index 992b6f3c..4d2694ae 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -709,7 +709,7 @@ enum IMessageLayer { depth: isize, /// Do we expect an MDC packet? /// - /// I.e. is this a SEIP container? + /// I.e. is this a SEIPv1 container? expect_mdc: bool, sym_algo: SymmetricAlgorithm, aead_algo: Option<AEADAlgorithm>, @@ -2414,7 +2414,8 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { v.structure.new_encryption_layer( pp.recursion_depth(), - pp.packet.tag() == packet::Tag::SEIP, + pp.packet.tag() == packet::Tag::SEIP + && pp.packet.version() == Some(1), sym_algo, if let Packet::AED(ref p) = pp.packet { Some(p.aead()) |