blob: e96b7924284912e33fc29a82b2163ed9a5dd5be0 [file] [log] [blame]
David Yu7acfc2e2014-06-28 08:32:50 +08001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Xiaoyong Zhoub6f20902018-01-17 17:54:48 -08005#include "cryptohome/bootlockbox/boot_attributes.h"
David Yu7acfc2e2014-06-28 08:32:50 +08006
7#include <map>
Gwendal Grignouc7acaa92016-06-24 15:34:06 -07008#include <memory>
David Yu7acfc2e2014-06-28 08:32:50 +08009#include <string>
10
11#include <base/compiler_specific.h>
Gwendal Grignoudcdc1a42016-06-30 09:41:01 -070012#include <base/files/file_path.h>
Alex Vakulenkoe7696532015-10-16 16:27:29 -070013#include <brillo/secure_blob.h>
David Yu7acfc2e2014-06-28 08:32:50 +080014#include <gmock/gmock.h>
15#include <gtest/gtest.h>
16
Xiaoyong Zhoub6f20902018-01-17 17:54:48 -080017#include "cryptohome/bootlockbox/mock_boot_lockbox.h"
Greg Kerrf9b0fc12020-08-13 22:29:10 +000018#include "cryptohome/install_attributes.pb.h"
Alex Vakulenkob4b694a2014-07-18 17:21:35 -070019#include "cryptohome/mock_crypto.h"
20#include "cryptohome/mock_platform.h"
21#include "cryptohome/mock_tpm.h"
22
Gwendal Grignoudcdc1a42016-06-30 09:41:01 -070023using base::FilePath;
Maksim Ivanovcab8a0c2018-02-22 20:55:12 +010024using ::testing::_;
David Yu7acfc2e2014-06-28 08:32:50 +080025using ::testing::DoAll;
26using ::testing::Invoke;
Maksim Ivanovcab8a0c2018-02-22 20:55:12 +010027using ::testing::NiceMock;
David Yu7acfc2e2014-06-28 08:32:50 +080028using ::testing::Return;
29using ::testing::SetArgPointee;
30
31namespace cryptohome {
32namespace {
33
34class BootAttributesTest : public testing::Test {
35 public:
Tom Hughes6711cdc2020-09-14 08:34:01 -070036 BootAttributesTest() : fake_signature_("fake signature") {}
David Yu7acfc2e2014-06-28 08:32:50 +080037
Alex Vakulenko0945eaf2014-08-14 12:55:41 -070038 void SetUp() override {
David Yu7acfc2e2014-06-28 08:32:50 +080039 ON_CALL(mock_boot_lockbox_, Sign(_, _))
40 .WillByDefault(DoAll(SetArgPointee<1>(fake_signature_), Return(true)));
41
Tom Hughes6711cdc2020-09-14 08:34:01 -070042 ON_CALL(mock_boot_lockbox_, Verify(_, _)).WillByDefault(Return(true));
David Yu7acfc2e2014-06-28 08:32:50 +080043
44 ON_CALL(mock_platform_, ReadFile(_, _))
45 .WillByDefault(Invoke(this, &BootAttributesTest::FakeReadFile));
46
Jorge Lucangeli Obesed0481c2018-05-01 09:46:22 -040047 ON_CALL(mock_platform_, ReadFileToSecureBlob(_, _))
48 .WillByDefault(
49 Invoke(this, &BootAttributesTest::FakeReadFileToSecureBlob));
50
David Yu7acfc2e2014-06-28 08:32:50 +080051 ON_CALL(mock_platform_, WriteFile(_, _))
52 .WillByDefault(Invoke(this, &BootAttributesTest::FakeWriteFile));
53
54 CreateFakeFiles();
55
56 boot_attributes_.reset(
57 new BootAttributes(&mock_boot_lockbox_, &mock_platform_));
58 }
59
60 void CreateFakeFiles() {
61 SerializedInstallAttributes message;
62 message.set_version(1);
63 SerializedInstallAttributes::Attribute* attr = message.add_attributes();
64 attr->set_name("test1");
65 attr->set_value("1234");
66
Allen Webb9b4dc782020-05-15 13:09:44 -070067 brillo::Blob blob(message.ByteSizeLong());
Alex Vakulenko89f59bb2015-03-25 16:21:34 -070068 message.SerializeWithCachedSizesToArray(blob.data());
Gwendal Grignoudcdc1a42016-06-30 09:41:01 -070069 files_[FilePath(BootAttributes::kAttributeFile)] = blob;
David Yu7acfc2e2014-06-28 08:32:50 +080070
71 blob.clear();
Gwendal Grignoudcdc1a42016-06-30 09:41:01 -070072 files_[FilePath(BootAttributes::kSignatureFile)] = blob;
David Yu7acfc2e2014-06-28 08:32:50 +080073 }
74
Gwendal Grignoudcdc1a42016-06-30 09:41:01 -070075 bool FakeReadFile(const FilePath& filename, brillo::Blob* blob) {
David Yu7acfc2e2014-06-28 08:32:50 +080076 *blob = files_[filename];
77 return true;
78 }
79
Jorge Lucangeli Obesed0481c2018-05-01 09:46:22 -040080 bool FakeReadFileToSecureBlob(const FilePath& filename,
81 brillo::SecureBlob* sblob) {
82 brillo::Blob temp = files_[filename];
83 sblob->assign(temp.begin(), temp.end());
84 return true;
85 }
86
Gwendal Grignoudcdc1a42016-06-30 09:41:01 -070087 bool FakeWriteFile(const FilePath& filename, brillo::Blob blob) {
David Yu7acfc2e2014-06-28 08:32:50 +080088 files_[filename] = blob;
89 return true;
90 }
91
92 protected:
Alex Vakulenkoe7696532015-10-16 16:27:29 -070093 const brillo::SecureBlob fake_signature_;
David Yu7acfc2e2014-06-28 08:32:50 +080094
Darren Krahn5c76c012014-09-22 15:14:52 -070095 NiceMock<MockBootLockbox> mock_boot_lockbox_;
96 NiceMock<MockPlatform> mock_platform_;
David Yu7acfc2e2014-06-28 08:32:50 +080097
Gwendal Grignouc7acaa92016-06-24 15:34:06 -070098 std::unique_ptr<BootAttributes> boot_attributes_;
David Yu7acfc2e2014-06-28 08:32:50 +080099
Gwendal Grignoudcdc1a42016-06-30 09:41:01 -0700100 std::map<FilePath, brillo::Blob> files_;
David Yu7acfc2e2014-06-28 08:32:50 +0800101};
102
103TEST_F(BootAttributesTest, BasicOperations) {
104 std::string value;
105
106 // Empty initially.
107 EXPECT_FALSE(boot_attributes_->Get("test1", &value));
108
109 // Load values from the file.
110 EXPECT_TRUE(boot_attributes_->Load());
111 EXPECT_TRUE(boot_attributes_->Get("test1", &value));
112 EXPECT_EQ("1234", value);
113
114 // The value should still be unavailable after Set().
115 boot_attributes_->Set("test2", "5678");
116 EXPECT_FALSE(boot_attributes_->Get("test2", &value));
117
118 // The value becomes available after FlushAndSign().
119 EXPECT_TRUE(boot_attributes_->FlushAndSign());
120 EXPECT_TRUE(boot_attributes_->Get("test2", &value));
121 EXPECT_EQ("5678", value);
122
123 // Overwrite a value
124 boot_attributes_->Set("test1", "abcd");
125 EXPECT_TRUE(boot_attributes_->FlushAndSign());
126 EXPECT_TRUE(boot_attributes_->Get("test1", &value));
127 EXPECT_EQ("abcd", value);
128
129 // Verify the attribute file content.
Gwendal Grignoudcdc1a42016-06-30 09:41:01 -0700130 brillo::Blob blob = files_[FilePath(BootAttributes::kAttributeFile)];
David Yu7acfc2e2014-06-28 08:32:50 +0800131 SerializedInstallAttributes message;
132 message.ParseFromString(
Alex Vakulenko89f59bb2015-03-25 16:21:34 -0700133 std::string(reinterpret_cast<char*>(blob.data()), blob.size()));
David Yu7acfc2e2014-06-28 08:32:50 +0800134 EXPECT_EQ(BootAttributes::kAttributeFileVersion, message.version());
135
136 EXPECT_EQ(2, message.attributes_size());
137 bool has_test1 = false;
138 bool has_test2 = false;
139 for (int i = 0; i < message.attributes_size(); ++i) {
140 const SerializedInstallAttributes::Attribute& attr = message.attributes(i);
141 if (attr.name() == "test1") {
142 has_test1 = true;
143 EXPECT_EQ("abcd", attr.value());
144 } else if (attr.name() == "test2") {
145 has_test2 = true;
146 EXPECT_EQ("5678", attr.value());
147 } else {
148 FAIL();
149 }
150 }
151 EXPECT_TRUE(has_test1);
152 EXPECT_TRUE(has_test2);
153
154 // Verify the signature file content.
Gwendal Grignoudcdc1a42016-06-30 09:41:01 -0700155 blob = files_[FilePath(BootAttributes::kSignatureFile)];
Tom Hughes6711cdc2020-09-14 08:34:01 -0700156 EXPECT_EQ("fake signature",
157 std::string(reinterpret_cast<char*>(blob.data()), blob.size()));
David Yu7acfc2e2014-06-28 08:32:50 +0800158}
159
160TEST_F(BootAttributesTest, SignFailed) {
Tom Hughes6711cdc2020-09-14 08:34:01 -0700161 EXPECT_CALL(mock_boot_lockbox_, Sign(_, _)).WillRepeatedly(Return(false));
162 EXPECT_CALL(mock_platform_, WriteFile(_, _)).Times(0);
David Yu7acfc2e2014-06-28 08:32:50 +0800163
164 boot_attributes_->Set("test", "1234");
165 EXPECT_FALSE(boot_attributes_->FlushAndSign());
166}
167
168TEST_F(BootAttributesTest, WriteFileFailed) {
Tom Hughes6711cdc2020-09-14 08:34:01 -0700169 EXPECT_CALL(mock_platform_, WriteFile(_, _)).WillRepeatedly(Return(false));
David Yu7acfc2e2014-06-28 08:32:50 +0800170
171 boot_attributes_->Set("test", "1234");
172 EXPECT_FALSE(boot_attributes_->FlushAndSign());
173}
174
175TEST_F(BootAttributesTest, ReadFileFailed) {
Jorge Lucangeli Obes36e3b772018-06-05 16:40:56 -0400176 EXPECT_CALL(mock_platform_, ReadFile(_, _)).WillRepeatedly(Return(false));
Jorge Lucangeli Obesed0481c2018-05-01 09:46:22 -0400177 EXPECT_CALL(mock_platform_, ReadFileToSecureBlob(_, _))
David Yu7acfc2e2014-06-28 08:32:50 +0800178 .WillRepeatedly(Return(false));
179
180 EXPECT_FALSE(boot_attributes_->Load());
181}
182
183TEST_F(BootAttributesTest, VerifyFailed) {
Tom Hughes6711cdc2020-09-14 08:34:01 -0700184 EXPECT_CALL(mock_boot_lockbox_, Verify(_, _)).WillRepeatedly(Return(false));
David Yu7acfc2e2014-06-28 08:32:50 +0800185
186 EXPECT_FALSE(boot_attributes_->Load());
187}
188
189} // namespace
190} // namespace cryptohome