From 84fcd8668cfaf531cd84ba1089b05ba1cc9cba7e Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 30 Oct 2022 13:32:08 +0300 Subject: [PATCH] feat: switch to version 2.0 (pre) of the signature crate Rework the crate to implement traits from the preview of the signature crate. Use Vec as Self::Repr type. Signed-off-by: Dmitry Baryshkov --- Cargo.toml | 4 +-- src/lib.rs | 8 ++--- src/pkcs1v15.rs | 84 ++++++++++++++++++++++------------------------ src/pss.rs | 89 ++++++++++++++++++++++++------------------------- 4 files changed, 88 insertions(+), 97 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 929573b2..e38c42eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ subtle = { version = "2.1.1", default-features = false } digest = { version = "0.10.5", default-features = false, features = ["alloc", "oid"] } pkcs1 = { version = "0.4", default-features = false, features = ["pkcs8", "alloc"] } pkcs8 = { version = "0.9", default-features = false, features = ["alloc"] } -signature = { version = "1.6.4", default-features = false , features = ["digest-preview", "rand-preview"] } +signature = { version = "2.0.0-pre", default-features = false , features = ["digest-preview", "rand-preview"] } zeroize = { version = "1", features = ["alloc"] } # Temporary workaround until https://github.com/dignifiedquire/num-bigint/pull/42 lands @@ -53,7 +53,7 @@ name = "key" [features] default = ["std", "pem"] -hazmat = ["signature/hazmat-preview"] +hazmat = [] nightly = ["num-bigint/nightly"] serde = ["num-bigint/serde", "serde_crate"] expose-internals = [] diff --git a/src/lib.rs b/src/lib.rs index 14f33e92..e38e3b07 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,7 +52,7 @@ //! use rsa::RsaPrivateKey; //! use rsa::pkcs1v15::{SigningKey, VerifyingKey}; //! use sha2::{Digest, Sha256}; -//! use signature::{RandomizedSigner, Signature, Verifier}; +//! use signature::{RandomizedSigner, SignatureEncoding, Verifier}; //! //! let mut rng = rand::thread_rng(); //! @@ -64,7 +64,7 @@ //! // Sign //! let data = b"hello world"; //! let signature = signing_key.sign_with_rng(&mut rng, data); -//! assert_ne!(signature.as_bytes(), data); +//! assert_ne!(signature.to_bytes().as_ref(), data.as_slice()); //! //! // Verify //! verifying_key.verify(data, &signature).expect("failed to verify"); @@ -75,7 +75,7 @@ //! use rsa::RsaPrivateKey; //! use rsa::pss::{BlindedSigningKey, VerifyingKey}; //! use sha2::{Digest, Sha256}; -//! use signature::{RandomizedSigner, Signature, Verifier}; +//! use signature::{RandomizedSigner, SignatureEncoding, Verifier}; //! //! let mut rng = rand::thread_rng(); //! @@ -87,7 +87,7 @@ //! // Sign //! let data = b"hello world"; //! let signature = signing_key.sign_with_rng(&mut rng, data); -//! assert_ne!(signature.as_bytes(), data); +//! assert_ne!(signature.to_bytes().as_ref(), data); //! //! // Verify //! verifying_key.verify(data, &signature).expect("failed to verify"); diff --git a/src/pkcs1v15.rs b/src/pkcs1v15.rs index 5fb377e8..a4185845 100644 --- a/src/pkcs1v15.rs +++ b/src/pkcs1v15.rs @@ -1,16 +1,15 @@ -use alloc::vec; +use alloc::boxed::Box; use alloc::vec::Vec; use core::fmt::{Debug, Display, Formatter, LowerHex, UpperHex}; use core::marker::PhantomData; -use core::ops::Deref; use digest::Digest; use pkcs8::{AssociatedOid, Document, EncodePrivateKey, EncodePublicKey, SecretDocument}; use rand_core::{CryptoRng, RngCore}; #[cfg(feature = "hazmat")] use signature::hazmat::{PrehashSigner, PrehashVerifier}; use signature::{ - DigestSigner, DigestVerifier, RandomizedDigestSigner, RandomizedSigner, - Signature as SignSignature, Signer, Verifier, + DigestSigner, DigestVerifier, RandomizedDigestSigner, RandomizedSigner, SignatureEncoding, + Signer, Verifier, }; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; use zeroize::Zeroizing; @@ -20,60 +19,52 @@ use crate::errors::{Error, Result}; use crate::key::{self, PrivateKey, PublicKey}; use crate::{RsaPrivateKey, RsaPublicKey}; -#[derive(Clone)] +#[derive(Clone, PartialEq, Eq)] pub struct Signature { - bytes: Vec, + bytes: Box<[u8]>, } -impl signature::Signature for Signature { - fn from_bytes(bytes: &[u8]) -> signature::Result { - Ok(Signature { - bytes: bytes.into(), - }) - } - - fn as_bytes(&self) -> &[u8] { - self.bytes.as_slice() - } +impl SignatureEncoding for Signature { + type Repr = Box<[u8]>; } -impl From> for Signature { - fn from(bytes: Vec) -> Self { +impl From> for Signature { + fn from(bytes: Box<[u8]>) -> Self { Self { bytes } } } -impl Deref for Signature { - type Target = [u8]; +impl<'a> TryFrom<&'a [u8]> for Signature { + type Error = signature::Error; - fn deref(&self) -> &Self::Target { - self.as_bytes() + fn try_from(bytes: &'a [u8]) -> signature::Result { + Ok(Self { + bytes: bytes.into(), + }) } } -impl PartialEq for Signature { - fn eq(&self, other: &Self) -> bool { - self.as_bytes() == other.as_bytes() +impl From for Box<[u8]> { + fn from(signature: Signature) -> Box<[u8]> { + signature.bytes } } -impl Eq for Signature {} - -impl Debug for Signature { - fn fmt(&self, fmt: &mut Formatter<'_>) -> core::result::Result<(), core::fmt::Error> { - fmt.debug_list().entries(self.as_bytes().iter()).finish() +impl AsRef<[u8]> for Signature { + fn as_ref(&self) -> &[u8] { + self.bytes.as_ref() } } -impl AsRef<[u8]> for Signature { - fn as_ref(&self) -> &[u8] { - self.as_bytes() +impl Debug for Signature { + fn fmt(&self, fmt: &mut Formatter<'_>) -> core::result::Result<(), core::fmt::Error> { + fmt.debug_list().entries(self.bytes.iter()).finish() } } impl LowerHex for Signature { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - for byte in self.as_bytes() { + for byte in self.bytes.iter() { write!(f, "{:02x}", byte)?; } Ok(()) @@ -82,7 +73,7 @@ impl LowerHex for Signature { impl UpperHex for Signature { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - for byte in self.as_bytes() { + for byte in self.bytes.iter() { write!(f, "{:02X}", byte)?; } Ok(()) @@ -391,7 +382,7 @@ where { fn try_sign(&self, msg: &[u8]) -> signature::Result { sign::(None, &self.inner, &self.prefix, &D::digest(msg)) - .map(|v| v.into()) + .map(|v| v.into_boxed_slice().into()) .map_err(|e| e.into()) } } @@ -406,7 +397,7 @@ where msg: &[u8], ) -> signature::Result { sign(Some(&mut rng), &self.inner, &self.prefix, &D::digest(msg)) - .map(|v| v.into()) + .map(|v| v.into_boxed_slice().into()) .map_err(|e| e.into()) } } @@ -417,7 +408,7 @@ where { fn try_sign_digest(&self, digest: D) -> signature::Result { sign::(None, &self.inner, &self.prefix, &digest.finalize()) - .map(|v| v.into()) + .map(|v| v.into_boxed_slice().into()) .map_err(|e| e.into()) } } @@ -437,7 +428,7 @@ where &self.prefix, &digest.finalize(), ) - .map(|v| v.into()) + .map(|v| v.into_boxed_slice().into()) .map_err(|e| e.into()) } } @@ -449,7 +440,7 @@ where { fn sign_prehash(&self, prehash: &[u8]) -> signature::Result { sign::(None, &self.inner, &self.prefix, prehash) - .map(|v| v.into()) + .map(|v| v.into_boxed_slice().into()) .map_err(|e| e.into()) } } @@ -604,7 +595,7 @@ mod tests { use sha1::{Digest, Sha1}; use sha2::Sha256; use sha3::Sha3_256; - use signature::{RandomizedSigner, Signature, Signer, Verifier}; + use signature::{RandomizedSigner, Signer, Verifier}; use crate::{PaddingScheme, PublicKey, PublicKeyParts, RsaPrivateKey, RsaPublicKey}; @@ -898,8 +889,10 @@ mod tests { let verifying_key = VerifyingKey::::new_with_prefix(pub_key); for (text, sig, expected) in &tests { - let result = - verifying_key.verify(text.as_bytes(), &Signature::from_bytes(sig).unwrap()); + let result = verifying_key.verify( + text.as_bytes(), + &Signature::try_from(sig.as_slice()).unwrap(), + ); match expected { true => result.expect("failed to verify"), false => { @@ -937,7 +930,8 @@ mod tests { for (text, sig, expected) in &tests { let mut digest = Sha1::new(); digest.update(text.as_bytes()); - let result = verifying_key.verify_digest(digest, &Signature::from_bytes(sig).unwrap()); + let result = + verifying_key.verify_digest(digest, &Signature::try_from(sig.as_slice()).unwrap()); match expected { true => result.expect("failed to verify"), false => { @@ -976,7 +970,7 @@ mod tests { let verifying_key: VerifyingKey<_> = (&signing_key).into(); verifying_key - .verify_prehash(msg, &Signature::from_bytes(&expected_sig).unwrap()) + .verify_prehash(msg, &Signature::from_bytes(&expected_sig.into_boxed_slice()).unwrap()) .expect("failed to verify"); } } diff --git a/src/pss.rs b/src/pss.rs index e9a8953e..bfd59575 100644 --- a/src/pss.rs +++ b/src/pss.rs @@ -1,16 +1,15 @@ -use alloc::vec; +use alloc::boxed::Box; use alloc::vec::Vec; use core::fmt::{Debug, Display, Formatter, LowerHex, UpperHex}; use core::marker::PhantomData; -use core::ops::Deref; use digest::{Digest, DynDigest, FixedOutputReset}; use pkcs8::{Document, EncodePrivateKey, EncodePublicKey, SecretDocument}; use rand_core::{CryptoRng, RngCore}; #[cfg(feature = "hazmat")] use signature::hazmat::{PrehashVerifier, RandomizedPrehashSigner}; use signature::{ - DigestVerifier, RandomizedDigestSigner, RandomizedSigner, Signature as SignSignature, Verifier, + DigestVerifier, RandomizedDigestSigner, RandomizedSigner, SignatureEncoding, Verifier, }; use subtle::ConstantTimeEq; @@ -19,60 +18,52 @@ use crate::errors::{Error, Result}; use crate::key::{PrivateKey, PublicKey}; use crate::{RsaPrivateKey, RsaPublicKey}; -#[derive(Clone)] +#[derive(Clone, PartialEq, Eq)] pub struct Signature { - bytes: Vec, + bytes: Box<[u8]>, } -impl signature::Signature for Signature { - fn from_bytes(bytes: &[u8]) -> signature::Result { - Ok(Signature { - bytes: bytes.into(), - }) - } - - fn as_bytes(&self) -> &[u8] { - self.bytes.as_slice() - } +impl SignatureEncoding for Signature { + type Repr = Box<[u8]>; } -impl From> for Signature { - fn from(bytes: Vec) -> Self { +impl From> for Signature { + fn from(bytes: Box<[u8]>) -> Self { Self { bytes } } } -impl Deref for Signature { - type Target = [u8]; +impl<'a> TryFrom<&'a [u8]> for Signature { + type Error = signature::Error; - fn deref(&self) -> &Self::Target { - self.as_bytes() + fn try_from(bytes: &'a [u8]) -> signature::Result { + Ok(Self { + bytes: bytes.into(), + }) } } -impl PartialEq for Signature { - fn eq(&self, other: &Self) -> bool { - self.as_bytes() == other.as_bytes() +impl From for Box<[u8]> { + fn from(signature: Signature) -> Box<[u8]> { + signature.bytes } } -impl Eq for Signature {} - impl Debug for Signature { fn fmt(&self, fmt: &mut Formatter<'_>) -> core::result::Result<(), core::fmt::Error> { - fmt.debug_list().entries(self.as_bytes().iter()).finish() + fmt.debug_list().entries(self.bytes.iter()).finish() } } impl AsRef<[u8]> for Signature { fn as_ref(&self) -> &[u8] { - self.as_bytes() + self.bytes.as_ref() } } impl LowerHex for Signature { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - for byte in self.as_bytes() { + for byte in self.bytes.iter() { write!(f, "{:02x}", byte)?; } Ok(()) @@ -81,7 +72,7 @@ impl LowerHex for Signature { impl UpperHex for Signature { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - for byte in self.as_bytes() { + for byte in self.bytes.iter() { write!(f, "{:02X}", byte)?; } Ok(()) @@ -593,7 +584,7 @@ where msg: &[u8], ) -> signature::Result { sign_digest::<_, _, D>(&mut rng, false, &self.inner, &D::digest(msg), self.salt_len) - .map(|v| v.into()) + .map(|v| v.into_boxed_slice().into()) .map_err(|e| e.into()) } } @@ -614,7 +605,7 @@ where &digest.finalize(), self.salt_len, ) - .map(|v| v.into()) + .map(|v| v.into_boxed_slice().into()) .map_err(|e| e.into()) } } @@ -630,7 +621,7 @@ where prehash: &[u8], ) -> signature::Result { sign_digest::<_, _, D>(&mut rng, false, &self.inner, prehash, self.salt_len) - .map(|v| v.into()) + .map(|v| v.into_boxed_slice().into()) .map_err(|e| e.into()) } } @@ -716,7 +707,7 @@ where msg: &[u8], ) -> signature::Result { sign_digest::<_, _, D>(&mut rng, true, &self.inner, &D::digest(msg), self.salt_len) - .map(|v| v.into()) + .map(|v| v.into_boxed_slice().into()) .map_err(|e| e.into()) } } @@ -737,7 +728,7 @@ where &digest.finalize(), self.salt_len, ) - .map(|v| v.into()) + .map(|v| v.into_boxed_slice().into()) .map_err(|e| e.into()) } } @@ -753,7 +744,7 @@ where prehash: &[u8], ) -> signature::Result { sign_digest::<_, _, D>(&mut rng, true, &self.inner, prehash, self.salt_len) - .map(|v| v.into()) + .map(|v| v.into_boxed_slice().into()) .map_err(|e| e.into()) } } @@ -904,7 +895,7 @@ where #[cfg(test)] mod test { - use crate::pss::{BlindedSigningKey, SigningKey, VerifyingKey}; + use crate::pss::{BlindedSigningKey, Signature, SigningKey, VerifyingKey}; use crate::{PaddingScheme, PublicKey, RsaPrivateKey, RsaPublicKey}; use hex_literal::hex; @@ -914,9 +905,7 @@ mod test { use sha1::{Digest, Sha1}; #[cfg(feature = "hazmat")] use signature::hazmat::{PrehashVerifier, RandomizedPrehashSigner}; - use signature::{ - DigestVerifier, RandomizedDigestSigner, RandomizedSigner, Signature, Verifier, - }; + use signature::{DigestVerifier, RandomizedDigestSigner, RandomizedSigner, Verifier}; fn get_private_key() -> RsaPrivateKey { // In order to generate new test vectors you'll need the PEM form of this key: @@ -1003,8 +992,10 @@ mod test { let verifying_key: VerifyingKey = VerifyingKey::new(pub_key); for (text, sig, expected) in &tests { - let result = - verifying_key.verify(text.as_bytes(), &Signature::from_bytes(sig).unwrap()); + let result = verifying_key.verify( + text.as_bytes(), + &Signature::try_from(sig.as_slice()).unwrap(), + ); match expected { true => result.expect("failed to verify"), false => { @@ -1042,7 +1033,8 @@ mod test { for (text, sig, expected) in &tests { let mut digest = Sha1::new(); digest.update(text.as_bytes()); - let result = verifying_key.verify_digest(digest, &Signature::from_bytes(sig).unwrap()); + let result = + verifying_key.verify_digest(digest, &Signature::try_from(sig.as_slice()).unwrap()); match expected { true => result.expect("failed to verify"), false => { @@ -1195,7 +1187,8 @@ mod test { let verifying_key = VerifyingKey::::new(pub_key); for (text, sig, expected) in &tests { - let result = verifying_key.verify_prehash(text.as_ref(), &Signature::from_bytes(sig).unwrap()); + let result = verifying_key + .verify_prehash(text.as_ref(), &Signature::try_from(sig.as_slice()).unwrap()); match expected { true => result.expect("failed to verify"), false => { @@ -1216,7 +1209,9 @@ mod test { let verifying_key = VerifyingKey::from(&signing_key); for test in &tests { - let sig = signing_key.sign_prehash_with_rng(&mut rng, &test).expect("failed to sign"); + let sig = signing_key + .sign_prehash_with_rng(&mut rng, &test) + .expect("failed to sign"); verifying_key .verify_prehash(&test, &sig) .expect("failed to verify"); @@ -1234,7 +1229,9 @@ mod test { let verifying_key = VerifyingKey::from(&signing_key); for test in &tests { - let sig = signing_key.sign_prehash_with_rng(&mut rng, &test).expect("failed to sign"); + let sig = signing_key + .sign_prehash_with_rng(&mut rng, &test) + .expect("failed to sign"); verifying_key .verify_prehash(&test, &sig) .expect("failed to verify");