diff options
author | Neal H. Walfield <neal@pep.foundation> | 2018-11-20 14:54:18 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2018-11-20 14:59:30 +0100 |
commit | 411de0d1647bf205c18b096e3fbda7fd0be7e93c (patch) | |
tree | 690f08d17d49bb771cf7c18bb7210f3896ac9c8c /openpgp/src | |
parent | a1eba557ff62f09bef2c7e379a238c643ac240d7 (diff) |
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.
Diffstat (limited to 'openpgp/src')
-rw-r--r-- | openpgp/src/keyid.rs | 5 | ||||
-rw-r--r-- | openpgp/src/parse/stream.rs | 52 |
2 files changed, 55 insertions, 2 deletions
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<packet::PKESK> = Vec::new(); let mut skesks: Vec<packet::SKESK> = 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; |