|
1 | | -pub use self::imp::Sha256; |
| 1 | +extern crate crypto_hash; |
| 2 | +use self::crypto_hash::{Hasher,Algorithm}; |
| 3 | +use std::io::Write; |
2 | 4 |
|
3 | | -// Someone upstream will link to OpenSSL, so we don't need to explicitly |
4 | | -// link to it ourselves. Hence we pick up Sha256 digests from OpenSSL |
5 | | -#[cfg(not(windows))] |
6 | | -mod imp { |
7 | | - extern crate openssl; |
| 5 | +pub struct Sha256(Hasher); |
8 | 6 |
|
9 | | - use std::io::Write; |
10 | | - use self::openssl::hash::{Hasher, MessageDigest}; |
11 | | - |
12 | | - pub struct Sha256(Hasher); |
13 | | - |
14 | | - impl Sha256 { |
15 | | - pub fn new() -> Sha256 { |
16 | | - let hasher = Hasher::new(MessageDigest::sha256()).unwrap(); |
17 | | - Sha256(hasher) |
18 | | - } |
19 | | - |
20 | | - pub fn update(&mut self, bytes: &[u8]) { |
21 | | - let _ = self.0.write_all(bytes); |
22 | | - } |
23 | | - |
24 | | - pub fn finish(&mut self) -> [u8; 32] { |
25 | | - let mut ret = [0u8; 32]; |
26 | | - let data = self.0.finish2().unwrap(); |
27 | | - ret.copy_from_slice(&data[..]); |
28 | | - ret |
29 | | - } |
30 | | - } |
31 | | -} |
32 | | - |
33 | | -// Leverage the crypto APIs that windows has built in. |
34 | | -#[cfg(windows)] |
35 | | -mod imp { |
36 | | - extern crate winapi; |
37 | | - extern crate advapi32; |
38 | | - use std::io; |
39 | | - use std::ptr; |
40 | | - |
41 | | - use self::winapi::{DWORD, HCRYPTPROV, HCRYPTHASH}; |
42 | | - use self::winapi::{PROV_RSA_AES, CRYPT_SILENT, CRYPT_VERIFYCONTEXT, CALG_SHA_256, HP_HASHVAL}; |
43 | | - use self::advapi32::{CryptAcquireContextW, CryptCreateHash, CryptDestroyHash}; |
44 | | - use self::advapi32::{CryptGetHashParam, CryptHashData, CryptReleaseContext}; |
45 | | - |
46 | | - macro_rules! call{ ($e:expr) => ({ |
47 | | - if $e == 0 { |
48 | | - panic!("failed {}: {}", stringify!($e), io::Error::last_os_error()) |
49 | | - } |
50 | | - }) } |
51 | | - |
52 | | - pub struct Sha256 { |
53 | | - hcryptprov: HCRYPTPROV, |
54 | | - hcrypthash: HCRYPTHASH, |
| 7 | +impl Sha256 { |
| 8 | + pub fn new() -> Sha256 { |
| 9 | + let hasher = Hasher::new(Algorithm::SHA256); |
| 10 | + Sha256(hasher) |
55 | 11 | } |
56 | 12 |
|
57 | | - impl Sha256 { |
58 | | - pub fn new() -> Sha256 { |
59 | | - let mut hcp = 0; |
60 | | - call!(unsafe { |
61 | | - CryptAcquireContextW(&mut hcp, ptr::null(), ptr::null(), |
62 | | - PROV_RSA_AES, |
63 | | - CRYPT_VERIFYCONTEXT | CRYPT_SILENT) |
64 | | - }); |
65 | | - let mut ret = Sha256 { hcryptprov: hcp, hcrypthash: 0 }; |
66 | | - call!(unsafe { |
67 | | - CryptCreateHash(ret.hcryptprov, CALG_SHA_256, |
68 | | - 0, 0, &mut ret.hcrypthash) |
69 | | - }); |
70 | | - ret |
71 | | - } |
72 | | - |
73 | | - pub fn update(&mut self, bytes: &[u8]) { |
74 | | - call!(unsafe { |
75 | | - CryptHashData(self.hcrypthash, bytes.as_ptr() as *mut _, |
76 | | - bytes.len() as DWORD, 0) |
77 | | - }) |
78 | | - } |
79 | | - |
80 | | - pub fn finish(&mut self) -> [u8; 32] { |
81 | | - let mut ret = [0u8; 32]; |
82 | | - let mut len = ret.len() as DWORD; |
83 | | - call!(unsafe { |
84 | | - CryptGetHashParam(self.hcrypthash, HP_HASHVAL, ret.as_mut_ptr(), |
85 | | - &mut len, 0) |
86 | | - }); |
87 | | - assert_eq!(len as usize, ret.len()); |
88 | | - ret |
89 | | - } |
| 13 | + pub fn update(&mut self, bytes: &[u8]) { |
| 14 | + let _ = self.0.write_all(bytes); |
90 | 15 | } |
91 | 16 |
|
92 | | - impl Drop for Sha256 { |
93 | | - fn drop(&mut self) { |
94 | | - if self.hcrypthash != 0 { |
95 | | - call!(unsafe { CryptDestroyHash(self.hcrypthash) }); |
96 | | - } |
97 | | - call!(unsafe { CryptReleaseContext(self.hcryptprov, 0) }); |
98 | | - } |
| 17 | + pub fn finish(&mut self) -> [u8; 32] { |
| 18 | + let mut ret = [0u8; 32]; |
| 19 | + let data = self.0.finish(); |
| 20 | + ret.copy_from_slice(&data[..]); |
| 21 | + ret |
99 | 22 | } |
100 | 23 | } |
0 commit comments