diff options
-rw-r--r-- | base/SConscript | 2 | ||||
-rw-r--r-- | base/base.xcodeproj/project.pbxproj | 10 | ||||
-rw-r--r-- | base/build/base.vcproj | 4 | ||||
-rw-r--r-- | base/hmac.h | 36 | ||||
-rw-r--r-- | base/hmac_mac.cc | 52 | ||||
-rw-r--r-- | base/hmac_unittest.cc | 131 | ||||
-rw-r--r-- | base/hmac_win.cc (renamed from base/hmac.cc) | 51 | ||||
-rw-r--r-- | chrome/browser/safe_browsing/safe_browsing_util.cc | 6 |
8 files changed, 238 insertions, 54 deletions
diff --git a/base/SConscript b/base/SConscript index d9b1c8f..05b9ed1 100644 --- a/base/SConscript +++ b/base/SConscript @@ -80,7 +80,7 @@ if env['PLATFORM'] == 'win32': 'clipboard_util.cc', 'event_recorder.cc', 'file_version_info.cc', - 'hmac.cc', # Depends on OpenSSL; Mac team will investigate. + 'hmac_win.cc', # This group all depends on MessageLoop. 'idle_timer.cc', diff --git a/base/base.xcodeproj/project.pbxproj b/base/base.xcodeproj/project.pbxproj index 56fda9d..0a43e64 100644 --- a/base/base.xcodeproj/project.pbxproj +++ b/base/base.xcodeproj/project.pbxproj @@ -81,6 +81,8 @@ 7BAE30E70E6D93A300C3F750 /* simple_thread.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BAE30E20E6D939800C3F750 /* simple_thread.cc */; }; 7BAE38AC0E6EFDBA00C3F750 /* thread_local_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BAE38A90E6EFD9900C3F750 /* thread_local_posix.cc */; }; 7BAE38AF0E6EFDC300C3F750 /* thread_local_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BAE38AB0E6EFD9900C3F750 /* thread_local_unittest.cc */; }; + 7BAE392A0E6F4EEF00C3F750 /* hmac_mac.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BAE39220E6F4EEC00C3F750 /* hmac_mac.cc */; }; + 7BAE392B0E6F4EF200C3F750 /* hmac_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BAE39240E6F4EEC00C3F750 /* hmac_unittest.cc */; }; 7BAF501C0E50B84200CA8A07 /* base_paths.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF501B0E50B84200CA8A07 /* base_paths.cc */; }; 7BAF50760E50B8F100CA8A07 /* file_version_info_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF50740E50B8F100CA8A07 /* file_version_info_mac.mm */; }; 7BD8F4A10E65AA4600034DE9 /* process_util_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BD8F49F0E65AA2400034DE9 /* process_util_posix.cc */; }; @@ -351,6 +353,9 @@ 7BAE38A90E6EFD9900C3F750 /* thread_local_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = thread_local_posix.cc; sourceTree = "<group>"; }; 7BAE38AA0E6EFD9900C3F750 /* thread_local_storage_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = thread_local_storage_unittest.cc; sourceTree = "<group>"; }; 7BAE38AB0E6EFD9900C3F750 /* thread_local_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = thread_local_unittest.cc; sourceTree = "<group>"; }; + 7BAE39220E6F4EEC00C3F750 /* hmac_mac.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hmac_mac.cc; sourceTree = "<group>"; }; + 7BAE39240E6F4EEC00C3F750 /* hmac_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hmac_unittest.cc; sourceTree = "<group>"; }; + 7BAE39BA0E6F576200C3F750 /* hmac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hmac.h; sourceTree = "<group>"; }; 7BAF4F7B0E50A3BD00CA8A07 /* logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logging.h; sourceTree = "<group>"; }; 7BAF501B0E50B84200CA8A07 /* base_paths.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = base_paths.cc; sourceTree = "<group>"; }; 7BAF50740E50B8F100CA8A07 /* file_version_info_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = file_version_info_mac.mm; sourceTree = "<group>"; }; @@ -768,6 +773,9 @@ 93611B160E5A875D00F9405D /* histogram.cc */, 93611B170E5A875D00F9405D /* histogram.h */, 93611B190E5A878400F9405D /* histogram_unittest.cc */, + 7BAE39BA0E6F576200C3F750 /* hmac.h */, + 7BAE39220E6F4EEC00C3F750 /* hmac_mac.cc */, + 7BAE39240E6F4EEC00C3F750 /* hmac_unittest.cc */, 8254030F0D92D1E80006B936 /* iat_patch.cc */, 825403100D92D1E80006B936 /* iat_patch.h */, 825403110D92D1E80006B936 /* icu_util.cc */, @@ -1210,6 +1218,7 @@ A5A0268E0E4A2BDC00498DA9 /* file_util_posix.cc in Sources */, 7BAF50760E50B8F100CA8A07 /* file_version_info_mac.mm in Sources */, 93611B180E5A875D00F9405D /* histogram.cc in Sources */, + 7BAE392A0E6F4EEF00C3F750 /* hmac_mac.cc in Sources */, 8216A5060E34DBDD00EE374C /* icu_util.cc in Sources */, ABF4B9AF0DC2BC6200A6E319 /* json_reader.cc in Sources */, ABF4B9B00DC2BC6500A6E319 /* json_writer.cc in Sources */, @@ -1284,6 +1293,7 @@ A5CE1D2B0E55F4D800AD0606 /* file_util_unittest.cc in Sources */, 7B78D3910E54FE0100609465 /* file_version_info_unittest.cc in Sources */, 93611B1A0E5A878400F9405D /* histogram_unittest.cc in Sources */, + 7BAE392B0E6F4EF200C3F750 /* hmac_unittest.cc in Sources */, AB956E0A0E5DDC0900BBE9D8 /* image_operations_unittest.cc in Sources */, 7B78D3920E54FE0100609465 /* json_reader_unittest.cc in Sources */, 7B78D3930E54FE0100609465 /* json_writer_unittest.cc in Sources */, diff --git a/base/build/base.vcproj b/base/build/base.vcproj index add54fe..27d7e3c 100644 --- a/base/build/base.vcproj +++ b/base/build/base.vcproj @@ -310,11 +310,11 @@ > </File> <File - RelativePath="..\hmac.cc" + RelativePath="..\hmac.h" > </File> <File - RelativePath="..\hmac.h" + RelativePath="..\hmac_win.cc" > </File> <File diff --git a/base/hmac.h b/base/hmac.h index dac4e82..f9c0e604 100644 --- a/base/hmac.h +++ b/base/hmac.h @@ -1,20 +1,26 @@ // Copyright (c) 2006-2008 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. -// + // Utility class for calculating the HMAC for a given message. We currently // only support SHA1 for the hash algorithm, but this can be extended easily. -#ifndef BASE_HMAC_H__ -#define BASE_HMAC_H__ +#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 { + class HMAC { public: // The set of supported hash functions. Extend as required. @@ -25,16 +31,17 @@ class HMAC { HMAC(HashAlgorithm hash_alg, const unsigned char* key, int key_length); ~HMAC(); - // Returns the HMAC in 'digest' for the message in 'data' and the key - // specified in the contructor. + // Calculates the HMAC for the message in |data| using the algorithm and key + // supplied to the constructor. The HMAC is returned in |digest|, which + // has |digest_length| bytes of storage available. 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. - // TODO(paulg): Bug: http://b/1084719, 'ImportKey' will not currently work on - // Windows 2000 since it requires special handling for importing - // keys. See this link for details: - // http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/2004-06/0270.html void ImportKey(const unsigned char* key, int key_length); // Returns the SHA1 hash of 'data' and 'key' in 'digest'. If there was any @@ -43,10 +50,6 @@ class HMAC { unsigned char* digest, int digest_length); - // Required for the SHA1 key_blob struct. We limit this to 16 bytes since - // Windows 2000 doesn't support keys larger than that. - static const int kMaxKeySize = 16; - // The hash algorithm to use. HashAlgorithm hash_alg_; @@ -54,10 +57,11 @@ class HMAC { HCRYPTPROV provider_; HCRYPTHASH hash_; HCRYPTKEY hkey_; +#endif // OS_WIN - DISALLOW_EVIL_CONSTRUCTORS(HMAC); + DISALLOW_COPY_AND_ASSIGN(HMAC); }; +} // namespace base -#endif // BASE_HMAC_H__ - +#endif // BASE_HMAC_H_ diff --git a/base/hmac_mac.cc b/base/hmac_mac.cc new file mode 100644 index 0000000..0542a70 --- /dev/null +++ b/base/hmac_mac.cc @@ -0,0 +1,52 @@ +// Copyright (c) 2008 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/hmac.h" + +#include <CommonCrypto/CommonHMAC.h> + +#include "base/logging.h" + +namespace base { + +HMAC::HMAC(HashAlgorithm hash_alg, const unsigned char* key, int key_length) + : hash_alg_(hash_alg), + key_(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); +} + +bool HMAC::Sign(const std::string& data, + unsigned char* digest, + int digest_length) { + CCHmacAlgorithm algorithm; + int algorithm_digest_length; + switch (hash_alg_) { + case SHA1: + algorithm = kCCHmacAlgSHA1; + algorithm_digest_length = CC_SHA1_DIGEST_LENGTH; + break; + default: + NOTREACHED(); + return false; + } + + if (digest_length < algorithm_digest_length) { + NOTREACHED(); + return false; + } + + CCHmac(algorithm, + key_.data(), key_.length(), data.data(), data.length(), + digest); + + return true; +} + +} // namespace base diff --git a/base/hmac_unittest.cc b/base/hmac_unittest.cc index 3ff2f9f..9881369 100644 --- a/base/hmac_unittest.cc +++ b/base/hmac_unittest.cc @@ -7,21 +7,23 @@ #include "base/hmac.h" #include "testing/gtest/include/gtest/gtest.h" -static const int kKeySize = 16; static const int kDigestSize = 20; -// Client key. -const unsigned char kClientKey[kKeySize] = - { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd, - 0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 }; +TEST(HMACTest, HmacSafeBrowsingResponseTest) { + const int kKeySize = 16; + + // Client key. + const unsigned char kClientKey[kKeySize] = + { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd, + 0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 }; -// Expected HMAC result using kMessage and kClientKey. -const unsigned char kReceivedHmac[kDigestSize] = - { 0xb9, 0x3c, 0xd6, 0xf0, 0x49, 0x47, 0xe2, 0x52, - 0x59, 0x7a, 0xbd, 0x1f, 0x2b, 0x4c, 0x83, 0xad, - 0x86, 0xd2, 0x48, 0x85 }; + // Expected HMAC result using kMessage and kClientKey. + const unsigned char kReceivedHmac[kDigestSize] = + { 0xb9, 0x3c, 0xd6, 0xf0, 0x49, 0x47, 0xe2, 0x52, + 0x59, 0x7a, 0xbd, 0x1f, 0x2b, 0x4c, 0x83, 0xad, + 0x86, 0xd2, 0x48, 0x85 }; -const char kMessage[] = + const char kMessage[] = "n:1896\ni:goog-malware-shavar\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shav" "ar_s_445-450\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_439-444\nu:s" ".ytimg.com/safebrowsing/rd/goog-malware-shavar_s_437\nu:s.ytimg.com/safebrowsi" @@ -47,12 +49,115 @@ const char kMessage[] = "-phish-shavar_a_2629-2631\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2" "626-2628\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2625\n"; -TEST(HMACTest, HmacSafeBrowsingResponseTest) { std::string message_data(kMessage); - HMAC hmac(HMAC::SHA1, kClientKey, kKeySize); + base::HMAC hmac(base::HMAC::SHA1, kClientKey, kKeySize); unsigned char calculated_hmac[kDigestSize]; EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kDigestSize)); EXPECT_EQ(memcmp(kReceivedHmac, calculated_hmac, kDigestSize), 0); } + +// Test cases from RFC 2202 section 3 +TEST(HMACTest, RFC2202TestCases) { + const struct { + const char *key; + const int key_len; + const char *data; + const int data_len; + const char *digest; + } cases[] = { + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B", 20, + "Hi There", 8, + "\xB6\x17\x31\x86\x55\x05\x72\x64\xE2\x8B\xC0\xB6\xFB\x37\x8C\x8E" + "\xF1\x46\xBE\x00" }, + { "Jefe", 4, + "what do ya want for nothing?", 28, + "\xEF\xFC\xDF\x6A\xE5\xEB\x2F\xA2\xD2\x74\x16\xD5\xF1\x84\xDF\x9C" + "\x25\x9A\x7C\x79" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA", 20, + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD", 50, + "\x12\x5D\x73\x42\xB9\xAC\x11\xCD\x91\xA3\x9A\xF4\x8A\xA1\x7B\x4F" + "\x63\xF1\x75\xD3" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25, + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD", 50, + "\x4C\x90\x07\xF4\x02\x62\x50\xC6\xBC\x84\x14\xF9\xBF\x50\xC8\x6C" + "\x2D\x72\x35\xDA" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C", 20, + "Test With Truncation", 20, + "\x4C\x1A\x03\x42\x4B\x55\xE0\x7F\xE7\xF2\x7B\xE1\xD5\x8B\xB9\x32" + "\x4A\x9A\x5A\x04" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", + 80, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + "\xAA\x4A\xE5\xE1\x52\x72\xD0\x0E\x95\x70\x56\x37\xCE\x8A\x3B\x55" + "\xED\x40\x21\x12" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", + 80, + "Test Using Larger Than Block-Size Key and Larger " + "Than One Block-Size Data", 73, + "\xE8\xE9\x9D\x0F\x45\x23\x7D\x78\x6D\x6B\xBA\xA7\x96\x5C\x78\x08" + "\xBB\xFF\x1A\x91" } + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { + base::HMAC hmac(base::HMAC::SHA1, + reinterpret_cast<const unsigned char*>(cases[i].key), + cases[i].key_len); + std::string data_string(cases[i].data, cases[i].data_len); + unsigned char digest[kDigestSize]; + EXPECT_TRUE(hmac.Sign(data_string, digest, kDigestSize)); + EXPECT_EQ(memcmp(cases[i].digest, digest, kDigestSize), 0); + } +} + +TEST(HMACTest, HMACObjectReuse) { + const char *key = + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"; + const int key_len = 80; + + const struct { + const char *data; + const int data_len; + const char *digest; + } cases[] = { + { "Test Using Larger Than Block-Size Key - Hash Key First", 54, + "\xAA\x4A\xE5\xE1\x52\x72\xD0\x0E\x95\x70\x56\x37\xCE\x8A\x3B\x55" + "\xED\x40\x21\x12" }, + { "Test Using Larger Than Block-Size Key and Larger " + "Than One Block-Size Data", 73, + "\xE8\xE9\x9D\x0F\x45\x23\x7D\x78\x6D\x6B\xBA\xA7\x96\x5C\x78\x08" + "\xBB\xFF\x1A\x91" } + }; + + base::HMAC hmac(base::HMAC::SHA1, + reinterpret_cast<const unsigned char*>(key), key_len); + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { + std::string data_string(cases[i].data, cases[i].data_len); + unsigned char digest[kDigestSize]; + EXPECT_TRUE(hmac.Sign(data_string, digest, kDigestSize)); + EXPECT_EQ(memcmp(cases[i].digest, digest, kDigestSize), 0); + } +} diff --git a/base/hmac.cc b/base/hmac_win.cc index 074491d..83ec26b 100644 --- a/base/hmac.cc +++ b/base/hmac_win.cc @@ -3,8 +3,14 @@ // found in the LICENSE file. #include "base/hmac.h" + +#include <algorithm> +#include <vector> + #include "base/logging.h" +namespace base { + HMAC::HMAC(HashAlgorithm hash_alg, const unsigned char* key, int key_length) : hash_alg_(hash_alg), provider_(NULL), @@ -41,30 +47,36 @@ bool HMAC::Sign(const std::string& data, } void HMAC::ImportKey(const unsigned char* key, int key_length) { - if (key_length > kMaxKeySize) { - NOTREACHED(); - return; - } - - struct { + // 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 + // exponent-of-one key procedure must be used: + // http://support.microsoft.com/kb/228786/en-us + // CRYPT_IPSEC_HMAC_KEY allows keys longer than 16 bytes. + + struct KeyBlob { BLOBHEADER header; DWORD key_size; - BYTE key_data[kMaxKeySize]; - } key_blob; - key_blob.header.bType = PLAINTEXTKEYBLOB; - key_blob.header.bVersion = CUR_BLOB_VERSION; - key_blob.header.reserved = 0; - key_blob.header.aiKeyAlg = CALG_RC2; - key_blob.key_size = key_length; - memcpy(key_blob.key_data, key, key_length); - - if (!CryptImportKey(provider_, - reinterpret_cast<const BYTE *>(&key_blob), - sizeof(key_blob), 0, 0, &hkey_)) + BYTE key_data[1]; + }; + size_t key_blob_size = std::max(offsetof(KeyBlob, key_data) + key_length, + sizeof(KeyBlob)); + std::vector<BYTE> key_blob_storage = std::vector<BYTE>(key_blob_size); + KeyBlob* key_blob = reinterpret_cast<KeyBlob*>(&key_blob_storage[0]); + key_blob->header.bType = PLAINTEXTKEYBLOB; + key_blob->header.bVersion = CUR_BLOB_VERSION; + key_blob->header.reserved = 0; + key_blob->header.aiKeyAlg = CALG_RC2; + 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; + } // Destroy the copy of the key. - SecureZeroMemory(key_blob.key_data, key_length); + SecureZeroMemory(key_blob->key_data, key_length); } bool HMAC::SignWithSHA1(const std::string& data, @@ -95,3 +107,4 @@ bool HMAC::SignWithSHA1(const std::string& data, return true; } +} // namespace base diff --git a/chrome/browser/safe_browsing/safe_browsing_util.cc b/chrome/browser/safe_browsing/safe_browsing_util.cc index 1731d75..9ddfbb3 100644 --- a/chrome/browser/safe_browsing/safe_browsing_util.cc +++ b/chrome/browser/safe_browsing/safe_browsing_util.cc @@ -147,9 +147,9 @@ bool VerifyMAC(const std::string& key, const std::string& mac, std::string decoded_mac; net::Base64Decode(mac_copy, &decoded_mac); - HMAC hmac(HMAC::SHA1, - reinterpret_cast<const unsigned char*>(decoded_key.data()), - static_cast<int>(decoded_key.length())); + base::HMAC hmac(base::HMAC::SHA1, + reinterpret_cast<const unsigned char*>(decoded_key.data()), + static_cast<int>(decoded_key.length())); const std::string data_str(data, data_length); unsigned char digest[kSafeBrowsingMacDigestSize]; if (!hmac.Sign(data_str, digest, kSafeBrowsingMacDigestSize)) |