diff options
author | georgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-01 20:42:51 +0000 |
---|---|---|
committer | georgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-01 20:42:51 +0000 |
commit | 5dcf5261010aa0a4dadfc9c525a673ad7412915e (patch) | |
tree | e3a0a48042fbe46b2a646a24350bcbb94ef82f3a /chrome/browser | |
parent | ba6680fcdf06ea6bbb14e78f6b32d79e6d57c03e (diff) | |
download | chromium_src-5dcf5261010aa0a4dadfc9c525a673ad7412915e.zip chromium_src-5dcf5261010aa0a4dadfc9c525a673ad7412915e.tar.gz chromium_src-5dcf5261010aa0a4dadfc9c525a673ad7412915e.tar.bz2 |
Import autofill toolbar decryption code into chromium - part 1 - public code.
BUG=60180
TEST=already unit-tested - the tests should not break
Review URL: http://codereview.chromium.org/4102011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64658 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
3 files changed, 130 insertions, 17 deletions
diff --git a/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc b/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc index dcfe0a5..0165f1c 100644 --- a/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc +++ b/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc @@ -9,6 +9,7 @@ #include "base/win/registry.h" #include "chrome/browser/autofill/autofill_profile.h" #include "chrome/browser/autofill/credit_card.h" +#include "chrome/browser/autofill/crypto/rc4_decryptor.h" #include "chrome/browser/autofill/field_types.h" #include "chrome/browser/autofill/personal_data_manager.h" #include "chrome/browser/sync/util/data_encryption.h" @@ -21,17 +22,6 @@ bool ImportCurrentUserProfiles(std::vector<AutoFillProfile>* profiles, std::vector<CreditCard>* credit_cards); namespace { -#if defined(GOOGLE_CHROME_BUILD) -#include "chrome/browser/autofill/internal/autofill_ie_toolbar_decryption.h" -#else // defined(GOOGLE_CHROME_BUILD) -inline std::wstring DecryptCCNumber(const std::wstring& data) { - return std::wstring(); -} -inline bool IsEmptySalt(const std::wstring& salt) { - return false; -} -#endif // defined(GOOGLE_CHROME_BUILD) - const wchar_t* const kProfileKey = L"Software\\Google\\Google Toolbar\\4.0\\Autofill\\Profiles"; const wchar_t* const kCreditCardKey = @@ -39,6 +29,31 @@ const wchar_t* const kCreditCardKey = const wchar_t* const kPasswordHashValue = L"password_hash"; const wchar_t* const kSaltValue = L"salt"; +// This is RC4 decryption for Toolbar credit card data. This is necessary +// because it is not standard, so Crypto api cannot be used. +std::wstring DecryptCCNumber(const std::wstring& data) { + const wchar_t* kEmptyKey = + L"\x3605\xCEE5\xCE49\x44F7\xCF4E\xF6CC\x604B\xFCBE\xC70A\x08FD"; + const size_t kMacLen = 10; + + if (data.length() <= kMacLen) + return std::wstring(); + + RC4Decryptor rc4_algorithm(kEmptyKey); + return rc4_algorithm.Run(data.substr(kMacLen)); +} + +bool IsEmptySalt(std::wstring const& salt) { + // Empty salt in IE Toolbar is \x1\x2...\x14 + if (salt.length() != 20) + return false; + for (size_t i = 0; i < salt.length(); ++i) { + if (salt[i] != i + 1) + return false; + } + return true; +} + string16 ReadAndDecryptValue(RegKey* key, const wchar_t* value_name) { DWORD data_type = REG_BINARY; DWORD data_size = 0; diff --git a/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc b/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc index 0512139..5b23ee5 100644 --- a/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc +++ b/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc @@ -198,8 +198,7 @@ TEST_F(AutofillIeToolbarImportTest, TestAutoFillImport) { L"5556666"); EXPECT_EQ(profiles[0].GetFieldText(AutoFillType(PHONE_FAX_WHOLE_NUMBER)), L"27775556666"); -#if defined(GOOGLE_CHROME_BUILD) - // We have the ability to export credit cards only in chrome build. + ASSERT_EQ(credit_cards.size(), 1); EXPECT_EQ(credit_cards[0].GetFieldText(AutoFillType(CREDIT_CARD_NAME)), credit_card[0].value); @@ -225,9 +224,5 @@ TEST_F(AutofillIeToolbarImportTest, TestAutoFillImport) { EXPECT_EQ(profiles.size(), 2); // Credit cards are. EXPECT_EQ(credit_cards.size(), 0); -#else // defined(GOOGLE_CHROME_BUILD) - // Cannot decrypt CC in non-chrome build. - EXPECT_EQ(credit_cards.size(), 0); -#endif // defined(GOOGLE_CHROME_BUILD) } diff --git a/chrome/browser/autofill/crypto/rc4_decryptor.h b/chrome/browser/autofill/crypto/rc4_decryptor.h new file mode 100644 index 0000000..2fb18ac --- /dev/null +++ b/chrome/browser/autofill/crypto/rc4_decryptor.h @@ -0,0 +1,103 @@ +// 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. + +#ifndef CHROME_BROWSER_AUTOFILL_CRYPTO_RC4_DECRYPTOR_H_ +#define CHROME_BROWSER_AUTOFILL_CRYPTO_RC4_DECRYPTOR_H_ + +#include <string> +#include "base/basictypes.h" +#include "base/scoped_ptr.h" + +// This is modified RC4 decryption used for import of Toolbar autofill data +// only. The difference from the Crypto Api implementation is twofold: +// First, it uses a non-standard key size (160 bit), not supported by Microsoft +// (it supports only 40 and 128 bit for RC4). Second, it codes 128 words with +// value 0x0020 at the beginning of the code to enhance security. +// This class used in chrome/browser/autofill/autofill_ie_toolbar_import_win.cc. +// This class should not be used anywhere else!!! +class RC4Decryptor { + public: + explicit RC4Decryptor(wchar_t const* password) { + PrepareKey(reinterpret_cast<const uint8 *>(password), + wcslen(password) * sizeof(wchar_t)); + std::wstring data; + // First 128 bytes should be spaces. + data.resize(128, L' '); + Run(data.c_str()); + } + + // Run the algorithm + std::wstring Run(const std::wstring& data) { + int data_size = data.length() * sizeof(wchar_t); + + scoped_array<wchar_t> buffer(new wchar_t[data.length() + 1]); + memset(buffer.get(), 0, (data.length() + 1) * sizeof(wchar_t)); + memcpy(buffer.get(), data.c_str(), data_size); + + RunInternal(reinterpret_cast<uint8 *>(buffer.get()), data_size); + + std::wstring result(buffer.get()); + + // Clear the memory + memset(buffer.get(), 0, data_size); + return result; + } + + private: + static const int kKeyDataSize = 256; + struct Rc4Key { + uint8 state[kKeyDataSize]; + uint8 x; + uint8 y; + }; + + void SwapByte(uint8* byte1, uint8* byte2) { + uint8 temp = *byte1; + *byte1 = *byte2; + *byte2 = temp; + } + + void PrepareKey(const uint8 *key_data, int key_data_len) { + uint8 index1 = 0; + uint8 index2 = 0; + uint8* state; + short counter; + + state = &key_.state[0]; + for (counter = 0; counter < kKeyDataSize; ++counter) + state[counter] = static_cast<uint8>(counter); + + key_.x = key_.y = 0; + + for (counter = 0; counter < kKeyDataSize; counter++) { + index2 = (key_data[index1] + state[counter] + index2) % kKeyDataSize; + SwapByte(&state[counter], &state[index2]); + index1 = (index1 + 1) % key_data_len; + } + } + + void RunInternal(uint8 *buffer, int buffer_len) { + uint8 x, y; + uint8 xor_index = 0; + uint8* state; + int counter; + + x = key_.x; + y = key_.y; + state = &key_.state[0]; + for (counter = 0; counter < buffer_len; ++counter) { + x = (x + 1) % kKeyDataSize; + y = (state[x] + y) % kKeyDataSize; + SwapByte(&state[x], &state[y]); + xor_index = (state[x] + state[y]) % kKeyDataSize; + buffer[counter] ^= state[xor_index]; + } + key_.x = x; + key_.y = y; + } + + Rc4Key key_; +}; + +#endif // CHROME_BROWSER_AUTOFILL_CRYPTO_RC4_DECRYPTOR_H_ |