Skip to content

Commit

Permalink
Auto merge of #4542 - equal-l2:sha256-crypto-hash, r=alexcrichton
Browse files Browse the repository at this point in the history
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
bors committed Sep 29, 2017
2 parents 41d3fdb + 8346104 commit 0ac5362
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 96 deletions.
5 changes: 1 addition & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
107 changes: 15 additions & 92 deletions src/cargo/util/sha256.rs
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
}
}

0 comments on commit 0ac5362

Please sign in to comment.