| Index: base/hmac_win.cc
|
| ===================================================================
|
| --- base/hmac_win.cc (revision 1686)
|
| +++ base/hmac_win.cc (working copy)
|
| @@ -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 @@
|
| }
|
|
|
| void HMAC::ImportKey(const unsigned char* key, int key_length) {
|
| - if (key_length > kMaxKeySize) {
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| + // 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 {
|
| + 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);
|
| + 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_,
|
| - reinterpret_cast<const BYTE *>(&key_blob),
|
| - sizeof(key_blob), 0, 0, &hkey_))
|
| + 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 @@
|
| return true;
|
| }
|
|
|
| +} // namespace base
|
|
|