crypto-hash-0.3.4/.gitignore010064400017500001750000000000271277137651500142050ustar0000000000000000*.bk target Cargo.lock crypto-hash-0.3.4/CONTRIBUTING.md010064400017500001750000000062501277137651500144520ustar0000000000000000# Contributing to `crypto-hash` `crypto-hash` is a part of the Rust ecosystem. As such, all contributions to this project follow the [Rust language's code of conduct](https://www.rust-lang.org/conduct.html) where appropriate. This project is hosted at [GitHub](https://github.com/malept/crypto-hash). Both pull requests and issues of many different kinds are accepted. ## Filing Issues Issues include bugs, questions, feedback, and feature requests. Before you file a new issue, please make sure that your issue has not already been filed by someone else. ### Filing Bugs When filing a bug, please include the following information: * Operating system and version. If on Linux, please also include the distribution name. * System architecture. Examples include: x86-64, x86, and ARMv7. * Rust version that compiled `crypto-hash`. * The version (and/or git revision) of `crypto-hash`. * A detailed list of steps to reproduce the bug. A minimal testcase would be very helpful, if possible. * If there any any error messages in the console, copying them in the bug summary will be very helpful. ## Adding a new implementation If you are requesting or adding a new library source for hash algorithms, please make sure that it supports all of the existing algorithms. For example, while the creator of this project supports the efforts of the team writing LibreSSL, it does not support the MD5 algorithm. ## Adding a new hash algorithm If you are requesting or adding a wrapper for a new hash algorithm, please make sure that it is available in all of the supported implementations listed in the README. ## Filing Pull Requests Here are some things to keep in mind as you file a pull request to fix a bug, add a new feature, etc.: * Travis CI (for Linux and OS X) and AppVeyor (for Windows) are used to make sure that the project builds as expected on the supported platforms, using the current stable and beta versions of Rust. Make sure the testsuite passes locally by running `cargo test`. * Unless it's impractical, please write tests for your changes. This will help spot regressions much easier. * If your PR changes the behavior of an existing feature, or adds a new feature, please add/edit the `rustdoc` inline documentation. * Please ensure that your changes follow the [rustfmt](https://github.com/rust-lang-nursery/rustfmt) coding standard, and do not produce any warnings when running the [clippy](https://github.com/Manishearth/rust-clippy) linter. * If you are contributing a nontrivial change, please add an entry to `NEWS.md`. The format is similar to the one described at [Keep a Changelog](http://keepachangelog.com/). * Please make sure your commits are rebased onto the latest commit in the master branch, and that you limit/squash the number of commits created to a "feature"-level. For instance: bad: ``` commit 1: add foo algorithm commit 2: run rustfmt commit 3: add test commit 4: add docs commit 5: add bar commit 6: add test + docs ``` good: ``` commit 1: add foo algorithm commit 2: add bar ``` If you are continuing the work of another person's PR and need to rebase/squash, please retain the attribution of the original author(s) and continue the work in subsequent commits. crypto-hash-0.3.4/Cargo.toml.orig010064400017500001750000000014711352617060500150770ustar0000000000000000[package] name = "crypto-hash" version = "0.3.4" authors = ["Mark Lee"] description = "A wrapper for OS-level cryptographic hash functions" documentation = "https://docs.rs/crypto-hash" repository = "https://github.com/malept/crypto-hash" readme = "README.md" keywords = ["crypto", "hash", "digest"] license = "MIT" exclude = [ ".*.yml", "ci/*" ] [badges] travis-ci = { repository = "malept/crypto-hash" } appveyor = { repository = "malept/crypto-hash" } [dependencies] hex = "0.3" [target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies] commoncrypto = "0.2" [target.'cfg(target_os = "windows")'.dependencies] winapi = { version = "0.3", features = ["minwindef", "wincrypt"] } [target.'cfg(not(any(target_os = "windows", target_os = "macos", target_os = "ios")))'.dependencies] openssl = "0.10" crypto-hash-0.3.4/Cargo.toml0000644000000025220000000000000113370ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "crypto-hash" version = "0.3.4" authors = ["Mark Lee"] exclude = [".*.yml", "ci/*"] description = "A wrapper for OS-level cryptographic hash functions" documentation = "https://docs.rs/crypto-hash" readme = "README.md" keywords = ["crypto", "hash", "digest"] license = "MIT" repository = "https://github.com/malept/crypto-hash" [dependencies.hex] version = "0.3" [target."cfg(any(target_os = \"macos\", target_os = \"ios\"))".dependencies.commoncrypto] version = "0.2" [target."cfg(not(any(target_os = \"windows\", target_os = \"macos\", target_os = \"ios\")))".dependencies.openssl] version = "0.10" [target."cfg(target_os = \"windows\")".dependencies.winapi] version = "0.3" features = ["minwindef", "wincrypt"] [badges.appveyor] repository = "malept/crypto-hash" [badges.travis-ci] repository = "malept/crypto-hash" crypto-hash-0.3.4/LICENSE010064400017500001750000000020431277137651500132220ustar0000000000000000Copyright (c) 2015, 2016 Mark Lee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. crypto-hash-0.3.4/Makefile010064400017500001750000000013001352612031600136310ustar0000000000000000CARGO ?= cargo CARGO_BUILD_TEST = $(CARGO) test --no-run KCOV ?= kcov TEST_APP = debug/crypto_hash-*.exe WIN_TARGET = x86_64-pc-windows-gnu build-test: $(CARGO_BUILD_TEST) check-i686: PKG_CONFIG_LIBDIR=/usr/lib/i386-linux-gnu/pkgconfig \ PKG_CONFIG_ALLOW_CROSS=1 \ $(CARGO) test --target i686-unknown-linux-gnu --verbose check-wine64: $(CARGO_BUILD_TEST) --target $(WIN_TARGET) WINEPREFIX=$(HOME)/.local/share/wineprefixes/wine64 wine64 target/$(WIN_TARGET)/$(TEST_APP) cov: build-test $(KCOV) --exclude-pattern=/.multirust,test.rs target/cov target/$(TEST_APP) debug: build-test rust-gdb target/$(TEST_APP) fmt: $(CARGO) fmt lint: $(CARGO) +nightly clippy -- --allow clippy::pedantic crypto-hash-0.3.4/NEWS.md010064400017500001750000000030321340732204000132670ustar0000000000000000# `crypto-hash`: Changes by Version ## [Unreleased](https://github.com/malept/crypto-hash/compare/v0.3.3...master) ## [0.3.3] - 2018-12-20 [0.3.3]: https://github.com/malept/crypto-hash/compare/v0.3.2...v0.3.3 ### Changed * Revert API change (#6) ## [0.3.2] - 2018-12-20 [0.3.2]: https://github.com/malept/crypto-hash/compare/v0.3.1...v0.3.2 **Note: This release was yanked from Cargo due to #6.** ### Added * iOS support ## [0.3.1] - 2018-02-14 [0.3.1]: https://github.com/malept/crypto-hash/compare/v0.3.0...v0.3.1 ### Changed * Upgrade to `openssl` 0.10.x (#1) * Upgrade to `winapi` 0.3.x ## [0.3.0] - 2017-06-18 [0.3.0]: https://github.com/malept/crypto-hash/compare/v0.2.1...v0.3.0 ### Changed * Upgrade to `commoncrypto` 0.2.x * Function signatures for `digest` and `hex_digest` changed to use `&[u8]`, per Clippy ## [0.2.1] - 2016-12-12 [0.2.1]: https://github.com/malept/crypto-hash/compare/v0.2.0...v0.2.1 ### Changed * Move CommonCrypto implementation to its own crate ## [0.2.0] - 2016-11-06 [0.2.0]: https://github.com/malept/crypto-hash/compare/v0.1.0...v0.2.0 ### Added * SHA-1 algorithm ### Changed * Upgrade rust-openssl to 0.9 ## [0.1.0] - 2016-06-26 [0.1.0]: https://github.com/malept/crypto-hash/releases/tag/v0.1.0 This release signifies the minimum amount of algorithms and implementations necessary for [HTTP digest authentication](https://tools.ietf.org/html/rfc7616). ### Added Algorithms: * MD5 * SHA256 * SHA512 Implementations: * CommonCrypto (OS X) * CryptoAPI (Windows) * OpenSSL (Linux/BSD/etc.) crypto-hash-0.3.4/README.md010064400017500001750000000034621324046056400134700ustar0000000000000000# `crypto-hash` [![Linux/OS X Status](https://travis-ci.org/malept/crypto-hash.svg?branch=master)](https://travis-ci.org/malept/crypto-hash) [![Windows status](https://ci.appveyor.com/api/projects/status/xwc9nb4633b5n67r/branch/master?svg=true)](https://ci.appveyor.com/project/malept/crypto-hash) [![Crates.io](https://img.shields.io/crates/v/crypto-hash.svg?maxAge=2592000)](https://crates.io/crates/crypto-hash) `crypto-hash` is a Rust wrapper around OS-level implementations of cryptographic hash functions. The purpose of this crate is to provide access to hash algorithms with as few dependencies as possible. This means that when possible, the library uses the hashing functions that are provided by the given operating system's bundled cryptographic libraries. ## Supported Implementations By operating system: * Windows: CryptoAPI * OS X: [CommonCrypto](https://crates.io/crates/commoncrypto) * Linux/BSD/etc.: [OpenSSL](https://crates.io/crates/openssl) ## Supported Algorithms * MD5 * SHA1 * SHA256 * SHA512 ## Usage Add `crypto-hash` to your project's `Cargo.toml`. For more details, consult the [Cargo guide](http://doc.crates.io/guide.html#adding-dependencies). Example: ```rust use crypto_hash::{Algorithm, hex_digest}; let digest = hex_digest(Algorithm::SHA256, b"crypto-hash"); ``` For more examples, consult the [documentation](https://malept.github.io/crypto-hash/). ## [Release Notes](https://github.com/malept/crypto-hash/blob/master/NEWS.md) ## [Contributing](https://github.com/malept/crypto-hash/blob/master/CONTRIBUTING.md) ## Acknowledgements This crate was inspired by [rust-native-tls](https://github.com/sfackler/rust-native-tls) and [crypto-bench](https://github.com/briansmith/crypto-bench). ## Legal `crypto-hash` is copyrighted under the terms of the MIT license. See LICENSE for details. crypto-hash-0.3.4/src/imp/commoncrypto.rs010064400017500001750000000055541340732204000166570ustar0000000000000000// Copyright (c) 2016 Mark Lee // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. //! A cryptographic hash generator dependent upon OSX's `CommonCrypto`. use super::Algorithm; use commoncrypto::hash; use std::io; /// Generator of digests using a cryptographic hash function. /// /// # Examples /// /// ```rust /// use crypto_hash::{Algorithm, Hasher}; /// use std::io::Write; /// /// let mut hasher = Hasher::new(Algorithm::SHA256); /// hasher.write_all(b"crypto"); /// hasher.write_all(b"-"); /// hasher.write_all(b"hash"); /// let result = hasher.finish(); /// let expected = /// b"\xfd\x1a\xfb`\"\xcdMG\xc8\x90\x96\x1cS9(\xea\xcf\xe8!\x9f\x1b%$\xf7\xfb*a\x84}\xdf\x8c'" /// .to_vec(); /// assert_eq!(expected, result) /// ``` #[derive(Debug)] pub struct Hasher(hash::Hasher); impl Hasher { /// Create a new `Hasher` for the given `Algorithm`. pub fn new(algorithm: Algorithm) -> Hasher { let cc_algorithm = match algorithm { Algorithm::MD5 => hash::CCDigestAlgorithm::kCCDigestMD5, Algorithm::SHA1 => hash::CCDigestAlgorithm::kCCDigestSHA1, Algorithm::SHA256 => hash::CCDigestAlgorithm::kCCDigestSHA256, Algorithm::SHA512 => hash::CCDigestAlgorithm::kCCDigestSHA512, }; Hasher(hash::Hasher::new(cc_algorithm)) } /// Generate a digest from the data written to the `Hasher`. pub fn finish(&mut self) -> Vec { let Hasher(ref mut hasher) = *self; match hasher.finish() { Ok(digest) => digest, Err(error) => panic!("CommonCrypto error: {}", error), } } } impl io::Write for Hasher { fn write(&mut self, buf: &[u8]) -> io::Result { let Hasher(ref mut hasher) = *self; hasher.write(buf) } fn flush(&mut self) -> io::Result<()> { let Hasher(ref mut hasher) = *self; hasher.flush() } } crypto-hash-0.3.4/src/imp/cryptoapi.rs010064400017500001750000000123061340732204000161310ustar0000000000000000// Copyright (c) 2016 Mark Lee // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. //! A cryptographic hash generator dependent upon Windows's `CryptoAPI`. //! //! Originally based on: //! https://github.com/rust-lang/cargo/blob/0.10.0/src/cargo/util/sha256.rs //! which is copyright (c) 2014 The Rust Project Developers under the MIT license. use super::Algorithm; use std::io; use std::ptr; use winapi::shared::minwindef::DWORD; use winapi::um::wincrypt::{ CryptAcquireContextW, CryptCreateHash, CryptDestroyHash, CryptGetHashParam, CryptHashData, CryptReleaseContext, ALG_ID, CALG_MD5, CALG_SHA1, CALG_SHA_256, CALG_SHA_512, CRYPT_SILENT, CRYPT_VERIFYCONTEXT, HCRYPTHASH, HCRYPTPROV, HP_HASHVAL, PROV_RSA_AES, }; macro_rules! call { ($e:expr) => {{ if $e == 0 { panic!("failed {}: {}", stringify!($e), io::Error::last_os_error()) } }}; } macro_rules! finish_algorithm { ($func_name: ident, $size: ident) => { fn $func_name(&mut self) -> Vec { let mut len = $size as u32; let mut hash = [0u8; $size]; call!(unsafe { CryptGetHashParam(self.hcrypthash, HP_HASHVAL, hash.as_mut_ptr(), &mut len, 0) }); assert_eq!(len as usize, hash.len()); hash.to_vec() } } } const MD5_LENGTH: usize = 16; const SHA1_LENGTH: usize = 20; const SHA256_LENGTH: usize = 32; const SHA512_LENGTH: usize = 64; /// Generator of digests using a cryptographic hash function. /// /// # Examples /// /// ```rust /// use crypto_hash::{Algorithm, Hasher}; /// use std::io::Write; /// /// let mut hasher = Hasher::new(Algorithm::SHA256); /// hasher.write_all(b"crypto"); /// hasher.write_all(b"-"); /// hasher.write_all(b"hash"); /// let result = hasher.finish(); /// let expected = /// b"\xfd\x1a\xfb`\"\xcdMG\xc8\x90\x96\x1cS9(\xea\xcf\xe8!\x9f\x1b%$\xf7\xfb*a\x84}\xdf\x8c'" /// .to_vec(); /// assert_eq!(expected, result) /// ``` pub struct Hasher { alg_id: ALG_ID, hcryptprov: HCRYPTPROV, hcrypthash: HCRYPTHASH, } impl Hasher { /// Create a new `Hasher` for the given `Algorithm`. pub fn new(algorithm: Algorithm) -> Hasher { let mut hcp = 0; call!(unsafe { CryptAcquireContextW( &mut hcp, ptr::null(), ptr::null(), PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_SILENT, ) }); let alg_id = match algorithm { Algorithm::MD5 => CALG_MD5, Algorithm::SHA1 => CALG_SHA1, Algorithm::SHA256 => CALG_SHA_256, Algorithm::SHA512 => CALG_SHA_512, }; let mut hasher = Hasher { alg_id, hcryptprov: hcp, hcrypthash: 0, }; call!(unsafe { CryptCreateHash( hasher.hcryptprov, hasher.alg_id, 0, 0, &mut hasher.hcrypthash, ) }); hasher } /// Generate a digest from the data written to the `Hasher`. pub fn finish(&mut self) -> Vec { match self.alg_id { CALG_MD5 => self.finish_md5(), CALG_SHA1 => self.finish_sha1(), CALG_SHA_256 => self.finish_sha256(), CALG_SHA_512 => self.finish_sha512(), _ => panic!("Unknown algorithm {}", self.alg_id), } } finish_algorithm!(finish_md5, MD5_LENGTH); finish_algorithm!(finish_sha1, SHA1_LENGTH); finish_algorithm!(finish_sha256, SHA256_LENGTH); finish_algorithm!(finish_sha512, SHA512_LENGTH); } impl io::Write for Hasher { fn write(&mut self, buf: &[u8]) -> io::Result { call!(unsafe { CryptHashData( self.hcrypthash, buf.as_ptr() as *mut _, buf.len() as DWORD, 0, ) }); Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { Ok(()) } } impl Drop for Hasher { fn drop(&mut self) { if self.hcrypthash != 0 { call!(unsafe { CryptDestroyHash(self.hcrypthash) }); } call!(unsafe { CryptReleaseContext(self.hcryptprov, 0) }); } } crypto-hash-0.3.4/src/imp/openssl.rs010064400017500001750000000057221340732204000156060ustar0000000000000000// Copyright (c) 2015, 2016 Mark Lee // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. //! A cryptographic hash digest generator dependent upon `OpenSSL`. #![warn(missing_docs)] use super::Algorithm; use openssl::hash; use std::io; /// Generator of digests using a cryptographic hash function. /// /// # Examples /// /// ```rust /// use crypto_hash::{Algorithm, Hasher}; /// use std::io::Write; /// /// let mut hasher = Hasher::new(Algorithm::SHA256); /// hasher.write_all(b"crypto"); /// hasher.write_all(b"-"); /// hasher.write_all(b"hash"); /// let result = hasher.finish(); /// let expected = /// b"\xfd\x1a\xfb`\"\xcdMG\xc8\x90\x96\x1cS9(\xea\xcf\xe8!\x9f\x1b%$\xf7\xfb*a\x84}\xdf\x8c'" /// .to_vec(); /// assert_eq!(expected, result) /// ``` pub struct Hasher(hash::Hasher); impl Hasher { /// Create a new `Hasher` for the given `Algorithm`. pub fn new(algorithm: Algorithm) -> Hasher { let hash_type = match algorithm { Algorithm::MD5 => hash::MessageDigest::md5(), Algorithm::SHA1 => hash::MessageDigest::sha1(), Algorithm::SHA256 => hash::MessageDigest::sha256(), Algorithm::SHA512 => hash::MessageDigest::sha512(), }; match hash::Hasher::new(hash_type) { Ok(hasher) => Hasher(hasher), Err(error_stack) => panic!("OpenSSL error(s): {}", error_stack), } } /// Generate a digest from the data written to the `Hasher`. pub fn finish(&mut self) -> Vec { let Hasher(ref mut hasher) = *self; match hasher.finish() { Ok(digest) => digest.to_vec(), Err(error_stack) => panic!("OpenSSL error(s): {}", error_stack), } } } impl io::Write for Hasher { fn write(&mut self, buf: &[u8]) -> io::Result { let Hasher(ref mut hasher) = *self; hasher.write(buf) } fn flush(&mut self) -> io::Result<()> { let Hasher(ref mut hasher) = *self; hasher.flush() } } crypto-hash-0.3.4/src/lib.rs010064400017500001750000000077001352617045000141120ustar0000000000000000// Copyright (c) 2015, 2016, 2017 Mark Lee // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. //! A set of [cryptographic hash //! functions](https://en.wikipedia.org/wiki/Cryptographic_hash_function) provided by the operating //! system, when available. //! //! The purpose of this crate is to provide access to hash algorithms with as few dependencies as //! possible. This means that when possible, the library uses the hashing functions that are //! provided by the given operating system's bundled cryptographic libraries. //! //! # Supported Implementations //! //! By operating system: //! //! * Windows: `CryptoAPI` //! * Mac OS X: `CommonCrypto` //! * Linux/BSD/etc.: `OpenSSL` //! //! # Supported Algorithms //! //! * MD5 //! * SHA1 //! * SHA256 //! * SHA512 #![warn(missing_docs)] #[cfg(any(target_os = "macos", target_os = "ios"))] extern crate commoncrypto; extern crate hex; #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "windows")))] extern crate openssl; #[cfg(target_os = "windows")] extern crate winapi; use std::io::Write; #[cfg(any(target_os = "macos", target_os = "ios"))] #[path = "imp/commoncrypto.rs"] mod imp; #[cfg(target_os = "windows")] #[path = "imp/cryptoapi.rs"] mod imp; #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "windows")))] #[path = "imp/openssl.rs"] mod imp; mod test; pub use imp::Hasher; /// Available cryptographic hash functions. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum Algorithm { /// Popular message digest algorithm, only available for backwards compatibility purposes. MD5, /// SHA-1 algorithm from NIST FIPS, only available for backwards compatibility purposes. SHA1, /// SHA-2 family algorithm (256 bits). SHA256, /// SHA-2 family algorithm (512 bits). SHA512, } /// Helper function for `Hasher` which generates a cryptographic digest from the given /// data and algorithm. /// /// # Examples /// /// ```rust /// use crypto_hash::{Algorithm, digest}; /// /// let data = b"crypto-hash"; /// let result = digest(Algorithm::SHA256, data); /// let expected = /// b"\xfd\x1a\xfb`\"\xcdMG\xc8\x90\x96\x1cS9(\xea\xcf\xe8!\x9f\x1b%$\xf7\xfb*a\x84}\xdf\x8c'" /// .to_vec(); /// assert_eq!(expected, result) /// ``` pub fn digest(algorithm: Algorithm, data: &[u8]) -> Vec { let mut hasher = imp::Hasher::new(algorithm); hasher.write_all(data).expect("Could not write hash data"); hasher.finish() } /// Helper function for `Hasher` which generates a cryptographic digest serialized in /// hexadecimal from the given data and algorithm. /// /// # Examples /// /// ```rust /// use crypto_hash::{Algorithm, hex_digest}; /// /// let data = b"crypto-hash"; /// let result = hex_digest(Algorithm::SHA256, data); /// let expected = "fd1afb6022cd4d47c890961c533928eacfe8219f1b2524f7fb2a61847ddf8c27"; /// assert_eq!(expected, result) /// ``` pub fn hex_digest(algorithm: Algorithm, data: &[u8]) -> String { hex::encode(digest(algorithm, data)) } crypto-hash-0.3.4/src/test.rs010064400017500001750000000055671340732204000143240ustar0000000000000000// Copyright (c) 2016, 2017 Mark Lee // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #![cfg(test)] use super::{hex_digest, Algorithm, Hasher}; use hex; use std::io::Write; // From Wikipedia const MD5_EMPTY_STRING: &'static str = "d41d8cd98f00b204e9800998ecf8427e"; const SHA1_EMPTY_STRING: &'static str = "da39a3ee5e6b4b0d3255bfef95601890afd80709"; const SHA256_EMPTY_STRING: &'static str = concat!( "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649", "b934ca495991b7852b855" ); const SHA512_EMPTY_STRING: &'static str = concat!( "cf83e1357eefb8bdf1542850d66d8007d620e4050b5", "715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318", "d2877eec2f63b931bd47417a81a538327af927da3e" ); const TO_HASH: &'static str = "The quick brown fox jumps over the lazy dog"; const TO_HASH_MD5: &'static str = "9e107d9d372bb6826bd81d3542a419d6"; #[test] fn md5_empty_string() { assert_hex_hashed_empty_string(Algorithm::MD5, MD5_EMPTY_STRING) } #[test] fn sha1_empty_string() { assert_hex_hashed_empty_string(Algorithm::SHA1, SHA1_EMPTY_STRING) } #[test] fn sha256_empty_string() { // From Wikipedia assert_hex_hashed_empty_string(Algorithm::SHA256, SHA256_EMPTY_STRING) } #[test] fn sha512_empty_string() { assert_hex_hashed_empty_string(Algorithm::SHA512, SHA512_EMPTY_STRING) } #[test] fn hasher_sans_write() { let mut hasher = Hasher::new(Algorithm::MD5); let actual = hex::encode(hasher.finish()); assert_eq!(MD5_EMPTY_STRING, actual) } #[test] fn hasher_with_write() { let mut hasher = Hasher::new(Algorithm::MD5); hasher .write_all(TO_HASH.as_bytes()) .expect("Could not write to hasher"); let actual = hex::encode(hasher.finish()); assert_eq!(TO_HASH_MD5, actual) } fn assert_hex_hashed_empty_string(algorithm: Algorithm, expected: &str) { let vec = vec![]; assert_eq!(expected, hex_digest(algorithm, vec.as_slice()).as_str()) } crypto-hash-0.3.4/.cargo_vcs_info.json0000644000000001120000000000000133320ustar00{ "git": { "sha1": "b2916b394f7bd5d39ce13cc083d6ced58a02b128" } }