From 7ce2694b07e61ae141f10606605b602e5b06c239 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 6 Jun 2019 09:33:38 -0700 Subject: [PATCH] Have DigestSigner/DigestVerifier take Digest instance This is needed forcompatibility with ed25519-dalek's Ed25519ph: https://docs.rs/ed25519-dalek/1.0.0-pre.1/ed25519_dalek/struct.Keypair.html#method.sign_prehashed Until const generics land, this API feels a lot cleaner to me. It gets all the `GenericArray` crap out of the way. It's also misuse resistant in that it ensures the prehashing is done by the relevant hash function, as opposed to the user being able to pass in arbitrary values. There's a potential attack if a verifier accidentally accepts a raw value which isn't the output of a hash function which could allow an attacker to forge signatures: https://twitter.com/pwuille/status/1063582706288586752 --- signature-crate/src/signer.rs | 8 ++++---- signature-crate/src/verifier.rs | 10 +++------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/signature-crate/src/signer.rs b/signature-crate/src/signer.rs index 2348c48e..46ec9d0d 100644 --- a/signature-crate/src/signer.rs +++ b/signature-crate/src/signer.rs @@ -1,7 +1,7 @@ //! Traits for generating digital signatures #[cfg(feature = "digest")] -use crate::digest::{generic_array::GenericArray, Digest}; +use crate::digest::Digest; use crate::{error::Error, Signature}; /// Sign the provided message bytestring using `Self` (e.g. a cryptographic key @@ -37,18 +37,18 @@ where /// Attempt to sign the computed digest of the given message. fn try_sign_msg_digest(&self, msg: &[u8]) -> Result { - self.try_sign_digest(D::digest(msg)) + self.try_sign_digest(D::new().chain(msg)) } /// Sign the given prehashed message `Digest`, returning a signature. /// /// Panics in the event of a signing error. - fn sign_digest(&self, digest: GenericArray) -> S { + fn sign_digest(&self, digest: D) -> S { self.try_sign_digest(digest) .expect("signature operation failed") } /// Attempt to sign the given prehashed message `Digest`, returning a /// digital signature on success, or an error if something went wrong. - fn try_sign_digest(&self, digest: GenericArray) -> Result; + fn try_sign_digest(&self, digest: D) -> Result; } diff --git a/signature-crate/src/verifier.rs b/signature-crate/src/verifier.rs index 1612cbf1..96aa7c58 100644 --- a/signature-crate/src/verifier.rs +++ b/signature-crate/src/verifier.rs @@ -1,7 +1,7 @@ //! Trait for verifying digital signatures #[cfg(feature = "digest")] -use crate::digest::{generic_array::GenericArray, Digest}; +use crate::digest::Digest; use crate::{error::Error, Signature}; /// Verify the provided message bytestring using `Self` (e.g. a public key) @@ -23,13 +23,9 @@ where { /// Verify the signature against the computed `Digest` output. fn verify_msg_digest(&self, msg: &[u8], signature: &S) -> Result<(), Error> { - self.verify_digest(D::digest(msg), signature) + self.verify_digest(D::new().chain(msg), signature) } /// Verify the signature against the given `Digest` output. - fn verify_digest( - &self, - digest: GenericArray, - signature: &S, - ) -> Result<(), Error>; + fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; }