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
diff --git a/Android.mk b/Android.mk
index a54cd09..c245939 100644
--- a/Android.mk
+++ b/Android.mk
@@ -48,6 +48,14 @@
 	libweave \
 	libwebserv \
 
+ifdef BRILLO
+
+buffetSharedLibraries += \
+	libkeymaster_messages \
+	libkeystore_binder \
+
+endif
+
 # buffet-common
 # ========================================================
 include $(CLEAR_VARS)
@@ -80,6 +88,13 @@
 	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_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 @@
 
 }  // 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 @@
 }
 
 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 @@
     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 @@
   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 @@
   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_