blob: c8441586b8dbf941a628f8817c1b9dd13fd15a2e [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "oobe_config/oobe_config.h"
#include <string>
#include <utility>
#include <base/files/file_path.h>
#include <base/files/scoped_temp_dir.h>
#include <gtest/gtest.h>
#include <libtpmcrypto/tpm_crypto_impl.h>
#include "oobe_config/rollback_constants.h"
namespace oobe_config {
// Fake crypto helper. Encrypt and Decrypt just flip every bit.
// This means that they are symmetric but also that the plaintext
// and ciphertext are different.
class BitFlipCrypto : public tpmcrypto::TpmCrypto {
public:
bool Encrypt(const brillo::SecureBlob& data,
std::string* encrypted_data) override {
*encrypted_data = data.to_string();
for (size_t i = 0; i < encrypted_data->size(); i++) {
(*encrypted_data)[i] = ~(*encrypted_data)[i];
}
return true;
}
bool Decrypt(const std::string& encrypted_data,
brillo::SecureBlob* data) override {
*data = brillo::SecureBlob(encrypted_data);
for (size_t i = 0; i < data->size(); i++) {
(*data)[i] = ~(*data)[i];
}
return true;
}
};
class OobeConfigTest : public ::testing::Test {
protected:
void SetUp() override {
std::unique_ptr<tpmcrypto::TpmCrypto> crypto =
std::make_unique<BitFlipCrypto>();
oobe_config_ = std::make_unique<OobeConfig>(std::move(crypto));
ASSERT_TRUE(fake_root_dir_.CreateUniqueTempDir());
oobe_config_->set_prefix_path_for_testing(fake_root_dir_.GetPath());
}
void CheckSaveAndRestore(bool encrypted) {
oobe_config_->WriteFile(kSaveTempPath.Append(kInstallAttributesFileName),
"install_attributes");
oobe_config_->WriteFile(kSaveTempPath.Append(kOwnerKeyFileName), "owner");
oobe_config_->WriteFile(kSaveTempPath.Append(kPolicyFileName), "policy0");
oobe_config_->WriteFile(
kSaveTempPath.Append(kPolicyDotOneFileNameForTesting), "policy1");
oobe_config_->WriteFile(kSaveTempPath.Append(kShillDefaultProfileFileName),
"shill");
// Saving rollback data.
LOG(INFO) << "Saving rollback data...";
if (encrypted) {
ASSERT_TRUE(oobe_config_->EncryptedRollbackSave());
} else {
ASSERT_TRUE(oobe_config_->UnencryptedRollbackSave());
}
std::string rollback_data;
ASSERT_TRUE(oobe_config_->ReadFile(kUnencryptedStatefulRollbackDataPath,
&rollback_data));
EXPECT_FALSE(rollback_data.empty());
// Simulate powerwash and only preserve rollback_data by creating new temp
// dir.
base::ScopedTempDir tempdir_after;
ASSERT_TRUE(tempdir_after.CreateUniqueTempDir());
oobe_config_->set_prefix_path_for_testing(tempdir_after.GetPath());
// Verify that we don't have any remaining files.
std::string tmp_data = "x";
ASSERT_FALSE(oobe_config_->ReadFile(kUnencryptedStatefulRollbackDataPath,
&tmp_data));
EXPECT_TRUE(tmp_data.empty());
// Rewrite the rollback data to simulate the preservation that happens
// during a rollback powerwash.
ASSERT_TRUE(oobe_config_->WriteFile(kUnencryptedStatefulRollbackDataPath,
rollback_data));
// Restore data.
LOG(INFO) << "Restoring rollback data...";
if (encrypted) {
EXPECT_TRUE(oobe_config_->EncryptedRollbackRestore());
} else {
EXPECT_TRUE(oobe_config_->UnencryptedRollbackRestore());
}
// Verify that the config files are restored.
std::string file_content;
EXPECT_TRUE(oobe_config_->ReadFile(
kRestoreTempPath.Append(kInstallAttributesFileName), &file_content));
EXPECT_EQ("install_attributes", file_content);
EXPECT_TRUE(oobe_config_->ReadFile(
kRestoreTempPath.Append(kOwnerKeyFileName), &file_content));
EXPECT_EQ("owner", file_content);
EXPECT_TRUE(oobe_config_->ReadFile(kRestoreTempPath.Append(kPolicyFileName),
&file_content));
EXPECT_EQ("policy0", file_content);
EXPECT_TRUE(oobe_config_->ReadFile(
kRestoreTempPath.Append(kPolicyDotOneFileNameForTesting),
&file_content));
EXPECT_EQ("policy1", file_content);
EXPECT_TRUE(oobe_config_->ReadFile(
kRestoreTempPath.Append(kShillDefaultProfileFileName), &file_content));
EXPECT_EQ("shill", file_content);
}
base::ScopedTempDir fake_root_dir_;
std::unique_ptr<OobeConfig> oobe_config_;
};
TEST_F(OobeConfigTest, BitFlipTest) {
BitFlipCrypto crypto;
const std::string expected_plaintext = "I'm secret!";
brillo::SecureBlob plaintext_blob;
std::string actual_plaintext;
std::string encrypted;
crypto.Encrypt(brillo::SecureBlob(expected_plaintext), &encrypted);
crypto.Decrypt(encrypted, &plaintext_blob);
EXPECT_NE(encrypted, expected_plaintext);
actual_plaintext = plaintext_blob.to_string();
EXPECT_EQ(expected_plaintext, actual_plaintext);
}
TEST_F(OobeConfigTest, UnencryptedSaveAndRestoreTest) {
CheckSaveAndRestore(false /* encrypted */);
}
TEST_F(OobeConfigTest, EncryptedSaveAndRestoreTest) {
CheckSaveAndRestore(true /* encrypted */);
}
} // namespace oobe_config