Commit 81a309fc authored by Leonid Baraz's avatar Leonid Baraz Committed by Chromium LUCI CQ

Handle signed encryption key file(s).

Writes the key to the file, parses it from the file during
initialization. Encryption is controlled by base::FeatureList;
if encryption is enabled, fail Storage initialization.
Later on we will instead send Upload with no records and
only need_encryption_key flag and reject Enqueue until it is
responded.

Bug: b:170054326
Change-Id: I343b17f9363e11b62e6ab1f69148a7e9e8e0d4c2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586086Reviewed-by: default avatarZach Trudo <zatrudo@google.com>
Commit-Queue: Leonid Baraz <lbaraz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836807}
parent b90bef2d
...@@ -47,8 +47,14 @@ void AddToRecord(base::StringPiece record, ...@@ -47,8 +47,14 @@ void AddToRecord(base::StringPiece record,
} // namespace } // namespace
// static
const char EncryptionModule::kEncryptedReporting[] = "EncryptedReporting"; const char EncryptionModule::kEncryptedReporting[] = "EncryptedReporting";
// static
bool EncryptionModule::is_enabled() {
return base::FeatureList::IsEnabled(kEncryptedReportingFeature);
}
EncryptionModule::EncryptionModule() { EncryptionModule::EncryptionModule() {
auto encryptor_result = Encryptor::Create(); auto encryptor_result = Encryptor::Create();
DCHECK(encryptor_result.ok()); DCHECK(encryptor_result.ok());
...@@ -60,7 +66,7 @@ EncryptionModule::~EncryptionModule() = default; ...@@ -60,7 +66,7 @@ EncryptionModule::~EncryptionModule() = default;
void EncryptionModule::EncryptRecord( void EncryptionModule::EncryptRecord(
base::StringPiece record, base::StringPiece record,
base::OnceCallback<void(StatusOr<EncryptedRecord>)> cb) const { base::OnceCallback<void(StatusOr<EncryptedRecord>)> cb) const {
if (!base::FeatureList::IsEnabled(kEncryptedReportingFeature)) { if (!is_enabled()) {
// Encryptor disabled. // Encryptor disabled.
EncryptedRecord encrypted_record; EncryptedRecord encrypted_record;
encrypted_record.mutable_encrypted_wrapped_record()->assign(record.begin(), encrypted_record.mutable_encrypted_wrapped_record()->assign(record.begin(),
......
...@@ -22,8 +22,8 @@ class EncryptionModule : public base::RefCountedThreadSafe<EncryptionModule> { ...@@ -22,8 +22,8 @@ class EncryptionModule : public base::RefCountedThreadSafe<EncryptionModule> {
// Feature to enable/disable encryption. // Feature to enable/disable encryption.
// By default encryption is disabled, until server can support decryption. // By default encryption is disabled, until server can support decryption.
static const char kEncryptedReporting[]; static const char kEncryptedReporting[];
EncryptionModule();
EncryptionModule();
EncryptionModule(const EncryptionModule& other) = delete; EncryptionModule(const EncryptionModule& other) = delete;
EncryptionModule& operator=(const EncryptionModule& other) = delete; EncryptionModule& operator=(const EncryptionModule& other) = delete;
...@@ -47,6 +47,10 @@ class EncryptionModule : public base::RefCountedThreadSafe<EncryptionModule> { ...@@ -47,6 +47,10 @@ class EncryptionModule : public base::RefCountedThreadSafe<EncryptionModule> {
// or even changing the key is OK at any time. // or even changing the key is OK at any time.
bool has_encryption_key() const; bool has_encryption_key() const;
// Returns 'true' if |kEncryptedReporting| feature is enabled.
// To be removed once encryption becomes mandatory.
static bool is_enabled();
protected: protected:
virtual ~EncryptionModule(); virtual ~EncryptionModule();
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility>
#include "base/callback.h" #include "base/callback.h"
#include "base/containers/flat_map.h" #include "base/containers/flat_map.h"
...@@ -88,6 +89,9 @@ class Storage : public base::RefCountedThreadSafe<Storage> { ...@@ -88,6 +89,9 @@ class Storage : public base::RefCountedThreadSafe<Storage> {
// Private bridge class. // Private bridge class.
class QueueUploaderInterface; class QueueUploaderInterface;
// Private helper class for key upload/download to the file system.
class KeyInStorage;
// Private constructor, to be called by Create factory method only. // Private constructor, to be called by Create factory method only.
// Queues need to be added afterwards. // Queues need to be added afterwards.
Storage(const StorageOptions& options, Storage(const StorageOptions& options,
...@@ -111,6 +115,9 @@ class Storage : public base::RefCountedThreadSafe<Storage> { ...@@ -111,6 +115,9 @@ class Storage : public base::RefCountedThreadSafe<Storage> {
// Encryption module. // Encryption module.
scoped_refptr<EncryptionModule> encryption_module_; scoped_refptr<EncryptionModule> encryption_module_;
// Internal key management module.
std::unique_ptr<KeyInStorage> key_in_storage_;
// Map priority->StorageQueue. // Map priority->StorageQueue.
base::flat_map<Priority, scoped_refptr<StorageQueue>> queues_; base::flat_map<Priority, scoped_refptr<StorageQueue>> queues_;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/containers/flat_set.h" #include "base/containers/flat_set.h"
#include "base/files/file.h"
#include "base/files/file_enumerator.h" #include "base/files/file_enumerator.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
...@@ -152,7 +153,7 @@ Status StorageQueue::Init() { ...@@ -152,7 +153,7 @@ Status StorageQueue::Init() {
return Status( return Status(
error::UNAVAILABLE, error::UNAVAILABLE,
base::StrCat( base::StrCat(
{"Fileset directory '", options_.directory().MaybeAsASCII(), {"Storage queue directory '", options_.directory().MaybeAsASCII(),
"' does not exist, error=", base::File::ErrorToString(error)})); "' does not exist, error=", base::File::ErrorToString(error)}));
} }
// Enumerate data files and scan the last one to determine what sequence // Enumerate data files and scan the last one to determine what sequence
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/strings/strcat.h" #include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "chrome/browser/policy/messaging_layer/encryption/test_encryption_module.h" #include "chrome/browser/policy/messaging_layer/encryption/test_encryption_module.h"
#include "chrome/browser/policy/messaging_layer/storage/storage_configuration.h" #include "chrome/browser/policy/messaging_layer/storage/storage_configuration.h"
...@@ -234,10 +235,14 @@ class MockUploadClient : public Storage::UploaderInterface { ...@@ -234,10 +235,14 @@ class MockUploadClient : public Storage::UploaderInterface {
class StorageTest : public ::testing::TestWithParam<size_t> { class StorageTest : public ::testing::TestWithParam<size_t> {
protected: protected:
void SetUp() override { ASSERT_TRUE(location_.CreateUniqueTempDir()); } void SetUp() override {
ASSERT_TRUE(location_.CreateUniqueTempDir());
// Encryption is disabled.
ASSERT_FALSE(EncryptionModule::is_enabled());
}
void CreateStorageTestOrDie(const StorageOptions& options) { StatusOr<scoped_refptr<Storage>> CreateStorageTest(
ASSERT_FALSE(storage_) << "StorageTest already assigned"; const StorageOptions& options) {
test_encryption_module_ = test_encryption_module_ =
base::MakeRefCounted<test::TestEncryptionModule>(); base::MakeRefCounted<test::TestEncryptionModule>();
TestEvent<StatusOr<scoped_refptr<Storage>>> e; TestEvent<StatusOr<scoped_refptr<Storage>>> e;
...@@ -245,7 +250,13 @@ class StorageTest : public ::testing::TestWithParam<size_t> { ...@@ -245,7 +250,13 @@ class StorageTest : public ::testing::TestWithParam<size_t> {
base::BindRepeating(&StorageTest::BuildMockUploader, base::BindRepeating(&StorageTest::BuildMockUploader,
base::Unretained(this)), base::Unretained(this)),
test_encryption_module_, e.cb()); test_encryption_module_, e.cb());
StatusOr<scoped_refptr<Storage>> storage_result = e.result(); return e.result();
}
void CreateStorageTestOrDie(const StorageOptions& options) {
ASSERT_FALSE(storage_) << "StorageTest already assigned";
StatusOr<scoped_refptr<Storage>> storage_result =
CreateStorageTest(options);
ASSERT_OK(storage_result) ASSERT_OK(storage_result)
<< "Failed to create StorageTest, error=" << storage_result.status(); << "Failed to create StorageTest, error=" << storage_result.status();
storage_ = std::move(storage_result.ValueOrDie()); storage_ = std::move(storage_result.ValueOrDie());
...@@ -288,6 +299,8 @@ class StorageTest : public ::testing::TestWithParam<size_t> { ...@@ -288,6 +299,8 @@ class StorageTest : public ::testing::TestWithParam<size_t> {
ASSERT_OK(c_result) << c_result; ASSERT_OK(c_result) << c_result;
} }
base::test::ScopedFeatureList scoped_feature_list_;
base::ScopedTempDir location_; base::ScopedTempDir location_;
scoped_refptr<test::TestEncryptionModule> test_encryption_module_; scoped_refptr<test::TestEncryptionModule> test_encryption_module_;
scoped_refptr<Storage> storage_; scoped_refptr<Storage> storage_;
...@@ -714,6 +727,18 @@ TEST_P(StorageTest, WriteEncryptFailure) { ...@@ -714,6 +727,18 @@ TEST_P(StorageTest, WriteEncryptFailure) {
EXPECT_EQ(result.error_code(), error::UNKNOWN); EXPECT_EQ(result.error_code(), error::UNKNOWN);
} }
TEST_P(StorageTest, InitFailureWithNoKey) {
// Enable encryption.
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitFromCommandLine(
{EncryptionModule::kEncryptedReporting}, {});
// TODO(b/170054326): When lack of key file is handled correctly,
// rewrite this test accordingly.
StatusOr<scoped_refptr<Storage>> storage_result =
CreateStorageTest(BuildStorageOptions());
ASSERT_FALSE(storage_result.ok()) << "Storage initialized";
}
INSTANTIATE_TEST_SUITE_P(VaryingFileSize, INSTANTIATE_TEST_SUITE_P(VaryingFileSize,
StorageTest, StorageTest,
testing::Values(128 * 1024LL * 1024LL, testing::Values(128 * 1024LL * 1024LL,
......
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