diff options
author | dhollowa@chromium.org <dhollowa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-16 02:28:38 +0000 |
---|---|---|
committer | dhollowa@chromium.org <dhollowa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-16 02:28:38 +0000 |
commit | 4c8442fb310087c71bc7a8c2233dee9ad8c9b072 (patch) | |
tree | f3845e02cd8b4aa574315ea39d4473295d1ed977 /chrome/browser/password_manager | |
parent | beac9998f6cb2de039fa6d49f241ce4e924f05f4 (diff) | |
download | chromium_src-4c8442fb310087c71bc7a8c2233dee9ad8c9b072.zip chromium_src-4c8442fb310087c71bc7a8c2233dee9ad8c9b072.tar.gz chromium_src-4c8442fb310087c71bc7a8c2233dee9ad8c9b072.tar.bz2 |
AutoFill credit cards should be obfuscated on Linux
AutoFill credit card information now gets stored in obfuscated form on disc.
BUG=42038, 49115
TEST=EncryptorTest.CypherTextDiffers, EncryptorTest.DecryptError
Review URL: http://codereview.chromium.org/2931020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52596 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/password_manager')
-rw-r--r-- | chrome/browser/password_manager/encryptor_linux.cc | 113 | ||||
-rw-r--r-- | chrome/browser/password_manager/encryptor_unittest.cc | 6 |
2 files changed, 106 insertions, 13 deletions
diff --git a/chrome/browser/password_manager/encryptor_linux.cc b/chrome/browser/password_manager/encryptor_linux.cc index 44ed207..b109089 100644 --- a/chrome/browser/password_manager/encryptor_linux.cc +++ b/chrome/browser/password_manager/encryptor_linux.cc @@ -1,12 +1,59 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. #include "chrome/browser/password_manager/encryptor.h" +#include "base/crypto/encryptor.h" +#include "base/crypto/symmetric_key.h" #include "base/logging.h" +#include "base/scoped_ptr.h" #include "base/utf_string_conversions.h" +namespace { + +// Salt for Symmetric key derivation. +const char kSalt[] = "saltysalt"; + +// Key size required for 128 bit AES. +const size_t kDerivedKeySizeInBits = 128; + +// Constant for Symmetic key derivation. +const size_t kEncryptionIterations = 1; + +// Size of initialization vector for AES 128-bit. +const size_t kIVBlockSizeAES128 = 16; + +// Prefix for cypher text returned by obfuscation version. We prefix the +// cyphertext with this string so that future data migration can detect +// this and migrate to full encryption without data loss. +const char kObfuscationPrefix[] = "v10"; + +// Generates a newly allocated SymmetricKey object based a hard-coded password. +// Ownership of the key is passed to the caller. Returns NULL key if a key +// generation error occurs. +base::SymmetricKey* GetEncryptionKey() { + // We currently "obfuscate" by encrypting and decrypting with hard-coded + // password. We need to improve this password situation by moving a secure + // password into a system-level key store. + // http://crbug.com/25404 and http://crbug.com/49115 + std::string password = "peanuts"; + std::string salt(kSalt); + + // Create an encryption key from our password and salt. + scoped_ptr<base::SymmetricKey> encryption_key( + base::SymmetricKey::DeriveKeyFromPassword(base::SymmetricKey::AES, + password, + salt, + kEncryptionIterations, + kDerivedKeySizeInBits)); + DCHECK(encryption_key.get()); + + return encryption_key.release(); +} + +} // namespace + bool Encryptor::EncryptString16(const string16& plaintext, std::string* ciphertext) { return EncryptString(UTF16ToUTF8(plaintext), ciphertext); @@ -24,19 +71,69 @@ bool Encryptor::DecryptString16(const std::string& ciphertext, bool Encryptor::EncryptString(const std::string& plaintext, std::string* ciphertext) { - // This doesn't actually encrypt, we need to work on the Encryptor API. - // http://code.google.com/p/chromium/issues/detail?id=25404 + // This currently "obfuscates" by encrypting with hard-coded password. + // We need to improve this password situation by moving a secure password + // into a system-level key store. + // http://crbug.com/25404 and http://crbug.com/49115 + + if (plaintext.empty()) { + *ciphertext = std::string(); + return true; + } + + scoped_ptr<base::SymmetricKey> encryption_key(GetEncryptionKey()); + if (!encryption_key.get()) + return false; - // this does a copy - ciphertext->assign(plaintext.data(), plaintext.length()); + std::string iv(kIVBlockSizeAES128, ' '); + base::Encryptor encryptor; + if (!encryptor.Init(encryption_key.get(), base::Encryptor::CBC, iv)) + return false; + + if (!encryptor.Encrypt(plaintext, ciphertext)) + return false; + + // Prefix the cypher text with version information. + ciphertext->insert(0, kObfuscationPrefix); return true; } bool Encryptor::DecryptString(const std::string& ciphertext, std::string* plaintext) { - // This doesn't actually decrypt, we need to work on the Encryptor API. - // http://code.google.com/p/chromium/issues/detail?id=25404 + // This currently "obfuscates" by encrypting with hard-coded password. + // We need to improve this password situation by moving a secure password + // into a system-level key store. + // http://crbug.com/25404 and http://crbug.com/49115 + + if (ciphertext.empty()) { + *plaintext = std::string(); + return true; + } + + // Check that the incoming cyphertext was indeed encrypted with the expected + // version. If the prefix is not found then we'll assume we're dealing with + // old data saved as clear text and we'll return it directly. + // Credit card numbers are current legacy data, so false match with prefix + // won't happen. + if (ciphertext.find(kObfuscationPrefix) != 0) { + *plaintext = ciphertext; + return true; + } + + // Strip off the versioning prefix before decrypting. + std::string raw_ciphertext = ciphertext.substr(strlen(kObfuscationPrefix)); + + scoped_ptr<base::SymmetricKey> encryption_key(GetEncryptionKey()); + if (!encryption_key.get()) + return false; + + std::string iv(kIVBlockSizeAES128, ' '); + base::Encryptor encryptor; + if (!encryptor.Init(encryption_key.get(), base::Encryptor::CBC, iv)) + return false; + + if (!encryptor.Decrypt(raw_ciphertext, plaintext)) + return false; - plaintext->assign(ciphertext.data(), ciphertext.length()); return true; } diff --git a/chrome/browser/password_manager/encryptor_unittest.cc b/chrome/browser/password_manager/encryptor_unittest.cc index 8ca176f..4ae41e6 100644 --- a/chrome/browser/password_manager/encryptor_unittest.cc +++ b/chrome/browser/password_manager/encryptor_unittest.cc @@ -97,9 +97,6 @@ TEST_F(EncryptorTest, EncryptionDecryption) { EXPECT_EQ(plaintext, "hel"); } -// Encryption currently only enabled on Mac and Windows. -// TODO(dhollowa): http://crbug.com/49115 Implement secure store on Linux. -#if defined(OS_WIN) || defined(OS_MACOSX) TEST_F(EncryptorTest, CypherTextDiffers) { std::string plaintext; std::string result; @@ -137,11 +134,10 @@ TEST_F(EncryptorTest, DecryptError) { ASSERT_TRUE(Encryptor::EncryptString(plaintext, &ciphertext)); EXPECT_NE(plaintext, ciphertext); ASSERT_LT(4UL, ciphertext.size()); - ciphertext[3] = ciphertext[0] + 1; + ciphertext[3] = ciphertext[3] + 1; EXPECT_FALSE(Encryptor::DecryptString(ciphertext, &result)); EXPECT_NE(plaintext, result); EXPECT_TRUE(result.empty()); } -#endif } // namespace |