Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(666)

Unified Diff: components/os_crypt/os_crypt_linux.cc

Issue 1973483002: OSCrypt for POSIX uses libsecret to store a randomised encryption key. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Refactored CL Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/os_crypt/os_crypt_linux.cc
diff --git a/components/os_crypt/os_crypt_posix.cc b/components/os_crypt/os_crypt_linux.cc
similarity index 54%
copy from components/os_crypt/os_crypt_posix.cc
copy to components/os_crypt/os_crypt_linux.cc
index 44f04b3801fead7d45d2758260c9721db6bf9334..b66aca07da0be75ad5d1db72df285352747aec33 100644
--- a/components/os_crypt/os_crypt_posix.cc
+++ b/components/os_crypt/os_crypt_linux.cc
@@ -1,4 +1,4 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright 2016 The Chromium Authors. All rights reserved.
vabr (Chromium) 2016/05/13 15:10:18 Looking at the code in this file, I see two main i
cfroussios 2016/05/13 17:09:12 (1) The source of the problem is that OSCrypt is a
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,10 +6,12 @@
#include <stddef.h>
+#include <functional>
#include <memory>
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
+#include "components/os_crypt/key_storage_linux.h"
#include "crypto/encryptor.h"
#include "crypto/symmetric_key.h"
@@ -27,41 +29,89 @@ const size_t kEncryptionIterations = 1;
// Size of initialization vector for AES 128-bit.
const size_t kIVBlockSizeAES128 = 16;
+// Used for array indexing
+enum Version {
+ V10 = 0,
+ V11 = 1,
+};
+
// 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";
+const char* kObfuscationPrefix[] = {
+ "v10", "v11",
+};
+
+// Use a mocked key storage and don't try to contact a real service.
+bool use_mock = false;
vabr (Chromium) 2016/05/13 15:10:19 nit: Please prefix all global variables with g_.
cfroussios 2016/05/13 17:09:12 Done.
+
+std::unique_ptr<KeyStorageMock> mock;
vabr (Chromium) 2016/05/13 15:10:19 Only plain old data can be a static variable. uniq
cfroussios 2016/05/13 17:09:12 Acknowledged.
+
+// Lazy acquisition of a KeyStorage. Will be null if no service is found.
+// Will return a mock if |use_mock| is true.
+KeyStorage* GetKeyStorage() {
+ if (use_mock) {
+ return mock.get();
+ }
+ static std::unique_ptr<KeyStorage> key_storage(KeyStorage::FindService());
vabr (Chromium) 2016/05/13 15:10:18 Also here, cannot use unique_ptr, because it has a
cfroussios 2016/05/13 17:09:12 Acknowledged.
+ return key_storage.get();
+}
+
+// Returns a cached instance of peanuts
+std::string* GetPasswordV10() {
+ static std::unique_ptr<std::string> password(new std::string("peanuts"));
vabr (Chromium) 2016/05/13 15:10:19 Also here.
cfroussios 2016/05/13 17:09:12 Acknowledged.
+ return password.get();
+}
+
+// Caches and returns the password from the KeyStorage or null if there is no
+// service.
+// Caching is disabled when mocking.
+std::string* GetPasswordV11() {
+ if (use_mock)
+ return new std::string(GetKeyStorage()->GetKey());
+
+ static std::unique_ptr<std::string> password(
+ GetKeyStorage() ? new std::string(GetKeyStorage()->GetKey()) : nullptr);
+ return password.get();
+}
+
+std::function<std::string*()> get_password[] = {
vabr (Chromium) 2016/05/13 15:10:19 std::function is not yet allowed. http://chromium-
cfroussios 2016/05/13 17:09:12 Acknowledged.
+ &GetPasswordV10, &GetPasswordV11,
+};
// 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.
-crypto::SymmetricKey* GetEncryptionKey() {
+std::unique_ptr<crypto::SymmetricKey> GetEncryptionKey(Version version) {
// 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);
+ std::string* password = get_password[version]();
+ if (password == nullptr)
+ return nullptr;
+
// Create an encryption key from our password and salt.
std::unique_ptr<crypto::SymmetricKey> encryption_key(
- crypto::SymmetricKey::DeriveKeyFromPassword(crypto::SymmetricKey::AES,
- password,
- salt,
- kEncryptionIterations,
- kDerivedKeySizeInBits));
+ crypto::SymmetricKey::DeriveKeyFromPassword(
+ crypto::SymmetricKey::AES, *password, salt, kEncryptionIterations,
+ kDerivedKeySizeInBits));
DCHECK(encryption_key.get());
- return encryption_key.release();
+ return encryption_key;
}
} // namespace
+// static
bool OSCrypt::EncryptString16(const base::string16& plaintext,
std::string* ciphertext) {
return EncryptString(base::UTF16ToUTF8(plaintext), ciphertext);
}
+// static
bool OSCrypt::DecryptString16(const std::string& ciphertext,
base::string16* plaintext) {
std::string utf8;
@@ -72,6 +122,7 @@ bool OSCrypt::DecryptString16(const std::string& ciphertext,
return true;
}
+// static
bool OSCrypt::EncryptString(const std::string& plaintext,
std::string* ciphertext) {
// This currently "obfuscates" by encrypting with hard-coded password.
@@ -84,7 +135,12 @@ bool OSCrypt::EncryptString(const std::string& plaintext,
return true;
}
- std::unique_ptr<crypto::SymmetricKey> encryption_key(GetEncryptionKey());
+ // If a KeyStorage is available, use a password backed by the KeyStorage.
+ // Otherwise use the hardcode password.
+ Version version = GetKeyStorage() ? Version::V11 : Version::V10;
+
+ std::unique_ptr<crypto::SymmetricKey> encryption_key(
+ GetEncryptionKey(version));
if (!encryption_key.get())
return false;
@@ -96,11 +152,13 @@ bool OSCrypt::EncryptString(const std::string& plaintext,
if (!encryptor.Encrypt(plaintext, ciphertext))
return false;
+ // TODO(cfrousios) update with encryption type used
vabr (Chromium) 2016/05/13 15:10:18 nit: Unless this is something planned for the next
cfroussios 2016/05/13 17:09:12 Done.
// Prefix the cypher text with version information.
- ciphertext->insert(0, kObfuscationPrefix);
+ ciphertext->insert(0, kObfuscationPrefix[version]);
return true;
}
+// static
bool OSCrypt::DecryptString(const std::string& ciphertext,
std::string* plaintext) {
// This currently "obfuscates" by encrypting with hard-coded password.
@@ -113,20 +171,27 @@ bool OSCrypt::DecryptString(const std::string& ciphertext,
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) {
+ // Check that the incoming cyphertext was encrypted and with what version.
+ // Credit card numbers are current legacy unencrypted data, so false match
+ // with prefix won't happen.
+ Version version;
+ if (ciphertext.find(kObfuscationPrefix[Version::V10]) == 0) {
vabr (Chromium) 2016/05/13 15:10:19 Could you use StartsWith from base/strings/string_
cfroussios 2016/05/13 17:09:12 I'm not sure it is more efficient. find runs on th
+ version = Version::V10;
+ } else if (ciphertext.find(kObfuscationPrefix[Version::V11]) == 0) {
+ version = Version::V11;
+ } else {
+ // 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.
*plaintext = ciphertext;
return true;
}
// Strip off the versioning prefix before decrypting.
- std::string raw_ciphertext = ciphertext.substr(strlen(kObfuscationPrefix));
+ std::string raw_ciphertext =
+ ciphertext.substr(strlen(kObfuscationPrefix[version]));
- std::unique_ptr<crypto::SymmetricKey> encryption_key(GetEncryptionKey());
+ std::unique_ptr<crypto::SymmetricKey> encryption_key(
+ GetEncryptionKey(version));
if (!encryption_key.get())
return false;
@@ -140,3 +205,11 @@ bool OSCrypt::DecryptString(const std::string& ciphertext,
return true;
}
+
+// static
+KeyStorageMock* OSCrypt::UseMockKeyStorage(bool use) {
+ use_mock = use;
+ if (!mock.get())
+ mock.reset(new KeyStorageMock());
+ return mock.get();
+}

Powered by Google App Engine
This is Rietveld 408576698