aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Vakulenko <avakulenko@google.com>2015-10-08 07:34:23 -0700
committerAlex Vakulenko <avakulenko@google.com>2015-10-08 07:44:57 -0700
commitdf38164c0c7bfef18b68d3ba5be9a516bf6198de (patch)
tree7f7e0d0546b87bbf20991c2f3b93eeb6d7bea529
parent2915a7b9a45821a7530d2fea8a982bc1b6efc7d3 (diff)
downloadweaved-df38164c0c7bfef18b68d3ba5be9a516bf6198de.tar.gz
Removing mnc-brillo-dev specific changes to weaved
Moved recent changes to weaved from Brillo branch to AOSP and used conditional compilation to compile Brillo-specific code on Brillo only. This eliminates differences in source files for the branch and future code merge issues. Change-Id: I355a1022cb0d31ea1ab7e0c476824ebbad1af43c
-rw-r--r--Android.mk16
-rw-r--r--buffet/buffet_config.cc59
-rw-r--r--buffet/buffet_config.h31
-rw-r--r--buffet/buffet_config_unittest.cc81
-rw-r--r--buffet/encryptor.h53
-rw-r--r--buffet/fake_encryptor.cc41
-rw-r--r--buffet/keystore_encryptor.cc51
-rw-r--r--buffet/keystore_encryptor.h46
8 files changed, 375 insertions, 3 deletions
diff --git a/Android.mk b/Android.mk
index a54cd09..c245939 100644
--- a/Android.mk
+++ b/Android.mk
@@ -48,6 +48,14 @@ buffetSharedLibraries := \
libweave \
libwebserv \
+ifdef BRILLO
+
+buffetSharedLibraries += \
+ libkeymaster_messages \
+ libkeystore_binder \
+
+endif
+
# buffet-common
# ========================================================
include $(CLEAR_VARS)
@@ -80,6 +88,13 @@ LOCAL_SRC_FILES := \
buffet/dbus_bindings/com.android.Weave.Command.dbus-xml \
buffet/dbus_bindings/com.android.Weave.Manager.dbus-xml \
+ifdef BRILLO
+LOCAL_SRC_FILES += buffet/keystore_encryptor.cc
+else
+LOCAL_SRC_FILES += buffet/fake_encryptor.cc
+endif
+
+
include $(BUILD_STATIC_LIBRARY)
# buffet
@@ -146,6 +161,7 @@ LOCAL_RTTI_FLAG := -frtti
LOCAL_CLANG := true
LOCAL_SRC_FILES := \
+ buffet/buffet_config_unittest.cc \
buffet/buffet_testrunner.cc \
buffet/dbus_command_proxy_unittest.cc \
buffet/dbus_conversion_unittest.cc \
diff --git a/buffet/buffet_config.cc b/buffet/buffet_config.cc
index fde6f0e..c375e1f 100644
--- a/buffet/buffet_config.cc
+++ b/buffet/buffet_config.cc
@@ -18,6 +18,24 @@
namespace buffet {
+namespace {
+
+const char kErrorDomain[] = "buffet";
+const char kFileReadError[] = "file_read_error";
+
+class DefaultFileIO : public BuffetConfig::FileIO {
+ public:
+ bool ReadFile(const base::FilePath& path, std::string* content) override {
+ return base::ReadFileToString(path, content);
+ }
+ bool WriteFile(const base::FilePath& path,
+ const std::string& content) override {
+ return base::ImportantFileWriter::WriteFileAtomically(path, content);
+ }
+};
+
+} // namespace
+
namespace config_keys {
const char kClientId[] = "client_id";
@@ -40,7 +58,12 @@ const char kPairingModes[] = "pairing_modes";
} // namespace config_keys
-BuffetConfig::BuffetConfig(const Options& options) : options_(options) {}
+BuffetConfig::BuffetConfig(const Options& options)
+ : options_(options),
+ default_encryptor_(Encryptor::CreateDefaultEncryptor()),
+ encryptor_(default_encryptor_.get()),
+ default_file_io_(new DefaultFileIO),
+ file_io_(default_file_io_.get()) {}
bool BuffetConfig::LoadDefaults(weave::Settings* settings) {
// Keep this hardcoded default for sometime. This previously was set by
@@ -132,13 +155,43 @@ bool BuffetConfig::LoadDefaults(const chromeos::KeyValueStore& store,
}
std::string BuffetConfig::LoadSettings() {
+ std::string settings_blob;
+ if (!file_io_->ReadFile(options_.settings, &settings_blob)) {
+ LOG(WARNING) << "Failed to read settings, proceeding with empty settings.";
+ return std::string();
+ }
std::string json_string;
- base::ReadFileToString(options_.settings, &json_string);
+ if (!encryptor_->DecryptWithAuthentication(settings_blob, &json_string)) {
+ LOG(WARNING)
+ << "Failed to decrypt settings, proceeding with empty settings.";
+ SaveSettings(std::string());
+ return std::string();
+ }
return json_string;
}
void BuffetConfig::SaveSettings(const std::string& settings) {
- base::ImportantFileWriter::WriteFileAtomically(options_.settings, settings);
+ std::string encrypted_settings;
+ if (!encryptor_->EncryptWithAuthentication(settings, &encrypted_settings)) {
+ LOG(ERROR) << "Failed to encrypt settings, writing empty settings.";
+ encrypted_settings.clear();
+ }
+ if (!file_io_->WriteFile(options_.settings, encrypted_settings)) {
+ LOG(ERROR) << "Failed to write settings.";
+ }
+}
+
+bool BuffetConfig::LoadFile(const base::FilePath& file_path,
+ std::string* data,
+ chromeos::ErrorPtr* error) {
+ if (!file_io_->ReadFile(file_path, data)) {
+ chromeos::errors::system::AddSystemError(error, FROM_HERE, errno);
+ chromeos::Error::AddToPrintf(error, FROM_HERE, kErrorDomain, kFileReadError,
+ "Failed to read file '%s'",
+ file_path.value().c_str());
+ return false;
+ }
+ return true;
}
} // namespace buffet
diff --git a/buffet/buffet_config.h b/buffet/buffet_config.h
index a286bf8..3db6de8 100644
--- a/buffet/buffet_config.h
+++ b/buffet/buffet_config.h
@@ -12,9 +12,12 @@
#include <base/callback.h>
#include <base/files/file_path.h>
+#include <chromeos/errors/error.h>
#include <chromeos/key_value_store.h>
#include <weave/provider/config_store.h>
+#include "buffet/encryptor.h"
+
namespace buffet {
class StorageInterface;
@@ -39,6 +42,14 @@ class BuffetConfig final : public weave::provider::ConfigStore {
std::string test_privet_ssid;
};
+ // An IO abstraction to enable testing without using real files.
+ class FileIO {
+ public:
+ virtual bool ReadFile(const base::FilePath& path, std::string* content) = 0;
+ virtual bool WriteFile(const base::FilePath& path,
+ const std::string& content) = 0;
+ };
+
~BuffetConfig() override = default;
explicit BuffetConfig(const Options& options);
@@ -51,8 +62,28 @@ class BuffetConfig final : public weave::provider::ConfigStore {
bool LoadDefaults(const chromeos::KeyValueStore& store,
weave::Settings* settings);
+ // Allows injection of a non-default |encryptor| for testing. The caller
+ // retains ownership of the pointer.
+ void SetEncryptor(Encryptor* encryptor) {
+ encryptor_ = encryptor;
+ }
+
+ // Allows injection of non-default |file_io| for testing. The caller retains
+ // ownership of the pointer.
+ void SetFileIO(FileIO* file_io) {
+ file_io_ = file_io;
+ }
+
private:
+ bool LoadFile(const base::FilePath& file_path,
+ std::string* data,
+ chromeos::ErrorPtr* error);
+
Options options_;
+ std::unique_ptr<Encryptor> default_encryptor_;
+ Encryptor* encryptor_{nullptr};
+ std::unique_ptr<FileIO> default_file_io_;
+ FileIO* file_io_{nullptr};
DISALLOW_COPY_AND_ASSIGN(BuffetConfig);
};
diff --git a/buffet/buffet_config_unittest.cc b/buffet/buffet_config_unittest.cc
index 58c2117..795d172 100644
--- a/buffet/buffet_config_unittest.cc
+++ b/buffet/buffet_config_unittest.cc
@@ -7,6 +7,7 @@
#include <set>
#include <base/bind.h>
+#include <chromeos/data_encoding.h>
#include <gtest/gtest.h>
namespace buffet {
@@ -66,4 +67,84 @@ TEST(BuffetConfigTest, LoadConfig) {
EXPECT_FALSE(settings.local_discovery_enabled);
}
+class BuffetConfigTestWithFakes : public testing::Test,
+ public BuffetConfig::FileIO,
+ public Encryptor {
+ public:
+ void SetUp() {
+ BuffetConfig::Options config_options;
+ config_options.settings = base::FilePath{"settings_file"};
+ config_.reset(new BuffetConfig{config_options});
+ config_->SetEncryptor(this);
+ config_->SetFileIO(this);
+ };
+
+ // buffet::Encryptor methods.
+ bool EncryptWithAuthentication(const std::string& plaintext,
+ std::string* ciphertext) override {
+ *ciphertext = chromeos::data_encoding::Base64Encode(plaintext);
+ return encryptor_result_;
+ };
+ bool DecryptWithAuthentication(const std::string& ciphertext,
+ std::string* plaintext) override {
+ return encryptor_result_ &&
+ chromeos::data_encoding::Base64Decode(ciphertext, plaintext);
+ };
+
+ // buffet::BuffetConfig::FileIO methods.
+ bool ReadFile(const base::FilePath& path, std::string* content) override {
+ if (fake_file_content_.count(path.value()) == 0) {
+ return false;
+ }
+ *content = fake_file_content_[path.value()];
+ return io_result_;
+ };
+ bool WriteFile(const base::FilePath& path,
+ const std::string& content) override {
+ if (io_result_) {
+ fake_file_content_[path.value()] = content;
+ }
+ return io_result_;
+ };
+
+ protected:
+ std::map<std::string, std::string> fake_file_content_;
+ bool encryptor_result_ = true;
+ bool io_result_ = true;
+ std::unique_ptr<BuffetConfig> config_;
+};
+
+TEST_F(BuffetConfigTestWithFakes, EncryptionEnabled) {
+ config_->SaveSettings("test");
+ ASSERT_NE("test", fake_file_content_["settings_file"]);
+ ASSERT_EQ("test", config_->LoadSettings());
+}
+
+TEST_F(BuffetConfigTestWithFakes, EncryptionFailure) {
+ config_->SaveSettings("test");
+ ASSERT_FALSE(fake_file_content_["settings_file"].empty());
+ encryptor_result_ = false;
+ config_->SaveSettings("test2");
+ // Encryption fails -> file cleared.
+ ASSERT_TRUE(fake_file_content_["settings_file"].empty());
+}
+
+TEST_F(BuffetConfigTestWithFakes, DecryptionFailure) {
+ config_->SaveSettings("test");
+ ASSERT_FALSE(fake_file_content_["settings_file"].empty());
+ encryptor_result_ = false;
+ // Decryption fails -> empty settings loaded.
+ ASSERT_TRUE(config_->LoadSettings().empty());
+}
+
+TEST_F(BuffetConfigTestWithFakes, SettingsIOFailure) {
+ config_->SaveSettings("test");
+ std::string original = fake_file_content_["settings_file"];
+ ASSERT_FALSE(original.empty());
+ io_result_ = false;
+ ASSERT_TRUE(config_->LoadSettings().empty());
+ config_->SaveSettings("test2");
+ ASSERT_EQ(original, fake_file_content_["settings_file"]);
+}
+
} // namespace buffet
diff --git a/buffet/encryptor.h b/buffet/encryptor.h
new file mode 100644
index 0000000..96f4f71
--- /dev/null
+++ b/buffet/encryptor.h
@@ -0,0 +1,53 @@
+// Copyright 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BUFFET_ENCRYPTOR_H_
+#define BUFFET_ENCRYPTOR_H_
+
+#include <memory>
+#include <string>
+
+#include <base/macros.h>
+
+namespace buffet {
+
+// An abstract class to perform authenticated encryption.
+class Encryptor {
+ public:
+ Encryptor() = default;
+ virtual ~Encryptor() = default;
+
+ // Encrypts and authenticates the given |plaintext| and emits the
+ // |ciphertext|. Returns true on success.
+ virtual bool EncryptWithAuthentication(const std::string& plaintext,
+ std::string* ciphertext) = 0;
+
+ // Decrypts and authenticates the given |ciphertext| and emits the
+ // |plaintext|. Returns true on success.
+ virtual bool DecryptWithAuthentication(const std::string& ciphertext,
+ std::string* plaintext) = 0;
+
+ // A factory method to be exported by the default Encryptor implementation
+ // for a given platform. Like a constructor, this method should not perform
+ // any significant initialization work. The caller assumes ownership of the
+ // pointer.
+ static std::unique_ptr<Encryptor> CreateDefaultEncryptor();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Encryptor);
+};
+
+} // namespace buffet
+
+#endif // BUFFET_ENCRYPTOR_H_
diff --git a/buffet/fake_encryptor.cc b/buffet/fake_encryptor.cc
new file mode 100644
index 0000000..b82b9f0
--- /dev/null
+++ b/buffet/fake_encryptor.cc
@@ -0,0 +1,41 @@
+// Copyright 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "buffet/encryptor.h"
+
+#include <memory>
+
+#include <chromeos/data_encoding.h>
+
+namespace buffet {
+
+class FakeEncryptor : public Encryptor {
+ public:
+ bool EncryptWithAuthentication(const std::string& plaintext,
+ std::string* ciphertext) override {
+ *ciphertext = chromeos::data_encoding::Base64Encode(plaintext);
+ return true;
+ }
+
+ bool DecryptWithAuthentication(const std::string& ciphertext,
+ std::string* plaintext) override {
+ return chromeos::data_encoding::Base64Decode(ciphertext, plaintext);
+ }
+};
+
+std::unique_ptr<Encryptor> Encryptor::CreateDefaultEncryptor() {
+ return std::unique_ptr<Encryptor>{new FakeEncryptor};
+}
+
+} // namespace buffet
diff --git a/buffet/keystore_encryptor.cc b/buffet/keystore_encryptor.cc
new file mode 100644
index 0000000..e4a5c82
--- /dev/null
+++ b/buffet/keystore_encryptor.cc
@@ -0,0 +1,51 @@
+// Copyright 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "buffet/keystore_encryptor.h"
+
+#include <memory>
+
+#include <keystore/keystore_client_impl.h>
+
+namespace {
+
+const char kBuffetKeyName[] = "buffet_config_b4f594c3";
+
+} // namespace
+
+namespace buffet {
+
+std::unique_ptr<Encryptor> Encryptor::CreateDefaultEncryptor() {
+ return std::unique_ptr<Encryptor>(
+ new KeystoreEncryptor(std::unique_ptr<keystore::KeystoreClient>(
+ new keystore::KeystoreClientImpl)));
+}
+
+KeystoreEncryptor::KeystoreEncryptor(
+ std::unique_ptr<keystore::KeystoreClient> keystore)
+ : keystore_(std::move(keystore)) {}
+
+bool KeystoreEncryptor::EncryptWithAuthentication(const std::string& plaintext,
+ std::string* ciphertext) {
+ return keystore_->encryptWithAuthentication(kBuffetKeyName, plaintext,
+ ciphertext);
+}
+
+bool KeystoreEncryptor::DecryptWithAuthentication(const std::string& ciphertext,
+ std::string* plaintext) {
+ return keystore_->decryptWithAuthentication(kBuffetKeyName, ciphertext,
+ plaintext);
+}
+
+} // namespace buffet
diff --git a/buffet/keystore_encryptor.h b/buffet/keystore_encryptor.h
new file mode 100644
index 0000000..ec2294b
--- /dev/null
+++ b/buffet/keystore_encryptor.h
@@ -0,0 +1,46 @@
+// Copyright 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BUFFET_KEYSTORE_ENCRYPTOR_H_
+#define BUFFET_KEYSTORE_ENCRYPTOR_H_
+
+#include "buffet/encryptor.h"
+
+#include <memory>
+
+#include <keystore/keystore_client.h>
+
+namespace buffet {
+
+// An Encryptor implementation backed by Brillo Keystore. This class is intended
+// to be the default encryptor on platforms that support it. An implementation
+// of Encryptor::CreateDefaultEncryptor is provided for this class.
+class KeystoreEncryptor : public Encryptor {
+ public:
+ explicit KeystoreEncryptor(
+ std::unique_ptr<keystore::KeystoreClient> keystore);
+ ~KeystoreEncryptor() override = default;
+
+ bool EncryptWithAuthentication(const std::string& plaintext,
+ std::string* ciphertext) override;
+ bool DecryptWithAuthentication(const std::string& ciphertext,
+ std::string* plaintext) override;
+
+ private:
+ std::unique_ptr<keystore::KeystoreClient> keystore_;
+};
+
+} // namespace buffet
+
+#endif // BUFFET_KEYSTORE_ENCRYPTOR_H_