-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #4542 - equal-l2:sha256-crypto-hash, r=alexcrichton
Use crypto-hash to calculate SHA256 `crypto-hash` is an abstraction library for native hash libraries. It uses CryptoAPI on Windows, CommonCrypto on macOS, and OpenSSL on *nix. This PR will also remove `openssl` and `advapi32-sys` from dependencies since they are only used for calculating SHA256, which is superseded by `crypto-hash`. (`crypto-hash` itself uses `openssl` and `advapi32-sys` though)
- Loading branch information
Showing
2 changed files
with
16 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,100 +1,23 @@ | ||
pub use self::imp::Sha256; | ||
extern crate crypto_hash; | ||
use self::crypto_hash::{Hasher,Algorithm}; | ||
use std::io::Write; | ||
|
||
// Someone upstream will link to OpenSSL, so we don't need to explicitly | ||
// link to it ourselves. Hence we pick up Sha256 digests from OpenSSL | ||
#[cfg(not(windows))] | ||
mod imp { | ||
extern crate openssl; | ||
pub struct Sha256(Hasher); | ||
|
||
use std::io::Write; | ||
use self::openssl::hash::{Hasher, MessageDigest}; | ||
|
||
pub struct Sha256(Hasher); | ||
|
||
impl Sha256 { | ||
pub fn new() -> Sha256 { | ||
let hasher = Hasher::new(MessageDigest::sha256()).unwrap(); | ||
Sha256(hasher) | ||
} | ||
|
||
pub fn update(&mut self, bytes: &[u8]) { | ||
let _ = self.0.write_all(bytes); | ||
} | ||
|
||
pub fn finish(&mut self) -> [u8; 32] { | ||
let mut ret = [0u8; 32]; | ||
let data = self.0.finish2().unwrap(); | ||
ret.copy_from_slice(&data[..]); | ||
ret | ||
} | ||
} | ||
} | ||
|
||
// Leverage the crypto APIs that windows has built in. | ||
#[cfg(windows)] | ||
mod imp { | ||
extern crate winapi; | ||
extern crate advapi32; | ||
use std::io; | ||
use std::ptr; | ||
|
||
use self::winapi::{DWORD, HCRYPTPROV, HCRYPTHASH}; | ||
use self::winapi::{PROV_RSA_AES, CRYPT_SILENT, CRYPT_VERIFYCONTEXT, CALG_SHA_256, HP_HASHVAL}; | ||
use self::advapi32::{CryptAcquireContextW, CryptCreateHash, CryptDestroyHash}; | ||
use self::advapi32::{CryptGetHashParam, CryptHashData, CryptReleaseContext}; | ||
|
||
macro_rules! call{ ($e:expr) => ({ | ||
if $e == 0 { | ||
panic!("failed {}: {}", stringify!($e), io::Error::last_os_error()) | ||
} | ||
}) } | ||
|
||
pub struct Sha256 { | ||
hcryptprov: HCRYPTPROV, | ||
hcrypthash: HCRYPTHASH, | ||
impl Sha256 { | ||
pub fn new() -> Sha256 { | ||
let hasher = Hasher::new(Algorithm::SHA256); | ||
Sha256(hasher) | ||
} | ||
|
||
impl Sha256 { | ||
pub fn new() -> Sha256 { | ||
let mut hcp = 0; | ||
call!(unsafe { | ||
CryptAcquireContextW(&mut hcp, ptr::null(), ptr::null(), | ||
PROV_RSA_AES, | ||
CRYPT_VERIFYCONTEXT | CRYPT_SILENT) | ||
}); | ||
let mut ret = Sha256 { hcryptprov: hcp, hcrypthash: 0 }; | ||
call!(unsafe { | ||
CryptCreateHash(ret.hcryptprov, CALG_SHA_256, | ||
0, 0, &mut ret.hcrypthash) | ||
}); | ||
ret | ||
} | ||
|
||
pub fn update(&mut self, bytes: &[u8]) { | ||
call!(unsafe { | ||
CryptHashData(self.hcrypthash, bytes.as_ptr() as *mut _, | ||
bytes.len() as DWORD, 0) | ||
}) | ||
} | ||
|
||
pub fn finish(&mut self) -> [u8; 32] { | ||
let mut ret = [0u8; 32]; | ||
let mut len = ret.len() as DWORD; | ||
call!(unsafe { | ||
CryptGetHashParam(self.hcrypthash, HP_HASHVAL, ret.as_mut_ptr(), | ||
&mut len, 0) | ||
}); | ||
assert_eq!(len as usize, ret.len()); | ||
ret | ||
} | ||
pub fn update(&mut self, bytes: &[u8]) { | ||
let _ = self.0.write_all(bytes); | ||
} | ||
|
||
impl Drop for Sha256 { | ||
fn drop(&mut self) { | ||
if self.hcrypthash != 0 { | ||
call!(unsafe { CryptDestroyHash(self.hcrypthash) }); | ||
} | ||
call!(unsafe { CryptReleaseContext(self.hcryptprov, 0) }); | ||
} | ||
pub fn finish(&mut self) -> [u8; 32] { | ||
let mut ret = [0u8; 32]; | ||
let data = self.0.finish(); | ||
ret.copy_from_slice(&data[..]); | ||
ret | ||
} | ||
} |