summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorgeorgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-01 20:42:51 +0000
committergeorgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-01 20:42:51 +0000
commit5dcf5261010aa0a4dadfc9c525a673ad7412915e (patch)
treee3a0a48042fbe46b2a646a24350bcbb94ef82f3a /chrome/browser
parentba6680fcdf06ea6bbb14e78f6b32d79e6d57c03e (diff)
downloadchromium_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')
-rw-r--r--chrome/browser/autofill/autofill_ie_toolbar_import_win.cc37
-rw-r--r--chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc7
-rw-r--r--chrome/browser/autofill/crypto/rc4_decryptor.h103
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_