summaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorjoi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-24 15:31:02 +0000
committerjoi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-24 15:31:02 +0000
commite2a5768bd0101579ba6416e00dcb131bd9fb930a (patch)
tree30eeb8dba2310e0f48df97f0a8325b8679390584 /components
parent88364961eeb66f0d812c2f8854832b9c49b09ddd (diff)
downloadchromium_src-e2a5768bd0101579ba6416e00dcb131bd9fb930a.zip
chromium_src-e2a5768bd0101579ba6416e00dcb131bd9fb930a.tar.gz
chromium_src-e2a5768bd0101579ba6416e00dcb131bd9fb930a.tar.bz2
Move ie7_password namespace to //components, so it can be used by components.
This will soon be used by the log-in related bits of WebData, which will be extracted along with the sign-in logic to //components/signin. TBR=ben@chromium.org BUG=233552 Review URL: https://codereview.chromium.org/14348027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@196154 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components')
-rw-r--r--components/webdata.gypi7
-rw-r--r--components/webdata/encryptor/ie7_password.cc144
-rw-r--r--components/webdata/encryptor/ie7_password.h46
3 files changed, 197 insertions, 0 deletions
diff --git a/components/webdata.gypi b/components/webdata.gypi
index ef99c61..bba421e 100644
--- a/components/webdata.gypi
+++ b/components/webdata.gypi
@@ -21,8 +21,15 @@
'webdata/encryptor/encryptor_password_mac.mm',
'webdata/encryptor/encryptor_posix.cc',
'webdata/encryptor/encryptor_win.cc',
+ 'webdata/encryptor/ie7_password.cc',
+ 'webdata/encryptor/ie7_password.h',
],
'conditions': [
+ ['OS!="win"', {
+ 'sources!': [
+ 'webdata/encryptor/ie7_password.cc'
+ ],
+ }],
['OS=="mac"', {
'sources!': [
'webdata/encryptor/encryptor_posix.cc',
diff --git a/components/webdata/encryptor/ie7_password.cc b/components/webdata/encryptor/ie7_password.cc
new file mode 100644
index 0000000..793fde8
--- /dev/null
+++ b/components/webdata/encryptor/ie7_password.cc
@@ -0,0 +1,144 @@
+// Copyright (c) 2011 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 "components/webdata/encryptor/ie7_password.h"
+
+#include <wincrypt.h>
+#include <string>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/sha1.h"
+#include "base/string_util.h"
+#include "base/stringprintf.h"
+
+namespace {
+
+// Structures that IE7/IE8 use to store a username/password.
+// Some of the fields might have been incorrectly reverse engineered.
+struct PreHeader {
+ DWORD pre_header_size; // Size of this header structure. Always 12.
+ DWORD header_size; // Size of the real Header: sizeof(Header) +
+ // item_count * sizeof(Entry);
+ DWORD data_size; // Size of the data referenced by the entries.
+};
+
+struct Header {
+ char wick[4]; // The string "WICK". I don't know what it means.
+ DWORD fixed_header_size; // The size of this structure without the entries:
+ // sizeof(Header).
+ DWORD item_count; // Number of entries. It should always be 2. One for
+ // the username, and one for the password.
+ wchar_t two_letters[2]; // Two unknown bytes.
+ DWORD unknown[2]; // Two unknown DWORDs.
+};
+
+struct Entry {
+ DWORD offset; // Offset where the data referenced by this entry is
+ // located.
+ FILETIME time_stamp; // Timestamp when the password got added.
+ DWORD string_length; // The length of the data string.
+};
+
+// Main data structure.
+struct PasswordEntry {
+ PreHeader pre_header; // Contains the size of the different sections.
+ Header header; // Contains the number of items.
+ Entry entry[1]; // List of entries containing a string. The first one
+ // is the username, the second one if the password.
+};
+
+} // namespace
+
+namespace ie7_password {
+
+bool GetUserPassFromData(const std::vector<unsigned char>& data,
+ std::wstring* username,
+ std::wstring* password) {
+ const PasswordEntry* information =
+ reinterpret_cast<const PasswordEntry*>(&data.front());
+
+ // Some expected values. If it's not what we expect we don't even try to
+ // understand the data.
+ if (information->pre_header.pre_header_size != sizeof(PreHeader))
+ return false;
+
+ if (information->header.item_count != 2) // Username and Password
+ return false;
+
+ if (information->header.fixed_header_size != sizeof(Header))
+ return false;
+
+ const uint8* ptr = &data.front();
+ const uint8* offset_to_data = ptr + information->pre_header.header_size +
+ information->pre_header.pre_header_size;
+
+ const Entry* user_entry = information->entry;
+ const Entry* pass_entry = user_entry+1;
+
+ *username = reinterpret_cast<const wchar_t*>(offset_to_data +
+ user_entry->offset);
+ *password = reinterpret_cast<const wchar_t*>(offset_to_data +
+ pass_entry->offset);
+ return true;
+}
+
+std::wstring GetUrlHash(const std::wstring& url) {
+ std::wstring lower_case_url = StringToLowerASCII(url);
+ // Get a data buffer out of our std::wstring to pass to SHA1HashString.
+ std::string url_buffer(
+ reinterpret_cast<const char*>(lower_case_url.c_str()),
+ (lower_case_url.size() + 1) * sizeof(wchar_t));
+ std::string hash_bin = base::SHA1HashString(url_buffer);
+
+ std::wstring url_hash;
+
+ // Transform the buffer to an hexadecimal string.
+ unsigned char checksum = 0;
+ for (size_t i = 0; i < hash_bin.size(); ++i) {
+ // std::string gives signed chars, which mess with StringPrintf and
+ // check_sum.
+ unsigned char hash_byte = static_cast<unsigned char>(hash_bin[i]);
+ checksum += hash_byte;
+ url_hash += base::StringPrintf(L"%2.2X", static_cast<unsigned>(hash_byte));
+ }
+ url_hash += base::StringPrintf(L"%2.2X", checksum);
+
+ return url_hash;
+}
+
+bool DecryptPassword(const std::wstring& url,
+ const std::vector<unsigned char>& data,
+ std::wstring* username, std::wstring* password) {
+ std::wstring lower_case_url = StringToLowerASCII(url);
+ DATA_BLOB input = {0};
+ DATA_BLOB output = {0};
+ DATA_BLOB url_key = {0};
+
+ input.pbData = const_cast<unsigned char*>(&data.front());
+ input.cbData = static_cast<DWORD>((data.size()) *
+ sizeof(std::string::value_type));
+
+ url_key.pbData = reinterpret_cast<unsigned char*>(
+ const_cast<wchar_t*>(lower_case_url.data()));
+ url_key.cbData = static_cast<DWORD>((lower_case_url.size() + 1) *
+ sizeof(std::wstring::value_type));
+
+ if (CryptUnprotectData(&input, NULL, &url_key, NULL, NULL,
+ CRYPTPROTECT_UI_FORBIDDEN, &output)) {
+ // Now that we have the decrypted information, we need to understand it.
+ std::vector<unsigned char> decrypted_data;
+ decrypted_data.resize(output.cbData);
+ memcpy(&decrypted_data.front(), output.pbData, output.cbData);
+
+ GetUserPassFromData(decrypted_data, username, password);
+
+ LocalFree(output.pbData);
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace ie7_password
diff --git a/components/webdata/encryptor/ie7_password.h b/components/webdata/encryptor/ie7_password.h
new file mode 100644
index 0000000..812dae3
--- /dev/null
+++ b/components/webdata/encryptor/ie7_password.h
@@ -0,0 +1,46 @@
+// 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.
+
+#ifndef COMPONENTS_WEBDATA_ENCRYPTOR_IE7_PASSWORD_H_
+#define COMPONENTS_WEBDATA_ENCRYPTOR_IE7_PASSWORD_H_
+
+#include <windows.h>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/time.h"
+
+// Contains the information read from the IE7/IE8 Storage2 key in the registry.
+struct IE7PasswordInfo {
+ // Hash of the url.
+ std::wstring url_hash;
+
+ // Encrypted data containing the username, password and some more undocumented
+ // fields.
+ std::vector<unsigned char> encrypted_data;
+
+ // When the login was imported.
+ base::Time date_created;
+};
+
+namespace ie7_password {
+
+// Parses a data structure to find the password and the username.
+bool GetUserPassFromData(const std::vector<unsigned char>& data,
+ std::wstring* username,
+ std::wstring* password);
+
+// Decrypts the username and password for a given data vector using the url as
+// the key.
+bool DecryptPassword(const std::wstring& url,
+ const std::vector<unsigned char>& data,
+ std::wstring* username, std::wstring* password);
+
+// Returns the hash of a url.
+std::wstring GetUrlHash(const std::wstring& url);
+
+} // namespace ie7_password
+
+#endif // COMPONENTS_WEBDATA_ENCRYPTOR_IE7_PASSWORD_H_