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)
This commit is contained in:
bors 2017-09-29 06:48:13 +00:00
commit 0ac53629de
2 changed files with 18 additions and 98 deletions

View File

@ -20,6 +20,7 @@ path = "src/cargo/lib.rs"
atty = "0.2"
crates-io = { path = "src/crates-io", version = "0.12" }
crossbeam = "0.3"
crypto-hash = "0.3"
curl = "0.4.6"
docopt = "0.8.1"
env_logger = "0.4"
@ -52,14 +53,10 @@ termcolor = "0.3"
toml = "0.4"
url = "1.1"
[target.'cfg(unix)'.dependencies]
openssl = "0.9"
[target.'cfg(target_os = "macos")'.dependencies]
core-foundation = { version = "0.4.4", features = ["mac_os_10_7_support"] }
[target.'cfg(windows)'.dependencies]
advapi32-sys = "0.2"
kernel32-sys = "0.2"
miow = "0.2"
psapi-sys = "0.1"

View File

@ -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};
impl Sha256 {
pub fn new() -> Sha256 {
let hasher = Hasher::new(Algorithm::SHA256);
Sha256(hasher)
}
pub struct Sha256(Hasher);
pub fn update(&mut self, bytes: &[u8]) {
let _ = self.0.write_all(bytes);
}
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 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
}
}
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
}
}