diff --git a/openssl-sys/src/sha.rs b/openssl-sys/src/sha.rs index a9e7b15c..e8d1403f 100644 --- a/openssl-sys/src/sha.rs +++ b/openssl-sys/src/sha.rs @@ -5,6 +5,7 @@ pub type SHA_LONG = c_uint; pub const SHA_LBLOCK: c_int = 16; #[repr(C)] +#[derive(Clone)] pub struct SHA_CTX { pub h0: SHA_LONG, pub h1: SHA_LONG, @@ -25,6 +26,7 @@ extern "C" { } #[repr(C)] +#[derive(Clone)] pub struct SHA256_CTX { pub h: [SHA_LONG; 8], pub Nl: SHA_LONG, @@ -48,6 +50,7 @@ extern "C" { pub type SHA_LONG64 = u64; #[repr(C)] +#[derive(Clone)] pub struct SHA512_CTX { pub h: [SHA_LONG64; 8], pub Nl: SHA_LONG64, diff --git a/openssl/src/sha.rs b/openssl/src/sha.rs index e3c4c2e8..7f6c4067 100644 --- a/openssl/src/sha.rs +++ b/openssl/src/sha.rs @@ -110,6 +110,7 @@ pub fn sha512(data: &[u8]) -> [u8; 64] { /// /// SHA1 is known to be insecure - it should not be used unless required for /// compatibility with existing systems. +#[derive(Clone)] pub struct Sha1(ffi::SHA_CTX); impl Sha1 { @@ -145,6 +146,7 @@ impl Sha1 { } /// An object which calculates a SHA224 hash of some data. +#[derive(Clone)] pub struct Sha224(ffi::SHA256_CTX); impl Sha224 { @@ -180,6 +182,7 @@ impl Sha224 { } /// An object which calculates a SHA256 hash of some data. +#[derive(Clone)] pub struct Sha256(ffi::SHA256_CTX); impl Sha256 { @@ -215,6 +218,7 @@ impl Sha256 { } /// An object which calculates a SHA384 hash of some data. +#[derive(Clone)] pub struct Sha384(ffi::SHA512_CTX); impl Sha384 { @@ -250,6 +254,7 @@ impl Sha384 { } /// An object which calculates a SHA512 hash of some data. +#[derive(Clone)] pub struct Sha512(ffi::SHA512_CTX); impl Sha512 { @@ -308,6 +313,20 @@ mod test { assert_eq!(hex::encode(hasher.finish()), expected); } + #[test] + fn cloning_allows_incremental_hashing() { + let expected = "a9993e364706816aba3e25717850c26c9cd0d89d"; + + let mut hasher = Sha1::new(); + hasher.update(b"a"); + + let mut incr_hasher = hasher.clone(); + incr_hasher.update(b"bc"); + + assert_eq!(hex::encode(incr_hasher.finish()), expected); + assert_ne!(hex::encode(hasher.finish()), expected); + } + #[test] fn standalone_224() { let data = b"abc";