blob: 401b54ce2d5b2a851083f8c75ad1d9416646ea4d [file] [log] [blame]
Greg Kerr3e750f42016-06-29 15:20:21 -07001// Copyright 2016 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
Greg Kerra6c0c522016-07-25 11:15:31 -07005#include "imageloader_impl.h"
6
Greg Kerr3e750f42016-06-29 15:20:21 -07007#include <dirent.h>
8#include <stdlib.h>
9
10#include <algorithm>
11#include <list>
12#include <vector>
13
Greg Kerr2f76fde2016-08-29 16:39:45 -070014#include "mock_verity_mounter.h"
15#include "verity_mounter.h"
Greg Kerr3e750f42016-06-29 15:20:21 -070016
17#include <base/files/file_enumerator.h>
18#include <base/files/file_path.h>
19#include <base/files/file_util.h>
20#include <base/files/scoped_temp_dir.h>
21#include <base/logging.h>
Greg Kerr89be05f2016-07-27 10:40:32 -070022#include <base/memory/ptr_util.h>
Greg Kerr3e750f42016-06-29 15:20:21 -070023#include <base/numerics/safe_conversions.h>
24#include <base/strings/string_number_conversions.h>
25#include <base/values.h>
26#include <crypto/secure_hash.h>
27#include <crypto/sha2.h>
Greg Kerr89be05f2016-07-27 10:40:32 -070028#include <gmock/gmock.h>
29#include <gtest/gtest.h>
Greg Kerr3e750f42016-06-29 15:20:21 -070030
31namespace imageloader {
32
Greg Kerr89be05f2016-07-27 10:40:32 -070033using testing::_;
34
Greg Kerr3e750f42016-06-29 15:20:21 -070035namespace {
36
Greg Kerra6c0c522016-07-25 11:15:31 -070037// Test data always uses the dev key.
Greg Kerr2f76fde2016-08-29 16:39:45 -070038constexpr uint8_t kDevPublicKey[] = {
Greg Kerra6c0c522016-07-25 11:15:31 -070039 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
40 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
41 0x42, 0x00, 0x04, 0x7a, 0xaa, 0x2b, 0xf9, 0x3d, 0x7a, 0xbe, 0x35, 0x9a,
42 0xfc, 0x9f, 0x39, 0x2d, 0x2d, 0x37, 0x07, 0xd4, 0x19, 0x67, 0x67, 0x30,
43 0xbb, 0x5c, 0x74, 0x22, 0xd5, 0x02, 0x07, 0xaf, 0x6b, 0x12, 0x9d, 0x12,
44 0xf0, 0x34, 0xfd, 0x1a, 0x7f, 0x02, 0xd8, 0x46, 0x2b, 0x25, 0xca, 0xa0,
45 0x6e, 0x2b, 0x54, 0x41, 0xee, 0x92, 0xa2, 0x0f, 0xa2, 0x2a, 0xc0, 0x30,
46 0xa6, 0x8c, 0xd1, 0x16, 0x0a, 0x48, 0xca};
47
Greg Kerr2f76fde2016-08-29 16:39:45 -070048constexpr char kImageLoaderJSON[] =
Greg Kerr3e750f42016-06-29 15:20:21 -070049 "{\"image-sha256-hash\":"
Greg Kerr30cd5fb2016-09-29 12:37:02 -070050 "\"6B1E52D97EE63DDFDB3375FDC7F840D54116667E02745D31427C108B3F6885FD\","
51 "\"table-sha256-hash\":"
52 "\"24ECDCEC354FB7D020A237908A525CC96F6F77B95E906D5A0E49644D02692F2F\","
53 "\"version\":\"22.0.0.256\","
Greg Kerr3e750f42016-06-29 15:20:21 -070054 "\"manifest-version\":1}";
55
Greg Kerr2f76fde2016-08-29 16:39:45 -070056constexpr char kImageLoaderSig[] = {
Greg Kerr30cd5fb2016-09-29 12:37:02 -070057 0x30, 0x46, 0x02, 0x21, 0x00, 0x86, 0x4f, 0x25, 0x51, 0x52, 0xb1, 0x79,
58 0xa3, 0x3e, 0x9b, 0x08, 0x70, 0x10, 0x61, 0xca, 0x63, 0x37, 0x0c, 0xa2,
59 0x9f, 0x4f, 0x21, 0xd7, 0x37, 0x05, 0x4e, 0x8d, 0x73, 0x39, 0x18, 0x98,
60 0x94, 0x02, 0x21, 0x00, 0xf1, 0x64, 0x4f, 0x9d, 0x39, 0x58, 0xca, 0xef,
61 0xe7, 0x4c, 0xa2, 0x5e, 0x00, 0xcb, 0x33, 0x43, 0x7b, 0x9d, 0x72, 0x3e,
62 0x67, 0x39, 0x2c, 0xfb, 0x3a, 0xcb, 0x80, 0x2b, 0xc4, 0xca, 0xab, 0x8d};
Greg Kerr3e750f42016-06-29 15:20:21 -070063
Greg Kerr2f76fde2016-08-29 16:39:45 -070064constexpr char kImageLoaderBadSig[] = {
Greg Kerra6c0c522016-07-25 11:15:31 -070065 0x30, 0x44, 0x02, 0x20, 0x0a, 0x75, 0x49, 0xaf, 0x01, 0x3b, 0x48, 0x51,
66 0x45, 0x74, 0x8b, 0x41, 0x64, 0x21, 0x83, 0xce, 0xf1, 0x78, 0x1d, 0xd0,
67 0xa8, 0xd6, 0xae, 0x84, 0xf3, 0xc1, 0x3c, 0x3a, 0xee, 0xb4, 0x35, 0xb7,
68 0x02, 0x20, 0x34, 0xeb, 0xdc, 0x68, 0x2d, 0x8b, 0x4f, 0x64, 0x94, 0x64,
69 0xa3, 0xd5, 0xde, 0xab, 0xf9, 0xa0, 0xbd, 0xcc, 0xc1, 0x2f, 0x78, 0xd4,
70 0xe8, 0xed, 0x6a, 0x45, 0x38, 0x53, 0x54, 0xd2, 0xb1, 0x97};
71
72// This is the name of the component used in the test data.
Greg Kerr2f76fde2016-08-29 16:39:45 -070073constexpr char kTestComponentName[] = "PepperFlashPlayer";
Greg Kerra6c0c522016-07-25 11:15:31 -070074// This is the version of flash player used in the test data.
Greg Kerr2f76fde2016-08-29 16:39:45 -070075constexpr char kTestDataVersion[] = "22.0.0.158";
Greg Kerra6c0c522016-07-25 11:15:31 -070076// This is the version of the updated flash player in the test data.
Greg Kerr2f76fde2016-08-29 16:39:45 -070077constexpr char kTestUpdatedVersion[] = "22.0.0.256";
Greg Kerr3e750f42016-06-29 15:20:21 -070078
79} // namespace {}
80
81class ImageLoaderTest : public testing::Test {
82 public:
Greg Kerra6c0c522016-07-25 11:15:31 -070083 ImageLoaderConfig GetConfig(const char* path) {
84 std::vector<uint8_t> key(std::begin(kDevPublicKey),
85 std::end(kDevPublicKey));
Greg Kerr2f76fde2016-08-29 16:39:45 -070086 auto ops = base::MakeUnique<MockVerityMounter>();
Greg Kerr89be05f2016-07-27 10:40:32 -070087 ImageLoaderConfig config(key, path, "/foo", std::move(ops));
Greg Kerra6c0c522016-07-25 11:15:31 -070088 return config;
89 }
90
Greg Kerr3e750f42016-06-29 15:20:21 -070091 base::FilePath GetComponentPath() {
Greg Kerra6c0c522016-07-25 11:15:31 -070092 return GetComponentPath(kTestDataVersion);
93 }
94
95 base::FilePath GetComponentPath(const std::string& version) {
Greg Kerr3e750f42016-06-29 15:20:21 -070096 const char* src_dir = getenv("CROS_WORKON_SRCROOT");
97 CHECK(src_dir != nullptr);
98 base::FilePath component_path(src_dir);
99 component_path =
100 component_path.Append("src")
101 .Append("platform")
102 .Append("imageloader")
103 .Append("test")
Greg Kerra6c0c522016-07-25 11:15:31 -0700104 .Append(version + "_chromeos_intel64_PepperFlashPlayer");
Greg Kerr3e750f42016-06-29 15:20:21 -0700105 return component_path;
106 }
107
108 void GetFilesInDir(const base::FilePath& dir, std::list<std::string>* files) {
109 base::FileEnumerator file_enum(dir, false, base::FileEnumerator::FILES);
110 for (base::FilePath name = file_enum.Next(); !name.empty();
111 name = file_enum.Next()) {
112 files->emplace_back(name.BaseName().value());
113 }
114 }
115};
116
Greg Kerra6c0c522016-07-25 11:15:31 -0700117// Test the RegisterComponent public interface.
118TEST_F(ImageLoaderTest, RegisterComponentAndGetVersion) {
119 base::ScopedTempDir scoped_temp_dir;
120 ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
121 const base::FilePath& temp_dir = scoped_temp_dir.path();
122 // Delete the directory so that the ImageLoader can recreate it with the
123 // correct permissions.
124 base::DeleteFile(temp_dir, /*recursive=*/true);
125
126 ImageLoaderImpl loader(GetConfig(temp_dir.value().c_str()));
127 ASSERT_TRUE(loader.RegisterComponent(kTestComponentName, kTestDataVersion,
128 GetComponentPath().value()));
129
130 base::FilePath comp_dir = temp_dir.Append(kTestComponentName);
131 ASSERT_TRUE(base::DirectoryExists(comp_dir));
132
Greg Kerr89be05f2016-07-27 10:40:32 -0700133 base::FilePath hint_file = comp_dir.Append("latest-version");
Greg Kerra6c0c522016-07-25 11:15:31 -0700134 ASSERT_TRUE(base::PathExists(hint_file));
135
136 std::string hint_file_contents;
137 ASSERT_TRUE(
138 base::ReadFileToStringWithMaxSize(hint_file, &hint_file_contents, 4096));
139 EXPECT_EQ(kTestDataVersion, hint_file_contents);
140
141 base::FilePath version_dir = comp_dir.Append(kTestDataVersion);
142 ASSERT_TRUE(base::DirectoryExists(version_dir));
143
144 std::list<std::string> files;
145 GetFilesInDir(version_dir, &files);
146 EXPECT_THAT(files, testing::UnorderedElementsAre(
Greg Kerr30cd5fb2016-09-29 12:37:02 -0700147 "imageloader.json", "imageloader.sig.1", "table",
Greg Kerra6c0c522016-07-25 11:15:31 -0700148 "image.squash", "manifest.fingerprint"));
149
150 // Reject a component if the version already exists.
151 EXPECT_FALSE(loader.RegisterComponent(kTestComponentName, kTestDataVersion,
Greg Kerr89be05f2016-07-27 10:40:32 -0700152 GetComponentPath().value()));
Greg Kerra6c0c522016-07-25 11:15:31 -0700153
154 EXPECT_EQ(kTestDataVersion, loader.GetComponentVersion(kTestComponentName));
155
156 // Now copy a new version into place.
Greg Kerr89be05f2016-07-27 10:40:32 -0700157 EXPECT_TRUE(
158 loader.RegisterComponent(kTestComponentName, kTestUpdatedVersion,
159 GetComponentPath(kTestUpdatedVersion).value()));
Greg Kerra6c0c522016-07-25 11:15:31 -0700160
161 std::string hint_file_contents2;
162 ASSERT_TRUE(
163 base::ReadFileToStringWithMaxSize(hint_file, &hint_file_contents2, 4096));
164 EXPECT_EQ(kTestUpdatedVersion, hint_file_contents2);
165
166 base::FilePath version_dir2 = comp_dir.Append(kTestUpdatedVersion);
167 ASSERT_TRUE(base::DirectoryExists(version_dir2));
168
169 std::list<std::string> files2;
170 GetFilesInDir(version_dir2, &files2);
171 EXPECT_THAT(files2, testing::UnorderedElementsAre("imageloader.json",
172 "imageloader.sig.1",
Greg Kerr30cd5fb2016-09-29 12:37:02 -0700173 "table", "image.squash"));
Greg Kerra6c0c522016-07-25 11:15:31 -0700174
Greg Kerr89be05f2016-07-27 10:40:32 -0700175 EXPECT_EQ(kTestUpdatedVersion,
176 loader.GetComponentVersion(kTestComponentName));
Greg Kerra6c0c522016-07-25 11:15:31 -0700177
178 // Reject rollback to an older version.
179 EXPECT_FALSE(loader.RegisterComponent(kTestComponentName, kTestDataVersion,
Greg Kerr89be05f2016-07-27 10:40:32 -0700180 GetComponentPath().value()));
Greg Kerra6c0c522016-07-25 11:15:31 -0700181
Greg Kerr89be05f2016-07-27 10:40:32 -0700182 EXPECT_EQ(kTestUpdatedVersion,
183 loader.GetComponentVersion(kTestComponentName));
Greg Kerra6c0c522016-07-25 11:15:31 -0700184}
185
Greg Kerr764438b2016-07-15 11:32:37 -0700186TEST_F(ImageLoaderTest, ECVerify) {
Greg Kerra6c0c522016-07-25 11:15:31 -0700187 ImageLoaderImpl loader(GetConfig("/nonexistant"));
188 EXPECT_TRUE(loader.ECVerify(
Greg Kerr3e750f42016-06-29 15:20:21 -0700189 base::StringPiece(kImageLoaderJSON),
190 base::StringPiece(kImageLoaderSig, sizeof(kImageLoaderSig))));
191
Greg Kerra6c0c522016-07-25 11:15:31 -0700192 EXPECT_FALSE(loader.ECVerify(
Greg Kerr3e750f42016-06-29 15:20:21 -0700193 base::StringPiece(kImageLoaderJSON),
194 base::StringPiece(kImageLoaderBadSig, sizeof(kImageLoaderBadSig))));
195}
196
197TEST_F(ImageLoaderTest, ManifestFingerPrint) {
Greg Kerra6c0c522016-07-25 11:15:31 -0700198 ImageLoaderImpl loader(GetConfig("/nonexistant"));
Greg Kerr3e750f42016-06-29 15:20:21 -0700199 const std::string valid_manifest =
200 "1.3464353b1ed78574e05f3ffe84b52582572b2fe7202f3824a3761e54ace8bb1";
Greg Kerra6c0c522016-07-25 11:15:31 -0700201 EXPECT_TRUE(loader.IsValidFingerprintFile(valid_manifest));
Greg Kerr3e750f42016-06-29 15:20:21 -0700202
203 const std::string invalid_unicode_manifest = "Ё Ђ Ѓ Є Ѕ І Ї Ј Љ ";
Greg Kerra6c0c522016-07-25 11:15:31 -0700204 EXPECT_FALSE(loader.IsValidFingerprintFile(invalid_unicode_manifest));
Greg Kerr3e750f42016-06-29 15:20:21 -0700205
Greg Kerra6c0c522016-07-25 11:15:31 -0700206 EXPECT_FALSE(loader.IsValidFingerprintFile("\x49\x34\x19-43.*+abc"));
Greg Kerr3e750f42016-06-29 15:20:21 -0700207}
208
209TEST_F(ImageLoaderTest, CopyValidComponent) {
Greg Kerra6c0c522016-07-25 11:15:31 -0700210 ImageLoaderImpl loader(GetConfig("/nonexistant"));
Greg Kerr3e750f42016-06-29 15:20:21 -0700211 const int image_size = 4096 * 4;
212 base::ScopedTempDir scoped_temp_dir;
213 ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
214 const base::FilePath& temp_dir = scoped_temp_dir.path();
215
216 std::vector<char> image(image_size, 0xBB);
217 base::FilePath component_dest = temp_dir.Append("copied-component");
Greg Kerra6c0c522016-07-25 11:15:31 -0700218 ASSERT_TRUE(loader.CopyComponentDirectory(GetComponentPath(), component_dest,
219 kTestDataVersion));
Greg Kerr3e750f42016-06-29 15:20:21 -0700220
221 // Check that all the files are present, except for the manifest.json which
222 // should be discarded.
223 std::list<std::string> original_files;
224 std::list<std::string> copied_files;
225 GetFilesInDir(GetComponentPath(), &original_files);
226 GetFilesInDir(component_dest, &copied_files);
227
228 EXPECT_THAT(original_files,
229 testing::UnorderedElementsAre(
230 "imageloader.json", "imageloader.sig.1", "manifest.json",
Greg Kerr30cd5fb2016-09-29 12:37:02 -0700231 "table", "image.squash", "manifest.fingerprint"));
Greg Kerr3e750f42016-06-29 15:20:21 -0700232 EXPECT_THAT(copied_files,
233 testing::UnorderedElementsAre(
Greg Kerr30cd5fb2016-09-29 12:37:02 -0700234 "imageloader.json", "imageloader.sig.1", "table",
Greg Kerr3e750f42016-06-29 15:20:21 -0700235 "image.squash", "manifest.fingerprint"));
236}
237
238TEST_F(ImageLoaderTest, CopyComponentWithBadManifest) {
239 base::ScopedTempDir scoped_temp_dir;
240 ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
241 const base::FilePath& temp_dir = scoped_temp_dir.path();
242
243 base::FilePath bad_component_dir = temp_dir.Append("bad-component");
244
245 ASSERT_TRUE(base::CopyDirectory(GetComponentPath(), bad_component_dir,
246 true /* recursive */));
247
248 base::FilePath manifest = bad_component_dir.Append("imageloader.json");
249 const char data[] = "c";
250 ASSERT_TRUE(base::AppendToFile(manifest, data, sizeof(data)));
251
Greg Kerra6c0c522016-07-25 11:15:31 -0700252 ImageLoaderImpl loader(GetConfig("/nonexistant"));
253 EXPECT_FALSE(loader.CopyComponentDirectory(
Greg Kerr89be05f2016-07-27 10:40:32 -0700254 bad_component_dir, temp_dir.Append("copied-component"),
255 kTestDataVersion));
Greg Kerr3e750f42016-06-29 15:20:21 -0700256}
257
258TEST_F(ImageLoaderTest, CopyValidImage) {
259 const int image_size = 4096 * 4;
260
261 base::ScopedTempDir scoped_temp_dir;
262 ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
263 const base::FilePath& temp_dir = scoped_temp_dir.path();
264
265 base::FilePath image_path = temp_dir.Append("image");
266 std::vector<char> image(image_size,
267 0xBB); // large enough to test streaming read.
268 ASSERT_TRUE(base::WriteFile(image_path, image.data(), image.size()) ==
269 image_size);
270
271 std::vector<uint8_t> hash(crypto::kSHA256Length);
272
273 std::unique_ptr<crypto::SecureHash> sha256(
274 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
275 sha256->Update(image.data(), image.size());
276 sha256->Finish(hash.data(), hash.size());
277
Greg Kerra6c0c522016-07-25 11:15:31 -0700278 ImageLoaderImpl loader(GetConfig("/nonexistant"));
Greg Kerr3e750f42016-06-29 15:20:21 -0700279 base::FilePath image_dest = temp_dir.Append("image.copied");
Greg Kerra6c0c522016-07-25 11:15:31 -0700280 ASSERT_TRUE(loader.CopyAndHashFile(image_path, image_dest, hash));
Greg Kerr3e750f42016-06-29 15:20:21 -0700281
282 // Check if the image file actually exists and has the correct contents.
283 std::string resulting_image;
284 ASSERT_TRUE(base::ReadFileToStringWithMaxSize(image_dest, &resulting_image,
285 image_size));
286
287 EXPECT_TRUE(memcmp(image.data(), resulting_image.data(), image_size) == 0);
288}
289
290TEST_F(ImageLoaderTest, CopyInvalidImage) {
291 const int image_size = 4096 * 4;
292 // It doesn't matter what the hash is, because this is testing a mismatch.
293 std::string hash_str =
294 "5342065E5D9889739B281D96FD985270A13F2B68A29DD47142ABFA0C2C659AA1";
295 std::vector<uint8_t> hash;
296 ASSERT_TRUE(base::HexStringToBytes(hash_str, &hash));
297
298 base::ScopedTempDir scoped_temp_dir;
299 ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
300 const base::FilePath& temp_dir = scoped_temp_dir.path();
301
302 base::FilePath image_src = temp_dir.Append("bad_image.squash");
303 base::FilePath image_dest = temp_dir.Append("image.squash");
304
305 std::vector<char> file(image_size, 0xAA);
306 ASSERT_EQ(image_size, base::WriteFile(image_src, file.data(), image_size));
307
Greg Kerra6c0c522016-07-25 11:15:31 -0700308 ImageLoaderImpl loader(GetConfig("/nonexistant"));
309 EXPECT_FALSE(loader.CopyAndHashFile(image_src, image_dest, hash));
Greg Kerr3e750f42016-06-29 15:20:21 -0700310}
311
Greg Kerr4bd78132016-07-19 11:51:16 -0700312TEST_F(ImageLoaderTest, ParseManifest) {
Greg Kerra6c0c522016-07-25 11:15:31 -0700313 ImageLoaderImpl loader(GetConfig("/nonexistant"));
314 ImageLoaderImpl::Manifest manifest;
Greg Kerr30cd5fb2016-09-29 12:37:02 -0700315 std::string imageloader_sig(kImageLoaderSig, sizeof(kImageLoaderSig));
316 ASSERT_TRUE(loader.VerifyAndParseManifest(kImageLoaderJSON, imageloader_sig,
Greg Kerra6c0c522016-07-25 11:15:31 -0700317 &manifest));
Greg Kerr4bd78132016-07-19 11:51:16 -0700318 EXPECT_EQ(1, manifest.manifest_version);
Greg Kerr30cd5fb2016-09-29 12:37:02 -0700319 EXPECT_EQ(kTestUpdatedVersion, manifest.version);
Greg Kerr4bd78132016-07-19 11:51:16 -0700320 EXPECT_EQ(32, manifest.image_sha256.size());
Greg Kerr30cd5fb2016-09-29 12:37:02 -0700321 EXPECT_EQ(32, manifest.table_sha256.size());
Greg Kerr4bd78132016-07-19 11:51:16 -0700322
323 std::string bad_manifest = "{\"foo\":\"128.0.0.9\"}";
Greg Kerra6c0c522016-07-25 11:15:31 -0700324 ImageLoaderImpl::Manifest manifest2;
325 EXPECT_FALSE(
326 loader.VerifyAndParseManifest(bad_manifest, kImageLoaderSig, &manifest2));
Greg Kerr4bd78132016-07-19 11:51:16 -0700327
Greg Kerra6c0c522016-07-25 11:15:31 -0700328 ImageLoaderImpl::Manifest manifest3;
329 EXPECT_FALSE(loader.VerifyAndParseManifest(kImageLoaderJSON,
330 kImageLoaderBadSig, &manifest3));
Greg Kerr4bd78132016-07-19 11:51:16 -0700331}
332
Greg Kerr89be05f2016-07-27 10:40:32 -0700333TEST_F(ImageLoaderTest, MountValidImage) {
334 std::vector<uint8_t> key(std::begin(kDevPublicKey), std::end(kDevPublicKey));
Greg Kerr2f76fde2016-08-29 16:39:45 -0700335 auto mount_mock = base::MakeUnique<MockVerityMounter>();
336 ON_CALL(*mount_mock, Mount(_, _, _)).WillByDefault(testing::Return(true));
337 EXPECT_CALL(*mount_mock, Mount(_, _, _)).Times(2);
Greg Kerr89be05f2016-07-27 10:40:32 -0700338
339 base::ScopedTempDir scoped_temp_dir;
340 base::ScopedTempDir scoped_mount_dir;
341 ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
342 ASSERT_TRUE(scoped_mount_dir.CreateUniqueTempDir());
343
344 const base::FilePath& temp_dir = scoped_temp_dir.path();
345 // Delete the directory so that the ImageLoader can recreate it with the
346 // correct permissions.
347 base::DeleteFile(temp_dir, /*recursive=*/true);
Greg Kerr2f76fde2016-08-29 16:39:45 -0700348 ImageLoaderConfig config(key, temp_dir.value().c_str(),
349 scoped_mount_dir.path().value().c_str(),
350 std::move(mount_mock));
Greg Kerr89be05f2016-07-27 10:40:32 -0700351 ImageLoaderImpl loader(std::move(config));
352
353 // We previously tested RegisterComponent, so assume this works if it reports
354 // true.
355 ASSERT_TRUE(loader.RegisterComponent(kTestComponentName, kTestDataVersion,
356 GetComponentPath().value()));
357
358 const std::string expected_path =
359 scoped_mount_dir.path().value() + "/PepperFlashPlayer/22.0.0.158";
Greg Kerrc5b91692016-09-14 12:09:22 -0700360 EXPECT_EQ(expected_path, loader.LoadComponent(kTestComponentName));
361
362 // Let's also test mounting the component at a fixed point.
363 const std::string expected_path2 =
364 scoped_mount_dir.path().value() + "/FixedMountPoint";
365 EXPECT_TRUE(loader.LoadComponent(kTestComponentName, expected_path2));
Greg Kerr89be05f2016-07-27 10:40:32 -0700366}
367
368TEST_F(ImageLoaderTest, MountInvalidImage) {
369 std::vector<uint8_t> key(std::begin(kDevPublicKey), std::end(kDevPublicKey));
Greg Kerr2f76fde2016-08-29 16:39:45 -0700370 auto mount_mock = base::MakeUnique<MockVerityMounter>();
371 ON_CALL(*mount_mock, Mount(_, _, _)).WillByDefault(testing::Return(true));
372 EXPECT_CALL(*mount_mock, Mount(_, _, _)).Times(0);
Greg Kerr89be05f2016-07-27 10:40:32 -0700373
374 base::ScopedTempDir scoped_temp_dir;
375 base::ScopedTempDir scoped_mount_dir;
376 ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
377 ASSERT_TRUE(scoped_mount_dir.CreateUniqueTempDir());
378
379 const base::FilePath& temp_dir = scoped_temp_dir.path();
380 // Delete the directory so that the ImageLoader can recreate it with the
381 // correct permissions.
382 base::DeleteFile(temp_dir, /*recursive=*/true);
383
Greg Kerr2f76fde2016-08-29 16:39:45 -0700384 ImageLoaderConfig config(key, temp_dir.value().c_str(),
385 scoped_mount_dir.path().value().c_str(),
386 std::move(mount_mock));
Greg Kerr89be05f2016-07-27 10:40:32 -0700387 ImageLoaderImpl loader(std::move(config));
388
389 // We previously tested RegisterComponent, so assume this works if it reports
390 // true.
391 ASSERT_TRUE(loader.RegisterComponent(kTestComponentName, kTestDataVersion,
392 GetComponentPath().value()));
393
Greg Kerr30cd5fb2016-09-29 12:37:02 -0700394 base::FilePath table = temp_dir.Append(kTestComponentName)
Greg Kerr89be05f2016-07-27 10:40:32 -0700395 .Append(kTestDataVersion)
Greg Kerr30cd5fb2016-09-29 12:37:02 -0700396 .Append("table");
Greg Kerr89be05f2016-07-27 10:40:32 -0700397 std::string contents = "corrupt";
398 ASSERT_EQ(static_cast<int>(contents.size()),
Greg Kerr30cd5fb2016-09-29 12:37:02 -0700399 base::WriteFile(table, contents.data(), contents.size()));
Greg Kerr89be05f2016-07-27 10:40:32 -0700400 ASSERT_EQ("", loader.LoadComponent(kTestComponentName));
401}
402
Greg Kerr2f76fde2016-08-29 16:39:45 -0700403TEST_F(ImageLoaderTest, SetupTable) {
404 std::string base_table = "0 40 verity payload=ROOT_DEV hashtree=HASH_DEV "
405 "hashstart=40 alg=sha256 root_hexdigest="
406 "34663b9920632778d38a0943a5472cae196bd4bf1d7dfa191506e7a8e7ec84d2 "
407 "salt=fcfc9b5a329e44be73a323188ae75ca644122d920161f672f6935623831d07e2";
408
409 // Make sure excess newlines are rejected.
410 std::string bad_table = base_table + "\n\n";
411 EXPECT_FALSE(VerityMounter::SetupTable(&bad_table, "/dev/loop6"));
412
413 // Make sure it does the right replacements on a simple base table.
414 std::string good_table = base_table;
415 EXPECT_TRUE(VerityMounter::SetupTable(&good_table, "/dev/loop6"));
416
417 std::string known_good_table =
418 "0 40 verity payload=/dev/loop6 hashtree=/dev/loop6 "
419 "hashstart=40 alg=sha256 root_hexdigest="
420 "34663b9920632778d38a0943a5472cae196bd4bf1d7dfa191506e7a8e7ec84d2 "
421 "salt=fcfc9b5a329e44be73a323188ae75ca644122d920161f672f6935623831d07e2 "
422 "error_behavior=eio";
423 EXPECT_EQ(known_good_table, good_table);
424
425 // Make sure the newline is stripped.
426 std::string good_table_newline = base_table + "\n";
427 EXPECT_TRUE(VerityMounter::SetupTable(&good_table_newline, "/dev/loop6"));
428 EXPECT_EQ(known_good_table, good_table_newline);
429
430 // Make sure error_behavior isn't appended twice.
431 std::string good_table_error = base_table + " error_behavior=eio\n";
432 EXPECT_TRUE(VerityMounter::SetupTable(&good_table_error, "/dev/loop6"));
433 EXPECT_EQ(known_good_table, good_table_error);
434}
435
Greg Kerra6c0c522016-07-25 11:15:31 -0700436} // namespace imageloader