summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2022-02-16 12:11:23 +0100
committerJustus Winter <justus@sequoia-pgp.org>2022-02-16 12:31:19 +0100
commit72c829e39f3628f6bc8400b67045230f4449e8dc (patch)
treec11c78e0254b85c294bb62e8a9fef27fa8fdddbd
parent579113cd358d873f75b61a5688e86e934d04baa5 (diff)
openpgp: Fix verifying cleartext signed messages with multiple sigs.
- We implement the cleartext signature framework by transforming the message on the fly to a signed message, then using our parsing framework as usual. However, we need to tweak the behavior slightly. - Notably, our CSF transformation yields just one OPS packet per encountered 'Hash' algorithm header, and it cannot know how many signatures are in fact following. Therefore, the message will not be well-formed according to the grammar. But, since we created the message structure during the transformation, we know it is good, even if it is a little out of spec. - This patch tweaks the streaming verifier's behavior to accommodate this.
-rw-r--r--openpgp/src/parse.rs6
-rw-r--r--openpgp/src/parse/stream.rs96
-rw-r--r--openpgp/tests/data/keys/InRelease.signers.pgp406
-rw-r--r--openpgp/tests/data/messages/InRelease1258
4 files changed, 1759 insertions, 7 deletions
diff --git a/openpgp/src/parse.rs b/openpgp/src/parse.rs
index 3e5eead6..eaa10d29 100644
--- a/openpgp/src/parse.rs
+++ b/openpgp/src/parse.rs
@@ -4922,6 +4922,12 @@ impl <'a> PacketParser<'a> {
pub fn take_map(&mut self) -> Option<map::Map> {
self.map.take()
}
+
+ /// Checks if we are processing a signed message using the
+ /// Cleartext Signature Framework.
+ pub(crate) fn processing_csf_message(&self) -> bool {
+ Cookie::processing_csf_message(&self.reader)
+ }
}
/// This interface allows a caller to read the content of a
diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs
index bd0a07ce..992b6f3c 100644
--- a/openpgp/src/parse/stream.rs
+++ b/openpgp/src/parse/stream.rs
@@ -647,14 +647,23 @@ impl IMessageStructure {
}
}
- fn push_signature(&mut self, sig: Signature) {
+ fn push_signature(&mut self, sig: Signature, csf_message: bool) {
for layer in self.layers.iter_mut().rev() {
match layer {
IMessageLayer::SignatureGroup {
ref mut sigs, ref mut count,
} if *count > 0 => {
sigs.push(sig);
- *count -= 1;
+ if csf_message {
+ // The CSF transformation does not know how
+ // many signatures will follow, so we may end
+ // up with too few synthesized OPS packets.
+ // But, we only have one layer anyway, and no
+ // notarizations, so we don't need to concern
+ // ourself with the counter.
+ } else {
+ *count -= 1;
+ }
return;
},
_ => (),
@@ -1719,6 +1728,11 @@ pub struct Decryptor<'a, H: VerificationHelper + DecryptionHelper> {
/// The mode of operation.
mode: Mode,
+ /// Whether we are actually processing a cleartext signature
+ /// framework message. If so, we need to tweak our behavior a
+ /// bit.
+ processing_csf_message: Option<bool>,
+
/// Signature verification relative to this time.
///
/// This is needed for checking the signature's liveness.
@@ -2309,12 +2323,19 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
time,
clock_skew_tolerance: tolerance,
policy,
+ processing_csf_message: None, // We don't know yet.
};
let mut pkesks: Vec<packet::PKESK> = Vec::new();
let mut skesks: Vec<packet::SKESK> = Vec::new();
while let PacketParserResult::Some(mut pp) = ppr {
+ // Check whether we are actually processing a cleartext
+ // signature framework message.
+ if v.processing_csf_message.is_none() {
+ v.processing_csf_message = Some(pp.processing_csf_message());
+ }
+
v.policy.packet(&pp.packet)?;
v.helper.inspect(&pp)?;
@@ -2330,8 +2351,19 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
.into());
}
} else if let Err(err) = pp.possible_message() {
- t!("Malformed message: {}", err);
- return Err(err.context("Malformed OpenPGP message"));
+ if v.processing_csf_message.expect("set by now") {
+ // Our CSF transformation yields just one OPS
+ // packet per encountered 'Hash' algorithm header,
+ // and it cannot know how many signatures are in
+ // fact following. Therefore, the message will
+ // not be well-formed according to the grammar.
+ // But, since we created the message structure
+ // during the transformation, we know it is good,
+ // even if it is a little out of spec.
+ } else {
+ t!("Malformed message: {}", err);
+ return Err(err.context("Malformed OpenPGP message"));
+ }
}
let sym_algo_hint = if let Packet::AED(ref aed) = pp.packet {
@@ -2488,7 +2520,8 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
match p {
Packet::Signature(sig) => {
sig.get_issuers().into_iter().for_each(|i| self.push_issuer(i));
- self.structure.push_signature(sig);
+ self.structure.push_signature(
+ sig, self.processing_csf_message.expect("set by now"));
},
_ => (),
}
@@ -2603,8 +2636,14 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
}
if let Err(err) = possible_message {
- return Err(err.context(
- "Malformed OpenPGP message"));
+ if self.processing_csf_message.expect("set by now") {
+ // CSF transformation creates slightly out
+ // of spec message structure. See above
+ // for longer explanation.
+ } else {
+ return Err(err.context(
+ "Malformed OpenPGP message"));
+ }
}
self.push_sig(p)?;
@@ -3694,4 +3733,47 @@ EK8=
Ok(())
}
+
+ /// Tests whether messages using the cleartext signature framework
+ /// with multiple signatures and signers are correctly handled.
+ #[test]
+ fn csf_multiple_signers() -> Result<()> {
+ struct H(bool);
+ impl VerificationHelper for H {
+ fn get_certs(&mut self, _ids: &[crate::KeyHandle])
+ -> Result<Vec<Cert>> {
+ crate::cert::CertParser::from_bytes(
+ crate::tests::key("InRelease.signers.pgp"))?
+ .collect()
+ }
+
+ fn check(&mut self, m: MessageStructure)
+ -> Result<()> {
+ for (i, layer) in m.into_iter().enumerate() {
+ assert_eq!(i, 0);
+ if let MessageLayer::SignatureGroup { results } = layer {
+ assert_eq!(results.len(), 3);
+ for result in results {
+ assert!(result.is_ok());
+ }
+ self.0 = true;
+ } else {
+ panic!();
+ }
+ }
+
+ Ok(())
+ }
+ }
+
+ let p = &P::new();
+ let mut verifier = VerifierBuilder::from_bytes(
+ crate::tests::message("InRelease"))?
+ .with_policy(p, None, H(false))?;
+ let mut b = Vec::new();
+ verifier.read_to_end(&mut b)?;
+ let h = verifier.into_helper();
+ assert!(h.0);
+ Ok(())
+ }
}
diff --git a/openpgp/tests/data/keys/InRelease.signers.pgp b/openpgp/tests/data/keys/InRelease.signers.pgp
new file mode 100644
index 00000000..bb64d1e1
--- /dev/null
+++ b/openpgp/tests/data/keys/InRelease.signers.pgp
@@ -0,0 +1,406 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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