Commit 265b3947 authored by Will Harris's avatar Will Harris Committed by Commit Bot

Rework os_crypt on Windows to not always need access to DPAPI.

A data encryption key is stored in profile and encrypted with
DPAPI. DPAPI is needed during initialization but not during
encrypt/decrypt operations. Data encrypted with the new key
has a header to indicate the correct key to use, or whether
it was originally encrypted with raw DPAPI.

This allows code that uses os_crypt to run inside the sandbox
as long as Init() is called before lockdown, or the key is
manually set by calling SetRawEncryptionKey().

The network process, which uses os_crypt to encrypt some
cookies, is now passed the encryption key via the mojo
SetEncryptionKey interface, which is already used on macOS
for the same purpose.

NOTE: Reverting this CL will cause user data loss so
please consult before doing so.

BUG=1000799

Change-Id: I4453c4efbe52eaf4a264e12eb789219578e9caa6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1842671Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarChristos Froussios <cfroussios@chromium.org>
Commit-Queue: Will Harris <wfh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#707696}
parent 113d3089
......@@ -75,6 +75,7 @@
#include "components/crash/content/app/crash_export_thunks.h"
#include "components/crash/content/app/dump_hung_process_with_ptype.h"
#include "components/crash/core/common/crash_key.h"
#include "components/os_crypt/os_crypt.h"
#include "components/version_info/channel.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
......@@ -510,6 +511,13 @@ void ChromeBrowserMainPartsWin::PreMainMessageLoopStart() {
// setup.exe. In Chrome, these strings are in the locale files.
SetupInstallerUtilStrings();
PrefService* local_state = g_browser_process->local_state();
DCHECK(local_state);
// Initialize the OSCrypt.
bool os_crypt_init = OSCrypt::Init(local_state);
DCHECK(os_crypt_init);
ChromeBrowserMainParts::PreMainMessageLoopStart();
if (!parameters().ui_task) {
// Make sure that we know how to handle exceptions from the message loop.
......
......@@ -668,9 +668,10 @@ void SystemNetworkContextManager::OnNetworkServiceCreated(
chrome::GetDefaultUserDataDirectory(&config->user_data_path);
content::GetNetworkService()->SetCryptConfig(std::move(config));
#endif
#if defined(OS_MACOSX)
content::GetNetworkService()->SetEncryptionKey(
OSCrypt::GetRawEncryptionKey());
#if defined(OS_WIN) || defined(OS_MACOSX)
std::string key = OSCrypt::GetRawEncryptionKey();
DCHECK(!key.empty());
content::GetNetworkService()->SetEncryptionKey(key);
#endif
// Asynchronously reapply the most recently received CRLSet (if any).
......
......@@ -331,7 +331,6 @@
#if defined(OS_MACOSX)
#include "chrome/browser/ui/cocoa/apps/quit_with_apps_controller_mac.h"
#include "chrome/browser/ui/cocoa/confirm_quit.h"
#include "components/os_crypt/os_crypt.h"
#endif
#if defined(OS_WIN)
......@@ -345,6 +344,10 @@
#include "chrome/browser/safe_browsing/settings_reset_prompt/settings_reset_prompt_prefs_manager.h"
#endif
#if defined(OS_WIN) || defined(OS_MACOSX)
#include "components/os_crypt/os_crypt.h"
#endif
#if defined(OS_WIN) || defined(OS_MACOSX) || \
(defined(OS_LINUX) && !defined(OS_CHROMEOS))
#include "chrome/browser/browser_switcher/browser_switcher_prefs.h"
......@@ -729,11 +732,14 @@ void RegisterLocalState(PrefRegistrySimple* registry) {
#if defined(OS_MACOSX)
confirm_quit::RegisterLocalState(registry);
OSCrypt::RegisterLocalPrefs(registry);
QuitWithAppsController::RegisterPrefs(registry);
system_media_permissions::RegisterSystemMediaPermissionStatesPrefs(registry);
#endif
#if defined(OS_WIN) || defined(OS_MACOSX)
OSCrypt::RegisterLocalPrefs(registry);
#endif
#if defined(OS_WIN)
registry->RegisterBooleanPref(prefs::kRendererCodeIntegrityEnabled, true);
component_updater::RegisterPrefsForSwReporter(registry);
......
......@@ -257,10 +257,14 @@ void InProcessBrowserTest::SetUp() {
SetScreenInstance();
// Always use a mocked password storage if OS encryption is used (which is
// when anything sensitive gets stored, including Cookies). Without this on
// Mac, many tests will hang waiting for a user to approve KeyChain access.
// Use a mocked password storage if OS encryption is used that might block or
// prompt the user (which is when anything sensitive gets stored, including
// Cookies). Without this on Mac and Linux, many tests will hang waiting for a
// user to approve KeyChain/kwallet access. On Windows this is not needed as
// OS APIs never block.
#if defined(OS_MACOSX) || defined(OS_LINUX)
OSCryptMocker::SetUp();
#endif
#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
CaptivePortalService::set_state_for_testing(
......@@ -322,7 +326,9 @@ void InProcessBrowserTest::TearDown() {
->Skipped())
return;
BrowserTestBase::TearDown();
#if defined(OS_MACOSX) || defined(OS_LINUX)
OSCryptMocker::TearDown();
#endif
ChromeContentBrowserClient::SetDefaultQuotaSettingsForTesting(nullptr);
#if defined(OS_CHROMEOS)
......
......@@ -13,6 +13,7 @@
#include "components/autofill/core/browser/data_model/credit_card.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/os_crypt/os_crypt.h"
#include "components/os_crypt/os_crypt_mocker.h"
#include "testing/gtest/include/gtest/gtest.h"
#include <windows.h>
......@@ -132,6 +133,7 @@ AutofillIeToolbarImportTest::AutofillIeToolbarImportTest() {
}
void AutofillIeToolbarImportTest::SetUp() {
OSCryptMocker::SetUp();
temp_hkcu_hive_key_.Create(HKEY_CURRENT_USER,
kUnitTestUserOverrideSubKey,
KEY_ALL_ACCESS);
......@@ -145,6 +147,7 @@ void AutofillIeToolbarImportTest::TearDown() {
temp_hkcu_hive_key_.Close();
RegKey key(HKEY_CURRENT_USER, kUnitTestRegistrySubKey, KEY_ALL_ACCESS);
key.DeleteKey(L"");
OSCryptMocker::TearDown();
}
TEST_F(AutofillIeToolbarImportTest, TestAutofillImport) {
......
......@@ -373,7 +373,6 @@ void AutofillMetricsTest::TearDown() {
autofill_manager_.reset();
autofill_driver_.reset();
personal_data_.reset();
test::ReenableSystemServices();
test_ukm_recorder_->Purge();
}
......
......@@ -30,6 +30,7 @@
#include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h"
#include "components/autofill/core/common/autofill_clock.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/os_crypt/os_crypt_mocker.h"
#include "components/webdata/common/web_data_results.h"
#include "components/webdata/common/web_data_service_base.h"
#include "components/webdata/common/web_data_service_consumer.h"
......@@ -96,6 +97,8 @@ class WebDataServiceTest : public testing::Test {
protected:
void SetUp() override {
base::FilePath path(WebDatabase::kInMemoryPath);
// OSCrypt is used for encryption of credit card data in this test.
OSCryptMocker::SetUp();
// TODO(pkasting): http://crbug.com/740773 This should likely be sequenced,
// not single-threaded; it's also possible the various uses of this below
......@@ -119,6 +122,7 @@ class WebDataServiceTest : public testing::Test {
wds_ = nullptr;
wdbs_ = nullptr;
task_environment_.RunUntilIdle();
OSCryptMocker::TearDown();
}
base::test::TaskEnvironment task_environment_;
......
......@@ -19,7 +19,7 @@
class KeyStorageLinux;
#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS)
#if defined(OS_MACOSX) && !defined(OS_IOS)
#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
class PrefRegistrySimple;
class PrefService;
#endif
......@@ -73,15 +73,16 @@ class OSCrypt {
const std::string& ciphertext,
std::string* plaintext);
#if defined(OS_MACOSX) && !defined(OS_IOS)
#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
// Registers preferences used by OSCrypt.
static COMPONENT_EXPORT(OS_CRYPT) void RegisterLocalPrefs(
PrefRegistrySimple* registry);
// Initialises OSCrypt.
// This method should be called on the main UI thread before any calls to
// encryption or decryption.
static COMPONENT_EXPORT(OS_CRYPT) void Init(PrefService* local_state);
// encryption or decryption. Returns |true| if os_crypt successfully
// initialized.
static COMPONENT_EXPORT(OS_CRYPT) bool Init(PrefService* local_state);
#endif
#if defined(OS_MACOSX)
......@@ -96,7 +97,9 @@ class OSCrypt {
// mock Keychain. Use OSCryptMocker, instead of calling this method directly.
static COMPONENT_EXPORT(OS_CRYPT) void UseLockedMockKeychainForTesting(
bool use_locked);
#endif
#if defined(OS_WIN) || defined(OS_MACOSX)
// Get the raw encryption key to be used for all AES encryption. Returns an
// empty string in the case password access is denied or key generation error
// occurs. This method is thread-safe.
......@@ -108,6 +111,22 @@ class OSCrypt {
const std::string& key);
#endif
#if defined(OS_WIN)
// For unit testing purposes we instruct the Encryptor to use a mock Key. The
// default is to use the real Key bound to profile. Use OSCryptMocker, instead
// of calling this method directly.
static COMPONENT_EXPORT(OS_CRYPT) void UseMockKeyForTesting(bool use_mock);
// For unit testing purposes, encrypt data using the older DPAPI method rather
// than using a session key.
static COMPONENT_EXPORT(OS_CRYPT) void SetLegacyEncryptionForTesting(
bool legacy);
// For unit testing purposes, reset the state of OSCrypt so a new key can be
// loaded via Init() or SetRawEncryptionkey().
static COMPONENT_EXPORT(OS_CRYPT) void ResetStateForTesting();
#endif
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(OSCrypt);
};
......
......@@ -239,10 +239,11 @@ void OSCrypt::RegisterLocalPrefs(PrefRegistrySimple* registry) {
registry->RegisterBooleanPref(os_crypt::prefs::kKeyCreated, false);
}
void OSCrypt::Init(PrefService* local_state) {
bool OSCrypt::Init(PrefService* local_state) {
base::AutoLock auto_lock(g_lock.Get());
g_key_creation_util = new os_crypt::EncryptionKeyCreationUtilMac(
local_state, base::ThreadTaskRunnerHandle::Get());
return true;
}
#endif
......
......@@ -16,6 +16,8 @@ void OSCryptMocker::SetUp() {
OSCrypt::UseMockKeychainForTesting(true);
#elif defined(USE_LIBSECRET) || defined(USE_KEYRING) || defined(USE_KWALLET)
OSCryptMockerLinux::SetUp();
#elif defined(OS_WIN)
OSCrypt::UseMockKeyForTesting(true);
#endif
}
......@@ -26,11 +28,25 @@ void OSCryptMocker::SetBackendLocked(bool locked) {
}
#endif
#if defined(OS_WIN)
// static
void OSCryptMocker::SetLegacyEncryption(bool legacy) {
OSCrypt::SetLegacyEncryptionForTesting(legacy);
}
void OSCryptMocker::ResetState() {
OSCrypt::ResetStateForTesting();
}
#endif
// static
void OSCryptMocker::TearDown() {
#if defined(OS_MACOSX)
OSCrypt::UseMockKeychainForTesting(false);
#elif defined(USE_LIBSECRET) || defined(USE_KEYRING) || defined(USE_KWALLET)
OSCryptMockerLinux::TearDown();
#elif defined(OS_WIN)
OSCrypt::UseMockKeyForTesting(false);
#endif
}
......@@ -20,6 +20,14 @@ class OSCryptMocker {
static void SetBackendLocked(bool locked);
#endif
#if defined(OS_WIN)
// Store data using the older DPAPI interface rather than session key.
static void SetLegacyEncryption(bool legacy);
// Reset OSCrypt so it can be initialized again with a new profile/key.
static void ResetState();
#endif
// Restore OSCrypt to its real behaviour.
static void TearDown();
......
......@@ -22,6 +22,12 @@
#include "components/os_crypt/os_crypt_mocker_linux.h"
#endif
#if defined(OS_WIN)
#include "base/strings/string_util.h"
#include "components/prefs/testing_pref_service.h"
#include "crypto/random.h"
#endif
namespace {
class OSCryptTest : public testing::Test {
......@@ -186,4 +192,115 @@ TEST_F(OSCryptConcurrencyTest, ConcurrentInitialization) {
}
}
#if defined(OS_WIN)
class OSCryptTestWin : public testing::Test {
public:
OSCryptTestWin() {}
~OSCryptTestWin() override { OSCryptMocker::ResetState(); }
private:
DISALLOW_COPY_AND_ASSIGN(OSCryptTestWin);
};
// This test verifies that the header of the data returned from CryptProtectData
// never collides with the kEncryptionVersionPrefix ("v10") used in
// os_crypt_win.cc. If this ever happened, we would not be able to distinguish
// between data encrypted using the legacy DPAPI interface, and data that's been
// encrypted with the new session key.
// If this test ever breaks do not ignore it as it might result in data loss for
// users.
TEST_F(OSCryptTestWin, DPAPIHeader) {
std::string plaintext;
std::string ciphertext;
OSCryptMocker::SetLegacyEncryption(true);
crypto::RandBytes(base::WriteInto(&plaintext, 11), 10);
ASSERT_TRUE(OSCrypt::EncryptString(plaintext, &ciphertext));
using std::string_literals::operator""s;
const std::string expected_header("\x01\x00\x00\x00"s);
ASSERT_EQ(4U, expected_header.length());
ASSERT_TRUE(ciphertext.length() >= expected_header.length());
std::string dpapi_header = ciphertext.substr(0, expected_header.length());
EXPECT_EQ(expected_header, dpapi_header);
}
TEST_F(OSCryptTestWin, ReadOldData) {
OSCryptMocker::SetLegacyEncryption(true);
std::string plaintext = "secrets";
std::string legacy_ciphertext;
ASSERT_TRUE(OSCrypt::EncryptString(plaintext, &legacy_ciphertext));
OSCryptMocker::SetLegacyEncryption(false);
TestingPrefServiceSimple pref_service_simple;
OSCrypt::RegisterLocalPrefs(pref_service_simple.registry());
ASSERT_TRUE(OSCrypt::Init(&pref_service_simple));
std::string decrypted;
// Should be able to decrypt data encrypted with DPAPI.
ASSERT_TRUE(OSCrypt::DecryptString(legacy_ciphertext, &decrypted));
EXPECT_EQ(plaintext, decrypted);
// Should now encrypt same plaintext to get different ciphertext.
std::string new_ciphertext;
ASSERT_TRUE(OSCrypt::EncryptString(plaintext, &new_ciphertext));
// Should be different from DPAPI ciphertext.
EXPECT_NE(legacy_ciphertext, new_ciphertext);
// Decrypt new ciphertext to give original string.
ASSERT_TRUE(OSCrypt::DecryptString(new_ciphertext, &decrypted));
EXPECT_EQ(plaintext, decrypted);
}
TEST_F(OSCryptTestWin, PrefsKeyTest) {
TestingPrefServiceSimple first_prefs;
OSCrypt::RegisterLocalPrefs(first_prefs.registry());
// Verify new random key can be generated.
ASSERT_TRUE(OSCrypt::Init(&first_prefs));
std::string first_key = OSCrypt::GetRawEncryptionKey();
std::string plaintext = "secrets";
std::string ciphertext;
ASSERT_TRUE(OSCrypt::EncryptString(plaintext, &ciphertext));
TestingPrefServiceSimple second_prefs;
OSCrypt::RegisterLocalPrefs(second_prefs.registry());
OSCryptMocker::ResetState();
ASSERT_TRUE(OSCrypt::Init(&second_prefs));
std::string second_key = OSCrypt::GetRawEncryptionKey();
// Keys should be different since they are random.
EXPECT_NE(first_key, second_key);
std::string decrypted;
// Cannot decrypt with the wrong key.
EXPECT_FALSE(OSCrypt::DecryptString(ciphertext, &decrypted));
// Initialize OSCrypt from existing key.
OSCryptMocker::ResetState();
OSCrypt::SetRawEncryptionKey(first_key);
// Verify decryption works with first key.
ASSERT_TRUE(OSCrypt::DecryptString(ciphertext, &decrypted));
EXPECT_EQ(plaintext, decrypted);
// Initialize OSCrypt from existing prefs.
OSCryptMocker::ResetState();
ASSERT_TRUE(OSCrypt::Init(&first_prefs));
// Verify decryption works with key from first prefs.
ASSERT_TRUE(OSCrypt::DecryptString(ciphertext, &decrypted));
EXPECT_EQ(plaintext, decrypted);
}
#endif // defined(OS_WIN)
} // namespace
......@@ -6,25 +6,56 @@
#include <windows.h>
#include "base/base64.h"
#include "base/no_destructor.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/wincrypt_shim.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "crypto/aead.h"
#include "crypto/hkdf.h"
#include "crypto/random.h"
bool OSCrypt::EncryptString16(const base::string16& plaintext,
std::string* ciphertext) {
return EncryptString(base::UTF16ToUTF8(plaintext), ciphertext);
}
namespace {
bool OSCrypt::DecryptString16(const std::string& ciphertext,
base::string16* plaintext) {
std::string utf8;
if (!DecryptString(ciphertext, &utf8))
return false;
// Contains base64 random key encrypted with DPAPI.
const char kOsCryptEncryptedKeyPrefName[] = "os_crypt.encrypted_key";
*plaintext = base::UTF8ToUTF16(utf8);
return true;
// AEAD key length in bytes.
const size_t kKeyLength = 256 / 8;
// AEAD nonce length in bytes.
const size_t kNonceLength = 96 / 8;
// Version prefix for data encrypted with profile bound key.
const char kEncryptionVersionPrefix[] = "v10";
// Key prefix for a key encrypted with DPAPI.
const char kDPAPIKeyPrefix[] = "DPAPI";
// Use mock key instead of a real encryption key. Used for testing.
bool g_use_mock_key = false;
// Store data using the legacy (DPAPI) method rather than session key.
bool g_use_legacy = false;
// These two keys must have no destructors to allow OSCrypt calls to function
// correctly during shutdown.
// Encryption Key. Set either by calling Init() or SetRawEncryptionKey().
std::string& GetEncryptionKeyFactory() {
static base::NoDestructor<std::string> encryption_key;
return *encryption_key;
}
bool OSCrypt::EncryptString(const std::string& plaintext,
// Mock Encryption Key. Only set and used if g_use_mock_key is true.
std::string& GetMockEncryptionKeyFactory() {
static base::NoDestructor<std::string> mock_encryption_key;
return *mock_encryption_key;
}
bool EncryptStringWithDPAPI(const std::string& plaintext,
std::string* ciphertext) {
DATA_BLOB input;
input.pbData = const_cast<BYTE*>(
......@@ -47,7 +78,7 @@ bool OSCrypt::EncryptString(const std::string& plaintext,
return true;
}
bool OSCrypt::DecryptString(const std::string& ciphertext,
bool DecryptStringWithDPAPI(const std::string& ciphertext,
std::string* plaintext) {
DATA_BLOB input;
input.pbData = const_cast<BYTE*>(
......@@ -66,3 +97,162 @@ bool OSCrypt::DecryptString(const std::string& ciphertext,
LocalFree(output.pbData);
return true;
}
const std::string& GetEncryptionKeyInternal() {
if (g_use_mock_key) {
if (GetMockEncryptionKeyFactory().empty())
GetMockEncryptionKeyFactory().assign(
crypto::HkdfSha256("peanuts", "salt", "info", kKeyLength));
DCHECK(!GetMockEncryptionKeyFactory().empty())
<< "Failed to initialize mock key.";
return GetMockEncryptionKeyFactory();
}
DCHECK(!GetEncryptionKeyFactory().empty()) << "No key.";
return GetEncryptionKeyFactory();
}
} // 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;
if (!DecryptString(ciphertext, &utf8))
return false;
*plaintext = base::UTF8ToUTF16(utf8);
return true;
}
// static
bool OSCrypt::EncryptString(const std::string& plaintext,
std::string* ciphertext) {
if (g_use_legacy)
return EncryptStringWithDPAPI(plaintext, ciphertext);
crypto::Aead aead(crypto::Aead::AES_256_GCM);
auto key = GetEncryptionKeyInternal();
aead.Init(&key);
// Note: can only check these once AEAD is initialized.
DCHECK_EQ(kKeyLength, aead.KeyLength());
DCHECK_EQ(kNonceLength, aead.NonceLength());
std::string nonce;
crypto::RandBytes(base::WriteInto(&nonce, kNonceLength + 1), kNonceLength);
if (!aead.Seal(plaintext, nonce, std::string(), ciphertext))
return false;
ciphertext->insert(0, nonce);
ciphertext->insert(0, kEncryptionVersionPrefix);
return true;
}
// static
bool OSCrypt::DecryptString(const std::string& ciphertext,
std::string* plaintext) {
if (!base::StartsWith(ciphertext, kEncryptionVersionPrefix,
base::CompareCase::SENSITIVE))
return DecryptStringWithDPAPI(ciphertext, plaintext);
crypto::Aead aead(crypto::Aead::AES_256_GCM);
auto key = GetEncryptionKeyInternal();
aead.Init(&key);
// Obtain the nonce.
std::string nonce =
ciphertext.substr(sizeof(kEncryptionVersionPrefix) - 1, kNonceLength);
// Strip off the versioning prefix before decrypting.
std::string raw_ciphertext =
ciphertext.substr(kNonceLength + (sizeof(kEncryptionVersionPrefix) - 1));
return aead.Open(raw_ciphertext, nonce, std::string(), plaintext);
}
// static
void OSCrypt::RegisterLocalPrefs(PrefRegistrySimple* registry) {
registry->RegisterStringPref(kOsCryptEncryptedKeyPrefName, "");
}
// static
bool OSCrypt::Init(PrefService* local_state) {
DCHECK(GetEncryptionKeyFactory().empty()) << "Key already exists.";
// Try and pull the key from local state.
if (local_state->HasPrefPath(kOsCryptEncryptedKeyPrefName)) {
std::string base64_encrypted_key =
local_state->GetString(kOsCryptEncryptedKeyPrefName);
std::string encrypted_key_with_header;
base::Base64Decode(base64_encrypted_key, &encrypted_key_with_header);
if (!base::StartsWith(encrypted_key_with_header, kDPAPIKeyPrefix,
base::CompareCase::SENSITIVE)) {
NOTREACHED() << "Invalid key format.";
return false;
}
std::string encrypted_key =
encrypted_key_with_header.substr(sizeof(kDPAPIKeyPrefix) - 1);
std::string key;
if (!DecryptStringWithDPAPI(encrypted_key, &key))
return false;
GetEncryptionKeyFactory().assign(key);
return true;
}
// Otherwise, generate a key.
std::string key;
crypto::RandBytes(base::WriteInto(&key, kKeyLength + 1), kKeyLength);
std::string encrypted_key;
if (!EncryptStringWithDPAPI(key, &encrypted_key))
return false;
// Add header indicating this key is encrypted with DPAPI.
encrypted_key.insert(0, kDPAPIKeyPrefix);
std::string base64_key;
base::Base64Encode(encrypted_key, &base64_key);
local_state->SetString(kOsCryptEncryptedKeyPrefName, base64_key);
GetEncryptionKeyFactory().assign(key);
return true;
}
// static
void OSCrypt::SetRawEncryptionKey(const std::string& raw_key) {
DCHECK(!g_use_mock_key) << "Mock key in use.";
DCHECK(!raw_key.empty()) << "Bad key.";
DCHECK(GetEncryptionKeyFactory().empty()) << "Key already set.";
GetEncryptionKeyFactory().assign(raw_key);
}
// static
std::string OSCrypt::GetRawEncryptionKey() {
return GetEncryptionKeyInternal();
}
// static
void OSCrypt::UseMockKeyForTesting(bool use_mock) {
g_use_mock_key = use_mock;
}
// static
void OSCrypt::SetLegacyEncryptionForTesting(bool legacy) {
g_use_legacy = legacy;
}
// static
void OSCrypt::ResetStateForTesting() {
g_use_legacy = false;
g_use_mock_key = false;
GetEncryptionKeyFactory().clear();
GetMockEncryptionKeyFactory().clear();
}
......@@ -602,11 +602,11 @@ void NetworkService::SetCryptConfig(mojom::CryptConfigPtr crypt_config) {
}
#endif
#if defined(OS_MACOSX) && !defined(OS_IOS)
#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
void NetworkService::SetEncryptionKey(const std::string& encryption_key) {
OSCrypt::SetRawEncryptionKey(encryption_key);
}
#endif // OS_MACOSX
#endif
void NetworkService::AddCorbExceptionForPlugin(uint32_t process_id) {
DCHECK_NE(mojom::kBrowserProcessId, process_id);
......
......@@ -146,7 +146,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkService
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
void SetCryptConfig(mojom::CryptConfigPtr crypt_config) override;
#endif
#if defined(OS_MACOSX) && !defined(OS_IOS)
#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
void SetEncryptionKey(const std::string& encryption_key) override;
#endif
void AddCorbExceptionForPlugin(uint32_t process_id) override;
......
......@@ -294,6 +294,10 @@ interface NetworkService {
[EnableIf=is_mac]
SetEncryptionKey(string encryption_key);
// Send the encryption key to the network service to use for AES encryption.
[EnableIf=is_win]
SetEncryptionKey(string encryption_key);
// Notifies CORB (Cross-Origin Read Blocking) that |process_id| is proxying
// requests on behalf of a universal-access plugin and therefore CORB should
// stop blocking requests marked as ResourceType::kPluginResource.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment