| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/hmac.h" | 5 #include "base/hmac.h" |
| 6 |
| 7 #include <algorithm> |
| 8 #include <vector> |
| 9 |
| 6 #include "base/logging.h" | 10 #include "base/logging.h" |
| 7 | 11 |
| 12 namespace base { |
| 13 |
| 8 HMAC::HMAC(HashAlgorithm hash_alg, const unsigned char* key, int key_length) | 14 HMAC::HMAC(HashAlgorithm hash_alg, const unsigned char* key, int key_length) |
| 9 : hash_alg_(hash_alg), | 15 : hash_alg_(hash_alg), |
| 10 provider_(NULL), | 16 provider_(NULL), |
| 11 hash_(NULL), | 17 hash_(NULL), |
| 12 hkey_(NULL) { | 18 hkey_(NULL) { |
| 13 if (!CryptAcquireContext(&provider_, NULL, NULL, | 19 if (!CryptAcquireContext(&provider_, NULL, NULL, |
| 14 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) | 20 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) |
| 15 provider_ = NULL; | 21 provider_ = NULL; |
| 16 ImportKey(key, key_length); | 22 ImportKey(key, key_length); |
| 17 } | 23 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 34 switch (hash_alg_) { | 40 switch (hash_alg_) { |
| 35 case SHA1: | 41 case SHA1: |
| 36 return SignWithSHA1(data, digest, digest_length); | 42 return SignWithSHA1(data, digest, digest_length); |
| 37 default: | 43 default: |
| 38 NOTREACHED(); | 44 NOTREACHED(); |
| 39 return false; | 45 return false; |
| 40 } | 46 } |
| 41 } | 47 } |
| 42 | 48 |
| 43 void HMAC::ImportKey(const unsigned char* key, int key_length) { | 49 void HMAC::ImportKey(const unsigned char* key, int key_length) { |
| 44 if (key_length > kMaxKeySize) { | 50 // This code doesn't work on Win2k because PLAINTEXTKEYBLOB and |
| 45 NOTREACHED(); | 51 // CRYPT_IPSEC_HMAC_KEY are not supported on Windows 2000. PLAINTEXTKEYBLOB |
| 46 return; | 52 // allows the import of an unencrypted key. For Win2k support, a cubmbersome |
| 53 // exponent-of-one key procedure must be used: |
| 54 // http://support.microsoft.com/kb/228786/en-us |
| 55 // CRYPT_IPSEC_HMAC_KEY allows keys longer than 16 bytes. |
| 56 |
| 57 struct KeyBlob { |
| 58 BLOBHEADER header; |
| 59 DWORD key_size; |
| 60 BYTE key_data[1]; |
| 61 }; |
| 62 size_t key_blob_size = std::max(offsetof(KeyBlob, key_data) + key_length, |
| 63 sizeof(KeyBlob)); |
| 64 std::vector<BYTE> key_blob_storage = std::vector<BYTE>(key_blob_size); |
| 65 KeyBlob* key_blob = reinterpret_cast<KeyBlob*>(&key_blob_storage[0]); |
| 66 key_blob->header.bType = PLAINTEXTKEYBLOB; |
| 67 key_blob->header.bVersion = CUR_BLOB_VERSION; |
| 68 key_blob->header.reserved = 0; |
| 69 key_blob->header.aiKeyAlg = CALG_RC2; |
| 70 key_blob->key_size = key_length; |
| 71 memcpy(key_blob->key_data, key, key_length); |
| 72 |
| 73 if (!CryptImportKey(provider_, &key_blob_storage[0], key_blob_storage.size(), |
| 74 0, CRYPT_IPSEC_HMAC_KEY, &hkey_)) { |
| 75 hkey_ = NULL; |
| 47 } | 76 } |
| 48 | 77 |
| 49 struct { | |
| 50 BLOBHEADER header; | |
| 51 DWORD key_size; | |
| 52 BYTE key_data[kMaxKeySize]; | |
| 53 } key_blob; | |
| 54 key_blob.header.bType = PLAINTEXTKEYBLOB; | |
| 55 key_blob.header.bVersion = CUR_BLOB_VERSION; | |
| 56 key_blob.header.reserved = 0; | |
| 57 key_blob.header.aiKeyAlg = CALG_RC2; | |
| 58 key_blob.key_size = key_length; | |
| 59 memcpy(key_blob.key_data, key, key_length); | |
| 60 | |
| 61 if (!CryptImportKey(provider_, | |
| 62 reinterpret_cast<const BYTE *>(&key_blob), | |
| 63 sizeof(key_blob), 0, 0, &hkey_)) | |
| 64 hkey_ = NULL; | |
| 65 | |
| 66 // Destroy the copy of the key. | 78 // Destroy the copy of the key. |
| 67 SecureZeroMemory(key_blob.key_data, key_length); | 79 SecureZeroMemory(key_blob->key_data, key_length); |
| 68 } | 80 } |
| 69 | 81 |
| 70 bool HMAC::SignWithSHA1(const std::string& data, | 82 bool HMAC::SignWithSHA1(const std::string& data, |
| 71 unsigned char* digest, | 83 unsigned char* digest, |
| 72 int digest_length) { | 84 int digest_length) { |
| 73 DCHECK(provider_); | 85 DCHECK(provider_); |
| 74 DCHECK(hkey_); | 86 DCHECK(hkey_); |
| 75 | 87 |
| 76 if (!CryptCreateHash(provider_, CALG_HMAC, hkey_, 0, &hash_)) | 88 if (!CryptCreateHash(provider_, CALG_HMAC, hkey_, 0, &hash_)) |
| 77 return false; | 89 return false; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 88 static_cast<DWORD>(data.size()), 0)) | 100 static_cast<DWORD>(data.size()), 0)) |
| 89 return false; | 101 return false; |
| 90 | 102 |
| 91 DWORD sha1_size = digest_length; | 103 DWORD sha1_size = digest_length; |
| 92 if (!CryptGetHashParam(hash_, HP_HASHVAL, digest, &sha1_size, 0)) | 104 if (!CryptGetHashParam(hash_, HP_HASHVAL, digest, &sha1_size, 0)) |
| 93 return false; | 105 return false; |
| 94 | 106 |
| 95 return true; | 107 return true; |
| 96 } | 108 } |
| 97 | 109 |
| 110 } // namespace base |
| OLD | NEW |