summaryrefslogtreecommitdiffstats
path: root/openpgp/src/crypto
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2022-11-11 09:32:25 +0100
committerNeal H. Walfield <neal@pep.foundation>2022-11-11 21:01:46 +0100
commit53474e58493cc10a9e021fde5ca1048a86859f2b (patch)
tree38bf36070d7aa5fb87d0e790809bad1003f5c5f2 /openpgp/src/crypto
parent813f3f00a967eea210641103b5e64e0d31299ae6 (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.rs31
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),
}
}