summaryrefslogtreecommitdiffstats
path: root/openpgp/src
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-11-16 13:54:56 +0100
committerJustus Winter <justus@sequoia-pgp.org>2020-11-24 13:27:51 +0100
commitfbbe3cf4ca6b6b1881160925f869065e8f3df58e (patch)
tree0a5313dac497810f9b7a06b6562ab89de2fd35e0 /openpgp/src
parent03598e4da99dbaf4c9f978e8f6f57ce3f6720b48 (diff)
openpgp: Align hashing of compound objects with primitive objects.
Diffstat (limited to 'openpgp/src')
-rw-r--r--openpgp/src/cert.rs19
-rw-r--r--openpgp/src/crypto/hash.rs113
-rw-r--r--openpgp/src/packet/signature.rs103
3 files changed, 120 insertions, 115 deletions
diff --git a/openpgp/src/cert.rs b/openpgp/src/cert.rs
index f6232bc6..65a47486 100644
--- a/openpgp/src/cert.rs
+++ b/openpgp/src/cert.rs
@@ -1482,9 +1482,12 @@ impl Cert {
.into_iter()
{
// Use hash prefix as heuristic.
- match Signature::$hash_method(&sig,
- self.primary.key(),
- $($verify_args),*) {
+ let key = self.primary.key();
+ match sig.hash_algo().context().and_then(|mut ctx| {
+ Signature::$hash_method(&mut ctx, &sig, key,
+ $($verify_args),*);
+ ctx.into_digest()
+ }) {
Ok(hash) => {
if &sig.digest_prefix()[..] == &hash[..2] {
// See if we can get the key for a
@@ -1706,8 +1709,14 @@ impl Cert {
}
} else {
// Use hash prefix as heuristic.
- if let Ok(hash) = Signature::$hash_method(
- &sig, self.primary.key(), $($verify_args),*) {
+ let key = self.primary.key();
+ if let Ok(hash) = sig.hash_algo().context()
+ .and_then(|mut ctx| {
+ Signature::$hash_method(&mut ctx, &sig, key,
+ $($verify_args),*);
+ ctx.into_digest()
+ })
+ {
if &sig.digest_prefix()[..] == &hash[..2] {
t!("Sig {:02X}{:02X}, {:?} \
was out of place. Likely belongs to {}.",
diff --git a/openpgp/src/crypto/hash.rs b/openpgp/src/crypto/hash.rs
index 5517d205..9221e070 100644
--- a/openpgp/src/crypto/hash.rs
+++ b/openpgp/src/crypto/hash.rs
@@ -113,6 +113,13 @@ impl Context {
pub fn digest<D: AsMut<[u8]>>(&mut self, mut digest: D) -> Result<()> {
self.ctx.digest(digest.as_mut())
}
+
+ /// Finalizes the hash function and computes the digest.
+ pub fn into_digest(mut self) -> Result<Vec<u8>> {
+ let mut digest = vec![0u8; self.digest_size()];
+ self.digest(&mut digest)?;
+ Ok(digest)
+ }
}
impl io::Write for Context {
@@ -382,112 +389,81 @@ impl Hash for signature::SignatureFields {
/// <a name="hashing-functions"></a>
impl Signature {
/// Computes the message digest of standalone signatures.
- pub fn hash_standalone(sig: &signature::SignatureFields)
- -> Result<Vec<u8>>
+ pub fn hash_standalone(hash: &mut Context,
+ sig: &signature::SignatureFields)
{
- let mut h = sig.hash_algo().context()?;
-
- sig.hash(&mut h);
-
- let mut digest = vec![0u8; h.digest_size()];
- h.digest(&mut digest)?;
- Ok(digest)
+ sig.hash(hash);
}
/// Computes the message digest of timestamp signatures.
- pub fn hash_timestamp(sig: &signature::SignatureFields)
- -> Result<Vec<u8>>
+ pub fn hash_timestamp(hash: &mut Context,
+ sig: &signature::SignatureFields)
{
- Self::hash_standalone(sig)
+ Self::hash_standalone(hash, sig);
}
/// Returns the message digest of the direct key signature over
/// the specified primary key.
- pub fn hash_direct_key<P>(sig: &signature::SignatureFields,
+ pub fn hash_direct_key<P>(hash: &mut Context,
+ sig: &signature::SignatureFields,
key: &Key<P, key::PrimaryRole>)
- -> Result<Vec<u8>>
where P: key::KeyParts,
{
-
- let mut h = sig.hash_algo().context()?;
-
- key.hash(&mut h);
- sig.hash(&mut h);
-
- let mut digest = vec![0u8; h.digest_size()];
- h.digest(&mut digest)?;
- Ok(digest)
+ key.hash(hash);
+ sig.hash(hash);
}
/// Returns the message digest of the subkey binding over the
/// specified primary key and subkey.
- pub fn hash_subkey_binding<P, Q>(sig: &signature::SignatureFields,
+ pub fn hash_subkey_binding<P, Q>(hash: &mut Context,
+ sig: &signature::SignatureFields,
key: &Key<P, key::PrimaryRole>,
subkey: &Key<Q, key::SubordinateRole>)
- -> Result<Vec<u8>>
where P: key::KeyParts,
Q: key::KeyParts,
{
- let mut h = sig.hash_algo().context()?;
-
- key.hash(&mut h);
- subkey.hash(&mut h);
- sig.hash(&mut h);
-
- let mut digest = vec![0u8; h.digest_size()];
- h.digest(&mut digest)?;
- Ok(digest)
+ key.hash(hash);
+ subkey.hash(hash);
+ sig.hash(hash);
}
/// Returns the message digest of the primary key binding over the
/// specified primary key and subkey.
- pub fn hash_primary_key_binding<P, Q>(sig: &signature::SignatureFields,
+ pub fn hash_primary_key_binding<P, Q>(hash: &mut Context,
+ sig: &signature::SignatureFields,
key: &Key<P, key::PrimaryRole>,
subkey: &Key<Q, key::SubordinateRole>)
- -> Result<Vec<u8>>
where P: key::KeyParts,
Q: key::KeyParts,
{
- Self::hash_subkey_binding(sig, key, subkey)
+ Self::hash_subkey_binding(hash, sig, key, subkey);
}
/// Returns the message digest of the user ID binding over the
/// specified primary key, user ID, and signature.
- pub fn hash_userid_binding<P>(sig: &signature::SignatureFields,
+ pub fn hash_userid_binding<P>(hash: &mut Context,
+ sig: &signature::SignatureFields,
key: &Key<P, key::PrimaryRole>,
userid: &UserID)
- -> Result<Vec<u8>>
where P: key::KeyParts,
{
- let mut h = sig.hash_algo().context()?;
-
- key.hash(&mut h);
- userid.hash(&mut h);
- sig.hash(&mut h);
-
- let mut digest = vec![0u8; h.digest_size()];
- h.digest(&mut digest)?;
- Ok(digest)
+ key.hash(hash);
+ userid.hash(hash);
+ sig.hash(hash);
}
/// Returns the message digest of the user attribute binding over
/// the specified primary key, user attribute, and signature.
pub fn hash_user_attribute_binding<P>(
+ hash: &mut Context,
sig: &signature::SignatureFields,
key: &Key<P, key::PrimaryRole>,
ua: &UserAttribute)
- -> Result<Vec<u8>>
where P: key::KeyParts,
{
- let mut h = sig.hash_algo().context()?;
-
- key.hash(&mut h);
- ua.hash(&mut h);
- sig.hash(&mut h);
-
- let mut digest = vec![0u8; h.digest_size()];
- h.digest(&mut digest)?;
- Ok(digest)
+ key.hash(hash);
+ ua.hash(hash);
+ sig.hash(hash);
}
}
@@ -503,10 +479,13 @@ mod test {
let mut userid_sigs = 0;
for (i, binding) in cert.userids().enumerate() {
for selfsig in binding.self_signatures() {
- let h = Signature::hash_userid_binding(
+ let mut hash = selfsig.hash_algo().context().unwrap();
+ Signature::hash_userid_binding(
+ &mut hash,
selfsig,
cert.primary_key().key(),
- binding.userid()).unwrap();
+ binding.userid());
+ let h = hash.into_digest().unwrap();
if &h[..2] != selfsig.digest_prefix() {
eprintln!("{:?}: {:?} / {:?}",
i, binding.userid(), selfsig);
@@ -520,10 +499,13 @@ mod test {
for (i, a) in cert.user_attributes().enumerate()
{
for selfsig in a.self_signatures() {
- let h = Signature::hash_user_attribute_binding(
+ let mut hash = selfsig.hash_algo().context().unwrap();
+ Signature::hash_user_attribute_binding(
+ &mut hash,
selfsig,
cert.primary_key().key(),
- a.user_attribute()).unwrap();
+ a.user_attribute());
+ let h = hash.into_digest().unwrap();
if &h[..2] != selfsig.digest_prefix() {
eprintln!("{:?}: {:?} / {:?}",
i, a.user_attribute(), selfsig);
@@ -536,10 +518,13 @@ mod test {
let mut subkey_sigs = 0;
for (i, binding) in cert.subkeys().enumerate() {
for selfsig in binding.self_signatures() {
- let h = Signature::hash_subkey_binding(
+ let mut hash = selfsig.hash_algo().context().unwrap();
+ Signature::hash_subkey_binding(
+ &mut hash,
selfsig,
cert.primary_key().key(),
- binding.key()).unwrap();
+ binding.key());
+ let h = hash.into_digest().unwrap();
if &h[..2] != selfsig.digest_prefix() {
eprintln!("{:?}: {:?}", i, binding);
eprintln!(" Hash: {:?}", h);
diff --git a/openpgp/src/packet/signature.rs b/openpgp/src/packet/signature.rs
index 07ba1098..e0cf5d37 100644
--- a/openpgp/src/packet/signature.rs
+++ b/openpgp/src/packet/signature.rs
@@ -577,9 +577,9 @@ impl SignatureBuilder {
self = self.pre_sign(signer)?;
- let digest = Signature::hash_standalone(&self)?;
-
- self.sign(signer, digest)
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_standalone(&mut hash, &self);
+ self.sign(signer, hash.into_digest()?)
}
/// Generates a Timestamp Signature.
@@ -690,9 +690,9 @@ impl SignatureBuilder {
self = self.pre_sign(signer)?;
- let digest = Signature::hash_timestamp(&self)?;
-
- self.sign(signer, digest)
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_timestamp(&mut hash, &self);
+ self.sign(signer, hash.into_digest()?)
}
/// Generates a Direct Key Signature.
@@ -813,9 +813,9 @@ impl SignatureBuilder {
self = self.pre_sign(signer)?;
- let digest = Signature::hash_direct_key(&self, pk)?;
-
- self.sign(signer, digest)
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_direct_key(&mut hash, &self, pk);
+ self.sign(signer, hash.into_digest()?)
}
/// Generates a User ID binding signature.
@@ -950,9 +950,9 @@ impl SignatureBuilder {
self = self.pre_sign(signer)?;
- let digest = Signature::hash_userid_binding(&self, key, userid)?;
-
- self.sign(signer, digest)
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_userid_binding(&mut hash, &self, key, userid);
+ self.sign(signer, hash.into_digest()?)
}
/// Generates a subkey binding signature.
@@ -1070,9 +1070,9 @@ impl SignatureBuilder {
self = self.pre_sign(signer)?;
- let digest = Signature::hash_subkey_binding(&self, primary, subkey)?;
-
- self.sign(signer, digest)
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_subkey_binding(&mut hash, &self, primary, subkey);
+ self.sign(signer, hash.into_digest()?)
}
/// Generates a primary key binding signature.
@@ -1218,10 +1218,9 @@ impl SignatureBuilder {
self = self.pre_sign(subkey_signer)?;
- let digest =
- Signature::hash_primary_key_binding(&self, primary, subkey)?;
-
- self.sign(subkey_signer, digest)
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_primary_key_binding(&mut hash, &self, primary, subkey);
+ self.sign(subkey_signer, hash.into_digest()?)
}
@@ -1353,10 +1352,9 @@ impl SignatureBuilder {
self = self.pre_sign(signer)?;
- let digest =
- Signature::hash_user_attribute_binding(&self, key, ua)?;
-
- self.sign(signer, digest)
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_user_attribute_binding(&mut hash, &self, key, ua);
+ self.sign(signer, hash.into_digest()?)
}
/// Generates a signature.
@@ -2419,8 +2417,9 @@ impl Signature {
// Standalone signatures are like binary-signatures over the
// zero-sized string.
- let digest = Signature::hash_standalone(self)?;
- self.verify_digest(key, &digest[..])
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_standalone(&mut hash, &self);
+ self.verify_digest(key, &hash.into_digest()?[..])
}
/// Verifies the timestamp signature using `key`.
@@ -2446,8 +2445,9 @@ impl Signature {
// Timestamp signatures are like binary-signatures over the
// zero-sized string.
- let digest = Signature::hash_timestamp(self)?;
- self.verify_digest(key, &digest[..])
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_timestamp(&mut hash, &self);
+ self.verify_digest(key, &hash.into_digest()?[..])
}
/// Verifies the direct key signature.
@@ -2481,8 +2481,9 @@ impl Signature {
return Err(Error::UnsupportedSignatureType(self.typ()).into());
}
- let hash = Signature::hash_direct_key(self, pk)?;
- self.verify_digest(signer, &hash[..])
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_direct_key(&mut hash, &self, pk);
+ self.verify_digest(signer, &hash.into_digest()?[..])
}
/// Verifies the primary key revocation certificate.
@@ -2516,8 +2517,9 @@ impl Signature {
return Err(Error::UnsupportedSignatureType(self.typ()).into());
}
- let hash = Signature::hash_direct_key(self, pk)?;
- self.verify_digest(signer, &hash[..])
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_direct_key(&mut hash, &self, pk);
+ self.verify_digest(signer, &hash.into_digest()?[..])
}
/// Verifies the subkey binding.
@@ -2559,8 +2561,9 @@ impl Signature {
return Err(Error::UnsupportedSignatureType(self.typ()).into());
}
- let hash = Signature::hash_subkey_binding(self, pk, subkey)?;
- self.verify_digest(signer, &hash[..])?;
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_subkey_binding(&mut hash, &self, pk, subkey);
+ self.verify_digest(signer, &hash.into_digest()?[..])?;
// The signature is good, but we may still need to verify the
// back sig.
@@ -2622,8 +2625,9 @@ impl Signature {
return Err(Error::UnsupportedSignatureType(self.typ()).into());
}
- let hash = Signature::hash_primary_key_binding(self, pk, subkey)?;
- self.verify_digest(subkey, &hash[..])
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_primary_key_binding(&mut hash, &self, pk, subkey);
+ self.verify_digest(subkey, &hash.into_digest()?[..])
}
/// Verifies the subkey revocation.
@@ -2660,8 +2664,9 @@ impl Signature {
return Err(Error::UnsupportedSignatureType(self.typ()).into());
}
- let hash = Signature::hash_subkey_binding(self, pk, subkey)?;
- self.verify_digest(signer, &hash[..])
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_subkey_binding(&mut hash, &self, pk, subkey);
+ self.verify_digest(signer, &hash.into_digest()?[..])
}
/// Verifies the user id binding.
@@ -2699,8 +2704,9 @@ impl Signature {
return Err(Error::UnsupportedSignatureType(self.typ()).into());
}
- let hash = Signature::hash_userid_binding(self, pk, userid)?;
- self.verify_digest(signer, &hash[..])
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_userid_binding(&mut hash, &self, pk, userid);
+ self.verify_digest(signer, &hash.into_digest()?[..])
}
/// Verifies the user id revocation certificate.
@@ -2735,8 +2741,9 @@ impl Signature {
return Err(Error::UnsupportedSignatureType(self.typ()).into());
}
- let hash = Signature::hash_userid_binding(self, pk, userid)?;
- self.verify_digest(signer, &hash[..])
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_userid_binding(&mut hash, &self, pk, userid);
+ self.verify_digest(signer, &hash.into_digest()?[..])
}
/// Verifies the user attribute binding.
@@ -2774,8 +2781,9 @@ impl Signature {
return Err(Error::UnsupportedSignatureType(self.typ()).into());
}
- let hash = Signature::hash_user_attribute_binding(self, pk, ua)?;
- self.verify_digest(signer, &hash[..])
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_user_attribute_binding(&mut hash, &self, pk, ua);
+ self.verify_digest(signer, &hash.into_digest()?[..])
}
/// Verifies the user attribute revocation certificate.
@@ -2811,8 +2819,9 @@ impl Signature {
return Err(Error::UnsupportedSignatureType(self.typ()).into());
}
- let hash = Signature::hash_user_attribute_binding(self, pk, ua)?;
- self.verify_digest(signer, &hash[..])
+ let mut hash = self.hash_algo().context()?;
+ Signature::hash_user_attribute_binding(&mut hash, &self, pk, ua);
+ self.verify_digest(signer, &hash.into_digest()?[..])
}
/// Verifies a signature of a message.
@@ -3267,7 +3276,9 @@ mod test {
let p = Packet::from_bytes(crate::tests::file(
"contrib/gnupg/timestamp-signature-by-alice.asc")).unwrap();
if let Packet::Signature(mut sig) = p {
- let digest = Signature::hash_standalone(&sig).unwrap();
+ let mut hash = sig.hash_algo().context().unwrap();
+ Signature::hash_standalone(&mut hash, &sig);
+ let digest = hash.into_digest().unwrap();
eprintln!("{}", crate::fmt::hex::encode(&digest));
sig.verify_timestamp(alpha.primary_key().key()).unwrap();
} else {