Loading openssl/src/hash.rs +84 −20 Original line number Diff line number Diff line use std::io::prelude::*; use std::io; use std::ops::{Deref, DerefMut}; use std::fmt; use ffi; #[cfg(ossl110)] Loading Loading @@ -118,7 +120,7 @@ impl Hasher { match self.state { Reset => return Ok(()), Updated => { try!(self.finish()); try!(self.finish2()); } Finalized => (), } Loading @@ -141,19 +143,27 @@ impl Hasher { Ok(()) } /// Returns the hash of the data written since creation or /// the last `finish` and resets the hasher. #[deprecated(note = "use finish2 instead", since = "0.9.11")] pub fn finish(&mut self) -> Result<Vec<u8>, ErrorStack> { self.finish2().map(|b| b.to_vec()) } /// Returns the hash of the data written and resets the hasher. /// /// Unlike `finish`, this method does not allocate. pub fn finish2(&mut self) -> Result<DigestBytes, ErrorStack> { if self.state == Finalized { try!(self.init()); } unsafe { let mut len = ffi::EVP_MAX_MD_SIZE; let mut res = vec![0; len as usize]; try!(cvt(ffi::EVP_DigestFinal_ex(self.ctx, res.as_mut_ptr(), &mut len))); res.truncate(len as usize); let mut buf = [0; ffi::EVP_MAX_MD_SIZE as usize]; try!(cvt(ffi::EVP_DigestFinal_ex(self.ctx, buf.as_mut_ptr(), &mut len))); self.state = Finalized; Ok(res) Ok(DigestBytes { buf: buf, len: len as usize, }) } } } Loading Loading @@ -192,34 +202,88 @@ impl Drop for Hasher { fn drop(&mut self) { unsafe { if self.state != Finalized { drop(self.finish()); drop(self.finish2()); } EVP_MD_CTX_free(self.ctx); } } } /// Computes the hash of the `data` with the hash `t`. /// The resulting bytes of a digest. /// /// This type derefs to a byte slice - it exists to avoid allocating memory to /// store the digest data. #[derive(Copy)] pub struct DigestBytes { buf: [u8; ffi::EVP_MAX_MD_SIZE as usize], len: usize, } impl Clone for DigestBytes { #[inline] fn clone(&self) -> DigestBytes { *self } } impl Deref for DigestBytes { type Target = [u8]; #[inline] fn deref(&self) -> &[u8] { &self.buf[..self.len] } } impl DerefMut for DigestBytes { #[inline] fn deref_mut(&mut self) -> &mut [u8] { &mut self.buf[..self.len] } } impl AsRef<[u8]> for DigestBytes { #[inline] fn as_ref(&self) -> &[u8] { self.deref() } } impl fmt::Debug for DigestBytes { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&**self, fmt) } } #[deprecated(note = "use hash2 instead", since = "0.9.11")] pub fn hash(t: MessageDigest, data: &[u8]) -> Result<Vec<u8>, ErrorStack> { hash2(t, data).map(|b| b.to_vec()) } /// Computes the hash of the `data` with the hash `t`. /// /// Unlike `hash`, this function does not allocate the return value. pub fn hash2(t: MessageDigest, data: &[u8]) -> Result<DigestBytes, ErrorStack> { let mut h = try!(Hasher::new(t)); try!(h.update(data)); h.finish() h.finish2() } #[cfg(test)] mod tests { use hex::{FromHex, ToHex}; use super::{hash, Hasher, MessageDigest}; use std::io::prelude::*; use super::*; fn hash_test(hashtype: MessageDigest, hashtest: &(&str, &str)) { let res = hash(hashtype, &Vec::from_hex(hashtest.0).unwrap()).unwrap(); let res = hash2(hashtype, &Vec::from_hex(hashtest.0).unwrap()).unwrap(); assert_eq!(res.to_hex(), hashtest.1); } fn hash_recycle_test(h: &mut Hasher, hashtest: &(&str, &str)) { let _ = h.write_all(&Vec::from_hex(hashtest.0).unwrap()).unwrap(); let res = h.finish().unwrap(); let res = h.finish2().unwrap(); assert_eq!(res.to_hex(), hashtest.1); } Loading Loading @@ -259,10 +323,10 @@ mod tests { fn test_finish_twice() { let mut h = Hasher::new(MessageDigest::md5()).unwrap(); h.write_all(&Vec::from_hex(md5_tests[6].0).unwrap()).unwrap(); h.finish().unwrap(); let res = h.finish().unwrap(); let null = hash(MessageDigest::md5(), &[]).unwrap(); assert_eq!(res, null); h.finish2().unwrap(); let res = h.finish2().unwrap(); let null = hash2(MessageDigest::md5(), &[]).unwrap(); assert_eq!(&*res, &*null); } #[test] Loading @@ -280,17 +344,17 @@ mod tests { println!("Clone an updated hasher"); let mut h2 = h1.clone(); h2.write_all(&inp[p..]).unwrap(); let res = h2.finish().unwrap(); let res = h2.finish2().unwrap(); assert_eq!(res.to_hex(), md5_tests[i].1); } h1.write_all(&inp[p..]).unwrap(); let res = h1.finish().unwrap(); let res = h1.finish2().unwrap(); assert_eq!(res.to_hex(), md5_tests[i].1); println!("Clone a finished hasher"); let mut h3 = h1.clone(); h3.write_all(&Vec::from_hex(md5_tests[i + 1].0).unwrap()).unwrap(); let res = h3.finish().unwrap(); let res = h3.finish2().unwrap(); assert_eq!(res.to_hex(), md5_tests[i + 1].1); } Loading openssl/src/pkcs5.rs +2 −2 Original line number Diff line number Diff line Loading @@ -126,8 +126,6 @@ pub fn scrypt(pass: &[u8], #[cfg(test)] mod tests { use hex::ToHex; use hash::MessageDigest; use symm::Cipher; Loading Loading @@ -241,6 +239,8 @@ mod tests { #[test] #[cfg(all(feature = "v110", ossl110))] fn scrypt() { use hex::ToHex; let pass = "pleaseletmein"; let salt = "SodiumChloride"; let expected = "7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613\ Loading Loading
openssl/src/hash.rs +84 −20 Original line number Diff line number Diff line use std::io::prelude::*; use std::io; use std::ops::{Deref, DerefMut}; use std::fmt; use ffi; #[cfg(ossl110)] Loading Loading @@ -118,7 +120,7 @@ impl Hasher { match self.state { Reset => return Ok(()), Updated => { try!(self.finish()); try!(self.finish2()); } Finalized => (), } Loading @@ -141,19 +143,27 @@ impl Hasher { Ok(()) } /// Returns the hash of the data written since creation or /// the last `finish` and resets the hasher. #[deprecated(note = "use finish2 instead", since = "0.9.11")] pub fn finish(&mut self) -> Result<Vec<u8>, ErrorStack> { self.finish2().map(|b| b.to_vec()) } /// Returns the hash of the data written and resets the hasher. /// /// Unlike `finish`, this method does not allocate. pub fn finish2(&mut self) -> Result<DigestBytes, ErrorStack> { if self.state == Finalized { try!(self.init()); } unsafe { let mut len = ffi::EVP_MAX_MD_SIZE; let mut res = vec![0; len as usize]; try!(cvt(ffi::EVP_DigestFinal_ex(self.ctx, res.as_mut_ptr(), &mut len))); res.truncate(len as usize); let mut buf = [0; ffi::EVP_MAX_MD_SIZE as usize]; try!(cvt(ffi::EVP_DigestFinal_ex(self.ctx, buf.as_mut_ptr(), &mut len))); self.state = Finalized; Ok(res) Ok(DigestBytes { buf: buf, len: len as usize, }) } } } Loading Loading @@ -192,34 +202,88 @@ impl Drop for Hasher { fn drop(&mut self) { unsafe { if self.state != Finalized { drop(self.finish()); drop(self.finish2()); } EVP_MD_CTX_free(self.ctx); } } } /// Computes the hash of the `data` with the hash `t`. /// The resulting bytes of a digest. /// /// This type derefs to a byte slice - it exists to avoid allocating memory to /// store the digest data. #[derive(Copy)] pub struct DigestBytes { buf: [u8; ffi::EVP_MAX_MD_SIZE as usize], len: usize, } impl Clone for DigestBytes { #[inline] fn clone(&self) -> DigestBytes { *self } } impl Deref for DigestBytes { type Target = [u8]; #[inline] fn deref(&self) -> &[u8] { &self.buf[..self.len] } } impl DerefMut for DigestBytes { #[inline] fn deref_mut(&mut self) -> &mut [u8] { &mut self.buf[..self.len] } } impl AsRef<[u8]> for DigestBytes { #[inline] fn as_ref(&self) -> &[u8] { self.deref() } } impl fmt::Debug for DigestBytes { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&**self, fmt) } } #[deprecated(note = "use hash2 instead", since = "0.9.11")] pub fn hash(t: MessageDigest, data: &[u8]) -> Result<Vec<u8>, ErrorStack> { hash2(t, data).map(|b| b.to_vec()) } /// Computes the hash of the `data` with the hash `t`. /// /// Unlike `hash`, this function does not allocate the return value. pub fn hash2(t: MessageDigest, data: &[u8]) -> Result<DigestBytes, ErrorStack> { let mut h = try!(Hasher::new(t)); try!(h.update(data)); h.finish() h.finish2() } #[cfg(test)] mod tests { use hex::{FromHex, ToHex}; use super::{hash, Hasher, MessageDigest}; use std::io::prelude::*; use super::*; fn hash_test(hashtype: MessageDigest, hashtest: &(&str, &str)) { let res = hash(hashtype, &Vec::from_hex(hashtest.0).unwrap()).unwrap(); let res = hash2(hashtype, &Vec::from_hex(hashtest.0).unwrap()).unwrap(); assert_eq!(res.to_hex(), hashtest.1); } fn hash_recycle_test(h: &mut Hasher, hashtest: &(&str, &str)) { let _ = h.write_all(&Vec::from_hex(hashtest.0).unwrap()).unwrap(); let res = h.finish().unwrap(); let res = h.finish2().unwrap(); assert_eq!(res.to_hex(), hashtest.1); } Loading Loading @@ -259,10 +323,10 @@ mod tests { fn test_finish_twice() { let mut h = Hasher::new(MessageDigest::md5()).unwrap(); h.write_all(&Vec::from_hex(md5_tests[6].0).unwrap()).unwrap(); h.finish().unwrap(); let res = h.finish().unwrap(); let null = hash(MessageDigest::md5(), &[]).unwrap(); assert_eq!(res, null); h.finish2().unwrap(); let res = h.finish2().unwrap(); let null = hash2(MessageDigest::md5(), &[]).unwrap(); assert_eq!(&*res, &*null); } #[test] Loading @@ -280,17 +344,17 @@ mod tests { println!("Clone an updated hasher"); let mut h2 = h1.clone(); h2.write_all(&inp[p..]).unwrap(); let res = h2.finish().unwrap(); let res = h2.finish2().unwrap(); assert_eq!(res.to_hex(), md5_tests[i].1); } h1.write_all(&inp[p..]).unwrap(); let res = h1.finish().unwrap(); let res = h1.finish2().unwrap(); assert_eq!(res.to_hex(), md5_tests[i].1); println!("Clone a finished hasher"); let mut h3 = h1.clone(); h3.write_all(&Vec::from_hex(md5_tests[i + 1].0).unwrap()).unwrap(); let res = h3.finish().unwrap(); let res = h3.finish2().unwrap(); assert_eq!(res.to_hex(), md5_tests[i + 1].1); } Loading
openssl/src/pkcs5.rs +2 −2 Original line number Diff line number Diff line Loading @@ -126,8 +126,6 @@ pub fn scrypt(pass: &[u8], #[cfg(test)] mod tests { use hex::ToHex; use hash::MessageDigest; use symm::Cipher; Loading Loading @@ -241,6 +239,8 @@ mod tests { #[test] #[cfg(all(feature = "v110", ossl110))] fn scrypt() { use hex::ToHex; let pass = "pleaseletmein"; let salt = "SodiumChloride"; let expected = "7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613\ Loading