diff options
author | deanm@google.com <deanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-08 13:58:10 +0000 |
---|---|---|
committer | deanm@google.com <deanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-08 13:58:10 +0000 |
commit | fbcfafe4cd6d4f69ad0e1e3d921fb05bb5fcadfd (patch) | |
tree | 546a86df37312e589e6a9c0da1e94a42b40b0e36 | |
parent | 9795ec11c994c7750a19aeab79cbf094df0d90dd (diff) | |
download | chromium_src-fbcfafe4cd6d4f69ad0e1e3d921fb05bb5fcadfd.zip chromium_src-fbcfafe4cd6d4f69ad0e1e3d921fb05bb5fcadfd.tar.gz chromium_src-fbcfafe4cd6d4f69ad0e1e3d921fb05bb5fcadfd.tar.bz2 |
Remove the ifdef platform jungle from hmac.h, abstracting the platform specific data into a platform specific heap-allocated structure.
Review URL: http://codereview.chromium.org/1614
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1836 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/hmac.h | 31 | ||||
-rw-r--r-- | base/hmac_mac.cc | 18 | ||||
-rw-r--r-- | base/hmac_win.cc | 88 |
3 files changed, 59 insertions, 78 deletions
diff --git a/base/hmac.h b/base/hmac.h index f9c0e604..ac48ec07 100644 --- a/base/hmac.h +++ b/base/hmac.h @@ -8,19 +8,15 @@ #ifndef BASE_HMAC_H_ #define BASE_HMAC_H_ -#include "build/build_config.h" - -#if defined(OS_WIN) -#include <windows.h> -#include <wincrypt.h> -#endif - #include <string> #include "base/basictypes.h" namespace base { +// Simplify the interface and reduce includes by abstracting out the internals. +struct HMACPlatformData; + class HMAC { public: // The set of supported hash functions. Extend as required. @@ -37,27 +33,8 @@ class HMAC { bool Sign(const std::string& data, unsigned char* digest, int digest_length); private: -#if defined(OS_POSIX) HashAlgorithm hash_alg_; - std::string key_; -#elif defined(OS_WIN) - // Import the key so that we don't have to store it ourself. - void ImportKey(const unsigned char* key, int key_length); - - // Returns the SHA1 hash of 'data' and 'key' in 'digest'. If there was any - // error in the calculation, this method returns false, otherwise true. - bool SignWithSHA1(const std::string& data, - unsigned char* digest, - int digest_length); - - // The hash algorithm to use. - HashAlgorithm hash_alg_; - - // Windows Crypt API resources. - HCRYPTPROV provider_; - HCRYPTHASH hash_; - HCRYPTKEY hkey_; -#endif // OS_WIN + HMACPlatformData* plat_; DISALLOW_COPY_AND_ASSIGN(HMAC); }; diff --git a/base/hmac_mac.cc b/base/hmac_mac.cc index 0542a70..b2d0a33 100644 --- a/base/hmac_mac.cc +++ b/base/hmac_mac.cc @@ -10,16 +10,22 @@ namespace base { +struct HMACPlatformData { + std::string key_; +}; + HMAC::HMAC(HashAlgorithm hash_alg, const unsigned char* key, int key_length) - : hash_alg_(hash_alg), - key_(reinterpret_cast<const char*>(key), key_length) { + : hash_alg_(hash_alg), plat_(new HMACPlatformData()) { + plat_->key_.assign(reinterpret_cast<const char*>(key), key_length); } HMAC::~HMAC() { // Zero out key copy. - key_.assign(key_.length(), std::string::value_type()); - key_.clear(); - key_.reserve(0); + plat_->key_.assign(plat_->key_.length(), std::string::value_type()); + plat_->key_.clear(); + plat_->key_.reserve(0); + + delete plat_; } bool HMAC::Sign(const std::string& data, @@ -43,7 +49,7 @@ bool HMAC::Sign(const std::string& data, } CCHmac(algorithm, - key_.data(), key_.length(), data.data(), data.length(), + plat_->key_.data(), plat_->key_.length(), data.data(), data.length(), digest); return true; diff --git a/base/hmac_win.cc b/base/hmac_win.cc index 83ec26b..d611993 100644 --- a/base/hmac_win.cc +++ b/base/hmac_win.cc @@ -4,6 +4,9 @@ #include "base/hmac.h" +#include <windows.h> +#include <wincrypt.h> + #include <algorithm> #include <vector> @@ -11,42 +14,19 @@ namespace base { +struct HMACPlatformData { + // Windows Crypt API resources. + HCRYPTPROV provider_; + HCRYPTHASH hash_; + HCRYPTKEY hkey_; +}; + HMAC::HMAC(HashAlgorithm hash_alg, const unsigned char* key, int key_length) - : hash_alg_(hash_alg), - provider_(NULL), - hash_(NULL), - hkey_(NULL) { - if (!CryptAcquireContext(&provider_, NULL, NULL, + : hash_alg_(hash_alg), plat_(new HMACPlatformData()) { + if (!CryptAcquireContext(&plat_->provider_, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - provider_ = NULL; - ImportKey(key, key_length); -} - -HMAC::~HMAC() { - if (hkey_) - CryptDestroyKey(hkey_); - if (hash_) - CryptDestroyHash(hash_); - if (provider_) - CryptReleaseContext(provider_, 0); -} - -bool HMAC::Sign(const std::string& data, - unsigned char* digest, - int digest_length) { - if (!provider_ || !hkey_) - return false; - - switch (hash_alg_) { - case SHA1: - return SignWithSHA1(data, digest, digest_length); - default: - NOTREACHED(); - return false; - } -} + plat_->provider_ = NULL; -void HMAC::ImportKey(const unsigned char* key, int key_length) { // This code doesn't work on Win2k because PLAINTEXTKEYBLOB and // CRYPT_IPSEC_HMAC_KEY are not supported on Windows 2000. PLAINTEXTKEYBLOB // allows the import of an unencrypted key. For Win2k support, a cubmbersome @@ -70,38 +50,56 @@ void HMAC::ImportKey(const unsigned char* key, int key_length) { key_blob->key_size = key_length; memcpy(key_blob->key_data, key, key_length); - if (!CryptImportKey(provider_, &key_blob_storage[0], key_blob_storage.size(), - 0, CRYPT_IPSEC_HMAC_KEY, &hkey_)) { - hkey_ = NULL; + if (!CryptImportKey(plat_->provider_, &key_blob_storage[0], + key_blob_storage.size(), 0, CRYPT_IPSEC_HMAC_KEY, + &plat_->hkey_)) { + plat_->hkey_ = NULL; } // Destroy the copy of the key. SecureZeroMemory(key_blob->key_data, key_length); } -bool HMAC::SignWithSHA1(const std::string& data, - unsigned char* digest, - int digest_length) { - DCHECK(provider_); - DCHECK(hkey_); +HMAC::~HMAC() { + if (plat_->hkey_) + CryptDestroyKey(plat_->hkey_); + if (plat_->hash_) + CryptDestroyHash(plat_->hash_); + if (plat_->provider_) + CryptReleaseContext(plat_->provider_, 0); + + delete plat_; +} + +bool HMAC::Sign(const std::string& data, + unsigned char* digest, + int digest_length) { + if (!plat_->provider_ || !plat_->hkey_) + return false; + + if (hash_alg_ != SHA1) { + NOTREACHED(); + return false; + } - if (!CryptCreateHash(provider_, CALG_HMAC, hkey_, 0, &hash_)) + if (!CryptCreateHash( + plat_->provider_, CALG_HMAC, plat_->hkey_, 0, &plat_->hash_)) return false; HMAC_INFO hmac_info; memset(&hmac_info, 0, sizeof(hmac_info)); hmac_info.HashAlgid = CALG_SHA1; - if (!CryptSetHashParam(hash_, HP_HMAC_INFO, + if (!CryptSetHashParam(plat_->hash_, HP_HMAC_INFO, reinterpret_cast<BYTE*>(&hmac_info), 0)) return false; - if (!CryptHashData(hash_, + if (!CryptHashData(plat_->hash_, reinterpret_cast<const BYTE*>(data.data()), static_cast<DWORD>(data.size()), 0)) return false; DWORD sha1_size = digest_length; - if (!CryptGetHashParam(hash_, HP_HASHVAL, digest, &sha1_size, 0)) + if (!CryptGetHashParam(plat_->hash_, HP_HASHVAL, digest, &sha1_size, 0)) return false; return true; |