From 411de0d1647bf205c18b096e3fbda7fd0be7e93c Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Tue, 20 Nov 2018 14:54:18 +0100 Subject: openpgp: Add basic support for old-style sigs to the Verifier. - Although the PacketParser doesn't support old-style signatures (see issue #128), the Verifier should not choke on them. - This change prevents the Verifier from choking by processing all old-style signatures in the usual manner. However, because the old-style signatures will have a computed hash of 000..., they will appear to be bad. --- openpgp/src/keyid.rs | 5 +++++ openpgp/src/parse/stream.rs | 52 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-) (limited to 'openpgp/src') diff --git a/openpgp/src/keyid.rs b/openpgp/src/keyid.rs index c4fae110..f55fe336 100644 --- a/openpgp/src/keyid.rs +++ b/openpgp/src/keyid.rs @@ -97,6 +97,11 @@ impl KeyID { } } + /// Returns the wildcard KeyID. + pub fn wildcard() -> Self { + Self::from_bytes(&[0u8; 8][..]) + } + /// Returns true if this is a wild card ID. pub fn is_wildcard(&self) -> bool { self.as_slice().iter().all(|b| *b == 0) diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index bf857231..5956ea01 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -241,6 +241,13 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { }; let mut issuers = Vec::new(); + // The following structure is allowed: + // + // SIG LITERAL + // + // In this case, we queue the signature packets. + let mut sigs = Vec::new(); + while let PacketParserResult::Some(pp) = ppr { if ! pp.possible_message() { return Err(Error::MalformedMessage( @@ -282,13 +289,27 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { v.oppr = Some(PacketParserResult::Some(pp)); v.finish_maybe()?; + + // Verify any queued signatures. + for sig in sigs.into_iter() { + v.verify(Packet::Signature(sig))?; + } + return Ok(v); }, _ => (), } let (p, ppr_tmp) = pp.recurse()?; - v.verify(p)?; + if let Packet::Signature(sig) = p { + if let Some(issuer) = sig.get_issuer() { + issuers.push(issuer); + } else { + issuers.push(KeyID::wildcard()); + } + sigs.push(sig); + } + ppr = ppr_tmp; } @@ -664,8 +685,16 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { }; let mut issuers = Vec::new(); + // The following structure is allowed: + // + // SIG LITERAL + // + // In this case, we queue the signature packets. + let mut sigs = Vec::new(); let mut pkesks: Vec = Vec::new(); let mut skesks: Vec = Vec::new(); + let mut saw_content = false; + while let PacketParserResult::Some(mut pp) = ppr { v.helper.inspect(&pp)?; if ! pp.possible_message() { @@ -676,6 +705,8 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { match pp.packet { Packet::SEIP(_) | Packet::AED(_) => { + saw_content = true; + let mut decrypted = false; let pkesk_refs: Vec<&PKESK> = pkesks.iter().collect(); let skesk_refs: Vec<&SKESK> = skesks.iter().collect(); @@ -779,6 +810,12 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { v.oppr = Some(PacketParserResult::Some(pp)); v.finish_maybe()?; + + // Verify any queued signatures. + for sig in sigs.into_iter() { + v.verify(Packet::Signature(sig))?; + } + return Ok(v); }, Packet::MDC(ref mdc) => if ! mdc.valid() { @@ -791,7 +828,18 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { match p { Packet::PKESK(pkesk) => pkesks.push(pkesk), Packet::SKESK(skesk) => skesks.push(skesk), - Packet::Signature(_) => v.verify(p)?, + Packet::Signature(sig) => { + if saw_content { + v.verify(Packet::Signature(sig))?; + } else { + if let Some(issuer) = sig.get_issuer() { + issuers.push(issuer); + } else { + issuers.push(KeyID::wildcard()); + } + sigs.push(sig); + } + } _ => (), } ppr = ppr_tmp; -- cgit v1.2.3