diff options
author | Neal H. Walfield <neal@pep.foundation> | 2022-11-11 09:32:25 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2022-11-11 21:01:46 +0100 |
commit | 53474e58493cc10a9e021fde5ca1048a86859f2b (patch) | |
tree | 38bf36070d7aa5fb87d0e790809bad1003f5c5f2 /openpgp/src/crypto | |
parent | 813f3f00a967eea210641103b5e64e0d31299ae6 (diff) |
openpgp: Add support for verifying v3 signatures.
- RFC 4880 explicitly allows the use of v3 signatures, but adds:
> Implementations SHOULD accept V3 signatures. Implementations
> SHOULD generate V4 signatures.
- In practice, rpm-based distributions are generating v3 signatures,
and it will be awhile before we can actually stop supporting them.
https://bugzilla.redhat.com/show_bug.cgi?id=2141686#c20
- Add support for parsing, verifying, and serializing v3
signatures (but not v3 certificates, and not generating v3
signatures!).
Diffstat (limited to 'openpgp/src/crypto')
-rw-r--r-- | openpgp/src/crypto/hash.rs | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/openpgp/src/crypto/hash.rs b/openpgp/src/crypto/hash.rs index 9af3de07..c4e7c4c8 100644 --- a/openpgp/src/crypto/hash.rs +++ b/openpgp/src/crypto/hash.rs @@ -40,7 +40,7 @@ use crate::packet::UserAttribute; use crate::packet::key; use crate::packet::key::Key4; use crate::packet::Signature; -use crate::packet::signature::{self, Signature4}; +use crate::packet::signature::{self, Signature3, Signature4}; use crate::Result; use crate::types::Timestamp; @@ -411,11 +411,39 @@ impl<P, R> Hash for Key4<P, R> impl Hash for Signature { fn hash(&self, hash: &mut dyn Digest) { match self { + Signature::V3(sig) => sig.hash(hash), Signature::V4(sig) => sig.hash(hash), } } } +impl Hash for Signature3 { + fn hash(&self, hash: &mut dyn Digest) { + // XXX: Annoyingly, we have no proper way of handling errors + // here. + + let mut buffer = [0u8; 5]; + + // Signature type. + buffer[0] = u8::from(self.typ()); + + // Creation time. + let creation_time: u32 = + Timestamp::try_from( + self.signature_creation_time() + .unwrap_or(std::time::UNIX_EPOCH)) + .unwrap_or_else(|_| Timestamp::from(0)) + .into(); + + buffer[1] = (creation_time >> 24) as u8; + buffer[2] = (creation_time >> 16) as u8; + buffer[3] = (creation_time >> 8) as u8; + buffer[4] = (creation_time ) as u8; + + hash.update(&buffer[..]); + } +} + impl Hash for Signature4 { fn hash(&self, hash: &mut dyn Digest) { self.fields.hash(hash); @@ -566,6 +594,7 @@ impl Signature { /// signature. pub fn hash_for_confirmation(&self, hash: &mut dyn Digest) { match self { + Signature::V3(s) => s.hash_for_confirmation(hash), Signature::V4(s) => s.hash_for_confirmation(hash), } } |