diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-23 21:41:40 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-23 21:41:40 +0000 |
commit | 94d557e93368624bad52722bb4c093d4ac5cc1b9 (patch) | |
tree | a2105481bd54d84e9c7e7b0c2ee605089f06a453 /base/sha1_win.cc | |
parent | 6acc7562fb3b6c720b050a379ea2c7e3fca22300 (diff) | |
download | chromium_src-94d557e93368624bad52722bb4c093d4ac5cc1b9.zip chromium_src-94d557e93368624bad52722bb4c093d4ac5cc1b9.tar.gz chromium_src-94d557e93368624bad52722bb4c093d4ac5cc1b9.tar.bz2 |
Implement the SecureHashAlgorithm class using Windows CryptoAPI.
sha1.cc is renamed sha1_portable.cc. Change the swapends function
to take a pointer instead of a non-const reference parameter.
R=jhawkins,davidben,eroman
BUG=47218
TEST=SHA1Test.* in base_unittests should pass.
Review URL: http://codereview.chromium.org/2849018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50648 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/sha1_win.cc')
-rw-r--r-- | base/sha1_win.cc | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/base/sha1_win.cc b/base/sha1_win.cc new file mode 100644 index 0000000..b79ac38 --- /dev/null +++ b/base/sha1_win.cc @@ -0,0 +1,115 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/sha1.h" + +#include <windows.h> +#include <wincrypt.h> + +#include "base/logging.h" +#include "base/string_util.h" + +namespace base { + +// Implementation of SHA-1 using Windows CryptoAPI. + +// Usage example: +// +// SecureHashAlgorithm sha; +// while(there is data to hash) +// sha.Update(moredata, size of data); +// sha.Final(); +// memcpy(somewhere, sha.Digest(), 20); +// +// to reuse the instance of sha, call sha.Init(); + +class SecureHashAlgorithm { + public: + SecureHashAlgorithm() : prov_(NULL), hash_(NULL) { Init(); } + + void Init(); + void Update(const void* data, size_t nbytes); + void Final(); + + // 20 bytes of message digest. + const unsigned char* Digest() const { + return reinterpret_cast<const unsigned char*>(result_.data()); + } + + private: + // Cleans up prov_, hash_, and result_. + void Cleanup(); + + HCRYPTPROV prov_; + HCRYPTHASH hash_; + std::string result_; +}; + +void SecureHashAlgorithm::Init() { + Cleanup(); + + if (!CryptAcquireContext(&prov_, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + LOG(ERROR) << "CryptAcquireContext failed: " << GetLastError(); + return; + } + + // Initialize the hash. + if (!CryptCreateHash(prov_, CALG_SHA1, 0, 0, &hash_)) { + LOG(ERROR) << "CryptCreateHash failed: " << GetLastError(); + return; + } +} + +void SecureHashAlgorithm::Update(const void* data, size_t nbytes) { + BOOL ok = CryptHashData(hash_, reinterpret_cast<CONST BYTE*>(data), + static_cast<DWORD>(nbytes), 0); + CHECK(ok) << "CryptHashData failed: " << GetLastError(); +} + +void SecureHashAlgorithm::Final() { + DWORD hash_len = 0; + DWORD buffer_size = sizeof(hash_len); + if (!CryptGetHashParam(hash_, HP_HASHSIZE, + reinterpret_cast<unsigned char*>(&hash_len), + &buffer_size, 0)) { + LOG(ERROR) << "CryptGetHashParam(HP_HASHSIZE) failed: " << GetLastError(); + result_.assign(SHA1_LENGTH, '\0'); + return; + } + + // Get the hash data. + if (!CryptGetHashParam(hash_, HP_HASHVAL, + reinterpret_cast<BYTE*>(WriteInto(&result_, + hash_len + 1)), + &hash_len, 0)) { + LOG(ERROR) << "CryptGetHashParam(HP_HASHVAL) failed: " << GetLastError(); + result_.assign(SHA1_LENGTH, '\0'); + return; + } +} + +void SecureHashAlgorithm::Cleanup() { + BOOL ok; + if (hash_) { + ok = CryptDestroyHash(hash_); + DCHECK(ok); + hash_ = NULL; + } + if (prov_) { + ok = CryptReleaseContext(prov_, 0); + DCHECK(ok); + prov_ = NULL; + } + result_.clear(); +} + +std::string SHA1HashString(const std::string& str) { + SecureHashAlgorithm sha; + sha.Update(str.c_str(), str.length()); + sha.Final(); + std::string out(reinterpret_cast<const char*>(sha.Digest()), SHA1_LENGTH); + return out; +} + +} // namespace base |