blob: dc0b202fdb1ab5f73b524b6184bbbf9c3c963f09 [file] [log] [blame]
Mike Frysinger8155d082012-04-06 15:23:18 -04001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Andrew de los Reyes09e56d62010-04-23 13:45:53 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Andrew de los Reyes09e56d62010-04-23 13:45:53 -07005#include <inttypes.h>
Alex Deymo161c4a12014-05-16 15:56:21 -07006#include <sys/mount.h>
Andrew de los Reyes09e56d62010-04-23 13:45:53 -07007
8#include <algorithm>
9#include <string>
10#include <vector>
11
Darin Petkov9fa7ec52010-10-18 11:45:23 -070012#include <base/file_util.h>
Chris Masoned903c3b2011-05-12 15:35:46 -070013#include <base/memory/scoped_ptr.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070014#include <base/strings/string_util.h>
15#include <base/strings/stringprintf.h>
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070016#include <google/protobuf/repeated_field.h>
17#include <gtest/gtest.h>
18
Jay Srinivasand29695d2013-04-08 15:08:05 -070019#include "update_engine/constants.h"
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070020#include "update_engine/delta_performer.h"
Andrew de los Reyes353777c2010-10-08 10:34:30 -070021#include "update_engine/extent_ranges.h"
David Zeuthene7f89172013-10-31 10:21:04 -070022#include "update_engine/fake_hardware.h"
Gilad Arnold5bb4c902014-04-10 12:32:13 -070023#include "update_engine/fake_system_state.h"
Alex Deymo161c4a12014-05-16 15:56:21 -070024#include "update_engine/payload_constants.h"
25#include "update_engine/payload_generator/delta_diff_generator.h"
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070026#include "update_engine/payload_signer.h"
Darin Petkov73058b42010-10-06 16:32:19 -070027#include "update_engine/prefs_mock.h"
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070028#include "update_engine/test_utils.h"
29#include "update_engine/update_metadata.pb.h"
30#include "update_engine/utils.h"
31
32namespace chromeos_update_engine {
33
34using std::min;
35using std::string;
36using std::vector;
Darin Petkov73058b42010-10-06 16:32:19 -070037using testing::Return;
Alex Deymo161c4a12014-05-16 15:56:21 -070038using testing::_;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070039
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070040extern const char* kUnittestPrivateKeyPath;
Darin Petkovd7061ab2010-10-06 14:37:09 -070041extern const char* kUnittestPublicKeyPath;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -070042extern const char* kUnittestPrivateKey2Path;
43extern const char* kUnittestPublicKey2Path;
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070044
Jay Srinivasan738fdf32012-12-07 17:40:54 -080045static const size_t kBlockSize = 4096;
46static const char* kBogusMetadataSignature1 = "awSFIUdUZz2VWFiR+ku0Pj00V7bPQPQFYQSXjEXr3vaw3TE4xHV5CraY3/YrZpBvJ5z4dSBskoeuaO1TNC/S6E05t+yt36tE4Fh79tMnJ/z9fogBDXWgXLEUyG78IEQrYH6/eBsQGT2RJtBgXIXbZ9W+5G9KmGDoPOoiaeNsDuqHiBc/58OFsrxskH8E6vMSBmMGGk82mvgzic7ApcoURbCGey1b3Mwne/hPZ/bb9CIyky8Og9IfFMdL2uAweOIRfjoTeLYZpt+WN65Vu7jJ0cQN8e1y+2yka5112wpRf/LLtPgiAjEZnsoYpLUd7CoVpLRtClp97kN2+tXGNBQqkA==";
47
48static const int kDefaultKernelSize = 4096; // Something small for a test
49static const char* kNewDataString = "This is new data.";
50
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070051namespace {
Jay Srinivasan738fdf32012-12-07 17:40:54 -080052struct DeltaState {
53 string a_img;
54 string b_img;
55 int image_size;
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070056
Jay Srinivasan738fdf32012-12-07 17:40:54 -080057 string delta_path;
58 uint64_t metadata_size;
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070059
Jay Srinivasan738fdf32012-12-07 17:40:54 -080060 string old_kernel;
61 vector<char> old_kernel_data;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070062
Jay Srinivasan738fdf32012-12-07 17:40:54 -080063 string new_kernel;
64 vector<char> new_kernel_data;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070065
Jay Srinivasan738fdf32012-12-07 17:40:54 -080066 // The in-memory copy of delta file.
67 vector<char> delta;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080068
69 // The mock system state object with which we initialize the
70 // delta performer.
Gilad Arnold5bb4c902014-04-10 12:32:13 -070071 FakeSystemState fake_system_state;
Jay Srinivasan738fdf32012-12-07 17:40:54 -080072};
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070073
Jay Srinivasan738fdf32012-12-07 17:40:54 -080074enum SignatureTest {
75 kSignatureNone, // No payload signing.
76 kSignatureGenerator, // Sign the payload at generation time.
77 kSignatureGenerated, // Sign the payload after it's generated.
Don Garrett2ae37872013-10-25 13:33:20 -070078 kSignatureGeneratedPlaceholder, // Insert placeholder signatures, then real.
79 kSignatureGeneratedPlaceholderMismatch, // Insert a wrong sized placeholder.
Jay Srinivasan738fdf32012-12-07 17:40:54 -080080 kSignatureGeneratedShell, // Sign the generated payload through shell cmds.
81 kSignatureGeneratedShellBadKey, // Sign with a bad key through shell cmds.
82 kSignatureGeneratedShellRotateCl1, // Rotate key, test client v1
83 kSignatureGeneratedShellRotateCl2, // Rotate key, test client v2
84};
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070085
Jay Srinivasan738fdf32012-12-07 17:40:54 -080086// Different options that determine what we should fill into the
87// install_plan.metadata_signature to simulate the contents received in the
88// Omaha response.
89enum MetadataSignatureTest {
90 kEmptyMetadataSignature,
91 kInvalidMetadataSignature,
92 kValidMetadataSignature,
93};
94
95enum OperationHashTest {
96 kInvalidOperationData,
97 kValidOperationData,
98};
99
100} // namespace {}
101
102static void CompareFilesByBlock(const string& a_file, const string& b_file) {
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700103 vector<char> a_data, b_data;
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700104 EXPECT_TRUE(utils::ReadFile(a_file, &a_data)) << "file failed: " << a_file;
105 EXPECT_TRUE(utils::ReadFile(b_file, &b_data)) << "file failed: " << b_file;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700106
107 EXPECT_EQ(a_data.size(), b_data.size());
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700108 EXPECT_EQ(0, a_data.size() % kBlockSize);
109 for (size_t i = 0; i < a_data.size(); i += kBlockSize) {
110 EXPECT_EQ(0, i % kBlockSize);
111 vector<char> a_sub(&a_data[i], &a_data[i + kBlockSize]);
112 vector<char> b_sub(&b_data[i], &b_data[i + kBlockSize]);
113 EXPECT_TRUE(a_sub == b_sub) << "Block " << (i/kBlockSize) << " differs";
114 }
115}
116
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800117static bool WriteSparseFile(const string& path, off_t size) {
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700118 int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
119 TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
120 ScopedFdCloser fd_closer(&fd);
121 off_t rc = lseek(fd, size + 1, SEEK_SET);
122 TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1));
123 int return_code = ftruncate(fd, size);
124 TEST_AND_RETURN_FALSE_ERRNO(return_code == 0);
125 return true;
126}
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700127
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800128static size_t GetSignatureSize(const string& private_key_path) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800129 const vector<char> data(1, 'x');
130 vector<char> hash;
131 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(data, &hash));
132 vector<char> signature;
133 EXPECT_TRUE(PayloadSigner::SignHash(hash,
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800134 private_key_path,
Darin Petkovcbfb0172011-01-14 15:24:45 -0800135 &signature));
136 return signature.size();
137}
138
Don Garrett2ae37872013-10-25 13:33:20 -0700139static bool InsertSignaturePlaceholder(int signature_size,
140 const string& payload_path,
141 uint64_t* out_metadata_size) {
142 vector<vector<char> > signatures;
143 signatures.push_back(vector<char>(signature_size, 0));
144
145 return PayloadSigner::AddSignatureToPayload(
146 payload_path,
147 signatures,
148 payload_path,
149 out_metadata_size);
150}
151
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800152static void SignGeneratedPayload(const string& payload_path,
153 uint64_t* out_metadata_size) {
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800154 int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800155 vector<char> hash;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700156 ASSERT_TRUE(PayloadSigner::HashPayloadForSigning(
157 payload_path,
158 vector<int>(1, signature_size),
159 &hash));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800160 vector<char> signature;
161 ASSERT_TRUE(PayloadSigner::SignHash(hash,
162 kUnittestPrivateKeyPath,
163 &signature));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700164 ASSERT_TRUE(PayloadSigner::AddSignatureToPayload(
165 payload_path,
166 vector<vector<char> >(1, signature),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800167 payload_path,
168 out_metadata_size));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700169 EXPECT_TRUE(PayloadSigner::VerifySignedPayload(
170 payload_path,
171 kUnittestPublicKeyPath,
172 kSignatureMessageOriginalVersion));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800173}
174
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800175static void SignGeneratedShellPayload(SignatureTest signature_test,
176 const string& payload_path) {
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800177 string private_key_path = kUnittestPrivateKeyPath;
178 if (signature_test == kSignatureGeneratedShellBadKey) {
Gilad Arnolda6742b32014-01-11 00:18:34 -0800179 ASSERT_TRUE(utils::MakeTempFile("key.XXXXXX",
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800180 &private_key_path,
181 NULL));
182 } else {
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700183 ASSERT_TRUE(signature_test == kSignatureGeneratedShell ||
184 signature_test == kSignatureGeneratedShellRotateCl1 ||
185 signature_test == kSignatureGeneratedShellRotateCl2);
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800186 }
187 ScopedPathUnlinker key_unlinker(private_key_path);
188 key_unlinker.set_should_remove(signature_test ==
189 kSignatureGeneratedShellBadKey);
190 // Generates a new private key that will not match the public key.
191 if (signature_test == kSignatureGeneratedShellBadKey) {
192 LOG(INFO) << "Generating a mismatched private key.";
193 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700194 System(base::StringPrintf("openssl genrsa -out %s 2048",
195 private_key_path.c_str())));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800196 }
197 int signature_size = GetSignatureSize(private_key_path);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800198 string hash_file;
Gilad Arnolda6742b32014-01-11 00:18:34 -0800199 ASSERT_TRUE(utils::MakeTempFile("hash.XXXXXX", &hash_file, NULL));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800200 ScopedPathUnlinker hash_unlinker(hash_file);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700201 string signature_size_string;
202 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
203 signature_test == kSignatureGeneratedShellRotateCl2)
Alex Vakulenko75039d72014-03-25 12:36:28 -0700204 signature_size_string = base::StringPrintf("%d:%d",
205 signature_size, signature_size);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700206 else
Alex Vakulenko75039d72014-03-25 12:36:28 -0700207 signature_size_string = base::StringPrintf("%d", signature_size);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800208 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700209 System(base::StringPrintf(
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700210 "./delta_generator -in_file %s -signature_size %s "
Darin Petkovcbfb0172011-01-14 15:24:45 -0800211 "-out_hash_file %s",
212 payload_path.c_str(),
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700213 signature_size_string.c_str(),
Darin Petkovcbfb0172011-01-14 15:24:45 -0800214 hash_file.c_str())));
215
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -0700216 // Pad the hash
217 vector<char> hash;
218 ASSERT_TRUE(utils::ReadFile(hash_file, &hash));
219 ASSERT_TRUE(PayloadSigner::PadRSA2048SHA256Hash(&hash));
220 ASSERT_TRUE(WriteFileVector(hash_file, hash));
221
Darin Petkovcbfb0172011-01-14 15:24:45 -0800222 string sig_file;
Gilad Arnolda6742b32014-01-11 00:18:34 -0800223 ASSERT_TRUE(utils::MakeTempFile("signature.XXXXXX", &sig_file, NULL));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800224 ScopedPathUnlinker sig_unlinker(sig_file);
225 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700226 System(base::StringPrintf(
Mike Frysinger2149be42012-03-12 19:23:47 -0400227 "openssl rsautl -raw -sign -inkey %s -in %s -out %s",
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800228 private_key_path.c_str(),
Darin Petkovcbfb0172011-01-14 15:24:45 -0800229 hash_file.c_str(),
230 sig_file.c_str())));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700231 string sig_file2;
Gilad Arnolda6742b32014-01-11 00:18:34 -0800232 ASSERT_TRUE(utils::MakeTempFile("signature.XXXXXX", &sig_file2, NULL));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700233 ScopedPathUnlinker sig2_unlinker(sig_file2);
234 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
235 signature_test == kSignatureGeneratedShellRotateCl2) {
236 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700237 System(base::StringPrintf(
Mike Frysinger2149be42012-03-12 19:23:47 -0400238 "openssl rsautl -raw -sign -inkey %s -in %s -out %s",
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700239 kUnittestPrivateKey2Path,
240 hash_file.c_str(),
241 sig_file2.c_str())));
242 // Append second sig file to first path
243 sig_file += ":" + sig_file2;
244 }
245
Darin Petkovcbfb0172011-01-14 15:24:45 -0800246 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700247 System(base::StringPrintf(
Darin Petkovcbfb0172011-01-14 15:24:45 -0800248 "./delta_generator -in_file %s -signature_file %s "
249 "-out_file %s",
250 payload_path.c_str(),
251 sig_file.c_str(),
252 payload_path.c_str())));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800253 int verify_result =
Alex Vakulenko75039d72014-03-25 12:36:28 -0700254 System(base::StringPrintf(
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700255 "./delta_generator -in_file %s -public_key %s -public_key_version %d",
256 payload_path.c_str(),
257 signature_test == kSignatureGeneratedShellRotateCl2 ?
258 kUnittestPublicKey2Path : kUnittestPublicKeyPath,
259 signature_test == kSignatureGeneratedShellRotateCl2 ? 2 : 1));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800260 if (signature_test == kSignatureGeneratedShellBadKey) {
261 ASSERT_NE(0, verify_result);
262 } else {
263 ASSERT_EQ(0, verify_result);
264 }
Darin Petkovcbfb0172011-01-14 15:24:45 -0800265}
266
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800267static void GenerateDeltaFile(bool full_kernel,
268 bool full_rootfs,
269 bool noop,
Darin Petkov8e447e02013-04-16 16:23:50 +0200270 off_t chunk_size,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800271 SignatureTest signature_test,
272 DeltaState *state) {
Gilad Arnolda6742b32014-01-11 00:18:34 -0800273 EXPECT_TRUE(utils::MakeTempFile("a_img.XXXXXX", &state->a_img, NULL));
274 EXPECT_TRUE(utils::MakeTempFile("b_img.XXXXXX", &state->b_img, NULL));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800275 CreateExtImageAtPath(state->a_img, NULL);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700276
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800277 state->image_size = static_cast<int>(utils::FileSize(state->a_img));
Darin Petkov7ea32332010-10-13 10:46:11 -0700278
279 // Extend the "partitions" holding the file system a bit.
280 EXPECT_EQ(0, System(base::StringPrintf(
281 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800282 state->a_img.c_str(),
283 state->image_size + 1024 * 1024 - 1)));
284 EXPECT_EQ(state->image_size + 1024 * 1024, utils::FileSize(state->a_img));
Darin Petkov7ea32332010-10-13 10:46:11 -0700285
Don Garrett0dd39852013-04-03 16:55:42 -0700286 // Create ImageInfo A & B
287 ImageInfo old_image_info;
288 ImageInfo new_image_info;
289
290 if (!full_rootfs) {
291 old_image_info.set_channel("src-channel");
292 old_image_info.set_board("src-board");
293 old_image_info.set_version("src-version");
294 old_image_info.set_key("src-key");
295 old_image_info.set_build_channel("src-build-channel");
296 old_image_info.set_build_version("src-build-version");
297 }
298
299 new_image_info.set_channel("test-channel");
300 new_image_info.set_board("test-board");
301 new_image_info.set_version("test-version");
302 new_image_info.set_key("test-key");
303 new_image_info.set_build_channel("test-build-channel");
304 new_image_info.set_build_version("test-build-version");
305
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700306 // Make some changes to the A image.
307 {
308 string a_mnt;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800309 ScopedLoopMounter b_mounter(state->a_img, &a_mnt, 0);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700310
Darin Petkov8e447e02013-04-16 16:23:50 +0200311 vector<char> hardtocompress;
312 while (hardtocompress.size() < 3 * kBlockSize) {
313 hardtocompress.insert(hardtocompress.end(),
314 kRandomString,
315 kRandomString + sizeof(kRandomString) - 1);
316 }
Alex Vakulenko75039d72014-03-25 12:36:28 -0700317 EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700318 a_mnt.c_str()).c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700319 hardtocompress.data(),
Darin Petkov8e447e02013-04-16 16:23:50 +0200320 hardtocompress.size()));
321
Darin Petkov8a075a72013-04-25 14:46:09 +0200322 vector<char> zeros(16 * 1024, 0);
323 EXPECT_EQ(zeros.size(),
Ben Chan736fcb52014-05-21 18:28:22 -0700324 base::WriteFile(base::FilePath(base::StringPrintf(
325 "%s/move-to-sparse", a_mnt.c_str())),
326 zeros.data(), zeros.size()));
Darin Petkov8a075a72013-04-25 14:46:09 +0200327
328 EXPECT_TRUE(
Alex Vakulenko75039d72014-03-25 12:36:28 -0700329 WriteSparseFile(base::StringPrintf("%s/move-from-sparse",
330 a_mnt.c_str()), 16 * 1024));
Darin Petkov8a075a72013-04-25 14:46:09 +0200331
Alex Vakulenko75039d72014-03-25 12:36:28 -0700332 EXPECT_EQ(0,
333 system(base::StringPrintf("dd if=/dev/zero of=%s/move-semi-sparse"
334 " bs=1 seek=4096 count=1",
Darin Petkov8a075a72013-04-25 14:46:09 +0200335 a_mnt.c_str()).c_str()));
336
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700337 // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
338 // patch fails to zero out the final block.
339 vector<char> ones(1024 * 1024, 0xff);
Alex Vakulenko75039d72014-03-25 12:36:28 -0700340 EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/ones",
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700341 a_mnt.c_str()).c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700342 ones.data(),
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700343 ones.size()));
344 }
345
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700346 if (noop) {
Alex Vakulenko75039d72014-03-25 12:36:28 -0700347 EXPECT_TRUE(base::CopyFile(base::FilePath(state->a_img),
348 base::FilePath(state->b_img)));
Don Garrett0dd39852013-04-03 16:55:42 -0700349 old_image_info = new_image_info;
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700350 } else {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800351 CreateExtImageAtPath(state->b_img, NULL);
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700352 EXPECT_EQ(0, System(base::StringPrintf(
353 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800354 state->b_img.c_str(),
355 state->image_size + 1024 * 1024 - 1)));
356 EXPECT_EQ(state->image_size + 1024 * 1024, utils::FileSize(state->b_img));
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700357
358 // Make some changes to the B image.
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700359 string b_mnt;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800360 ScopedLoopMounter b_mounter(state->b_img, &b_mnt, 0);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700361
Alex Vakulenko75039d72014-03-25 12:36:28 -0700362 EXPECT_EQ(0, system(base::StringPrintf("cp %s/hello %s/hello2",
363 b_mnt.c_str(),
364 b_mnt.c_str()).c_str()));
365 EXPECT_EQ(0, system(base::StringPrintf("rm %s/hello",
366 b_mnt.c_str()).c_str()));
367 EXPECT_EQ(0, system(base::StringPrintf("mv %s/hello2 %s/hello",
368 b_mnt.c_str(),
369 b_mnt.c_str()).c_str()));
370 EXPECT_EQ(0, system(base::StringPrintf("echo foo > %s/foo",
371 b_mnt.c_str()).c_str()));
372 EXPECT_EQ(0, system(base::StringPrintf("touch %s/emptyfile",
373 b_mnt.c_str()).c_str()));
374 EXPECT_TRUE(WriteSparseFile(base::StringPrintf("%s/fullsparse",
375 b_mnt.c_str()),
376 1024 * 1024));
Darin Petkov8a075a72013-04-25 14:46:09 +0200377
378 EXPECT_TRUE(
Alex Vakulenko75039d72014-03-25 12:36:28 -0700379 WriteSparseFile(base::StringPrintf("%s/move-to-sparse", b_mnt.c_str()),
Darin Petkov8a075a72013-04-25 14:46:09 +0200380 16 * 1024));
381
382 vector<char> zeros(16 * 1024, 0);
383 EXPECT_EQ(zeros.size(),
Ben Chan736fcb52014-05-21 18:28:22 -0700384 base::WriteFile(base::FilePath(base::StringPrintf(
385 "%s/move-from-sparse", b_mnt.c_str())),
386 zeros.data(), zeros.size()));
Darin Petkov8a075a72013-04-25 14:46:09 +0200387
Alex Vakulenko75039d72014-03-25 12:36:28 -0700388 EXPECT_EQ(0, system(base::StringPrintf("dd if=/dev/zero "
389 "of=%s/move-semi-sparse "
390 "bs=1 seek=4096 count=1",
391 b_mnt.c_str()).c_str()));
Darin Petkov8a075a72013-04-25 14:46:09 +0200392
Alex Vakulenko75039d72014-03-25 12:36:28 -0700393 EXPECT_EQ(0, system(base::StringPrintf("dd if=/dev/zero "
394 "of=%s/partsparse bs=1 "
395 "seek=4096 count=1",
396 b_mnt.c_str()).c_str()));
397 EXPECT_EQ(0, system(base::StringPrintf("cp %s/srchardlink0 %s/tmp && "
398 "mv %s/tmp %s/srchardlink1",
399 b_mnt.c_str(),
400 b_mnt.c_str(),
401 b_mnt.c_str(),
402 b_mnt.c_str()).c_str()));
403 EXPECT_EQ(0, system(base::StringPrintf("rm %s/boguslink && "
Andrew de los Reyes48a0a482011-02-22 15:32:11 -0800404 "echo foobar > %s/boguslink",
405 b_mnt.c_str(), b_mnt.c_str()).c_str()));
Darin Petkov8e447e02013-04-16 16:23:50 +0200406
407 vector<char> hardtocompress;
408 while (hardtocompress.size() < 3 * kBlockSize) {
409 hardtocompress.insert(hardtocompress.end(),
410 kRandomString,
411 kRandomString + sizeof(kRandomString));
412 }
Alex Vakulenko75039d72014-03-25 12:36:28 -0700413 EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700414 b_mnt.c_str()).c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700415 hardtocompress.data(),
Darin Petkov8e447e02013-04-16 16:23:50 +0200416 hardtocompress.size()));
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700417 }
418
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700419 string old_kernel;
Gilad Arnolda6742b32014-01-11 00:18:34 -0800420 EXPECT_TRUE(utils::MakeTempFile("old_kernel.XXXXXX",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800421 &state->old_kernel,
422 NULL));
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700423
424 string new_kernel;
Gilad Arnolda6742b32014-01-11 00:18:34 -0800425 EXPECT_TRUE(utils::MakeTempFile("new_kernel.XXXXXX",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800426 &state->new_kernel,
427 NULL));
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700428
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800429 state->old_kernel_data.resize(kDefaultKernelSize);
430 state->new_kernel_data.resize(state->old_kernel_data.size());
431 FillWithData(&state->old_kernel_data);
432 FillWithData(&state->new_kernel_data);
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700433
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700434 // change the new kernel data
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800435 strcpy(&state->new_kernel_data[0], kNewDataString);
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700436
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700437 if (noop) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800438 state->old_kernel_data = state->new_kernel_data;
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700439 }
440
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700441 // Write kernels to disk
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800442 EXPECT_TRUE(utils::WriteFile(state->old_kernel.c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700443 state->old_kernel_data.data(),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800444 state->old_kernel_data.size()));
445 EXPECT_TRUE(utils::WriteFile(state->new_kernel.c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700446 state->new_kernel_data.data(),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800447 state->new_kernel_data.size()));
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700448
Gilad Arnolda6742b32014-01-11 00:18:34 -0800449 EXPECT_TRUE(utils::MakeTempFile("delta.XXXXXX",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800450 &state->delta_path,
451 NULL));
452 LOG(INFO) << "delta path: " << state->delta_path;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700453 {
454 string a_mnt, b_mnt;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800455 ScopedLoopMounter a_mounter(state->a_img, &a_mnt, MS_RDONLY);
456 ScopedLoopMounter b_mounter(state->b_img, &b_mnt, MS_RDONLY);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800457 const string private_key =
458 signature_test == kSignatureGenerator ? kUnittestPrivateKeyPath : "";
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700459 EXPECT_TRUE(
Darin Petkov68c10d12010-10-14 09:24:37 -0700460 DeltaDiffGenerator::GenerateDeltaUpdateFile(
Darin Petkov7a22d792010-11-08 14:10:00 -0800461 full_rootfs ? "" : a_mnt,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800462 full_rootfs ? "" : state->a_img,
Darin Petkov68c10d12010-10-14 09:24:37 -0700463 b_mnt,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800464 state->b_img,
465 full_kernel ? "" : state->old_kernel,
466 state->new_kernel,
467 state->delta_path,
468 private_key,
Darin Petkov8e447e02013-04-16 16:23:50 +0200469 chunk_size,
Chris Sosad5ae1562013-04-23 13:20:18 -0700470 kRootFSPartitionSize,
Don Garrett0dd39852013-04-03 16:55:42 -0700471 full_rootfs ? NULL : &old_image_info,
472 &new_image_info,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800473 &state->metadata_size));
Darin Petkov9574f7e2011-01-13 10:48:12 -0800474 }
475
Don Garrett2ae37872013-10-25 13:33:20 -0700476 if (signature_test == kSignatureGeneratedPlaceholder ||
477 signature_test == kSignatureGeneratedPlaceholderMismatch) {
478
479 int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
480 LOG(INFO) << "Inserting placeholder signature.";
481 ASSERT_TRUE(InsertSignaturePlaceholder(signature_size, state->delta_path,
482 &state->metadata_size));
483
484 if (signature_test == kSignatureGeneratedPlaceholderMismatch) {
485 signature_size -= 1;
486 LOG(INFO) << "Inserting mismatched placeholder signature.";
487 ASSERT_FALSE(InsertSignaturePlaceholder(signature_size, state->delta_path,
488 &state->metadata_size));
489 return;
490 }
491 }
492
493 if (signature_test == kSignatureGenerated ||
494 signature_test == kSignatureGeneratedPlaceholder ||
495 signature_test == kSignatureGeneratedPlaceholderMismatch) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800496 // Generate the signed payload and update the metadata size in state to
497 // reflect the new size after adding the signature operation to the
498 // manifest.
Don Garrett2ae37872013-10-25 13:33:20 -0700499 LOG(INFO) << "Signing payload.";
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800500 SignGeneratedPayload(state->delta_path, &state->metadata_size);
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800501 } else if (signature_test == kSignatureGeneratedShell ||
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700502 signature_test == kSignatureGeneratedShellBadKey ||
503 signature_test == kSignatureGeneratedShellRotateCl1 ||
504 signature_test == kSignatureGeneratedShellRotateCl2) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800505 SignGeneratedShellPayload(signature_test, state->delta_path);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700506 }
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800507}
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700508
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800509static void ApplyDeltaFile(bool full_kernel, bool full_rootfs, bool noop,
510 SignatureTest signature_test, DeltaState* state,
511 bool hash_checks_mandatory,
512 OperationHashTest op_hash_test,
513 DeltaPerformer** performer) {
Darin Petkov36a58222010-10-07 22:00:09 -0700514 // Check the metadata.
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700515 {
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700516 DeltaArchiveManifest manifest;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800517 EXPECT_TRUE(PayloadSigner::LoadPayload(state->delta_path,
518 &state->delta,
519 &manifest,
520 &state->metadata_size));
521 LOG(INFO) << "Metadata size: " << state->metadata_size;
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700522
Don Garrett0dd39852013-04-03 16:55:42 -0700523
524
Darin Petkovcbfb0172011-01-14 15:24:45 -0800525 if (signature_test == kSignatureNone) {
526 EXPECT_FALSE(manifest.has_signatures_offset());
527 EXPECT_FALSE(manifest.has_signatures_size());
528 } else {
529 EXPECT_TRUE(manifest.has_signatures_offset());
530 EXPECT_TRUE(manifest.has_signatures_size());
531 Signatures sigs_message;
532 EXPECT_TRUE(sigs_message.ParseFromArray(
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800533 &state->delta[state->metadata_size + manifest.signatures_offset()],
Darin Petkovcbfb0172011-01-14 15:24:45 -0800534 manifest.signatures_size()));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700535 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
536 signature_test == kSignatureGeneratedShellRotateCl2)
537 EXPECT_EQ(2, sigs_message.signatures_size());
538 else
539 EXPECT_EQ(1, sigs_message.signatures_size());
Darin Petkovcbfb0172011-01-14 15:24:45 -0800540 const Signatures_Signature& signature = sigs_message.signatures(0);
541 EXPECT_EQ(1, signature.version());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700542
Darin Petkovcbfb0172011-01-14 15:24:45 -0800543 uint64_t expected_sig_data_length = 0;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700544 vector<string> key_paths (1, kUnittestPrivateKeyPath);
545 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
546 signature_test == kSignatureGeneratedShellRotateCl2) {
547 key_paths.push_back(kUnittestPrivateKey2Path);
548 }
Darin Petkovcbfb0172011-01-14 15:24:45 -0800549 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700550 key_paths,
551 &expected_sig_data_length));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800552 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
553 EXPECT_FALSE(signature.data().empty());
554 }
Darin Petkov36a58222010-10-07 22:00:09 -0700555
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700556 if (noop) {
557 EXPECT_EQ(1, manifest.install_operations_size());
558 EXPECT_EQ(1, manifest.kernel_install_operations_size());
559 }
560
Darin Petkovd43d6902010-10-14 11:17:50 -0700561 if (full_kernel) {
562 EXPECT_FALSE(manifest.has_old_kernel_info());
563 } else {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800564 EXPECT_EQ(state->old_kernel_data.size(),
565 manifest.old_kernel_info().size());
Darin Petkovd43d6902010-10-14 11:17:50 -0700566 EXPECT_FALSE(manifest.old_kernel_info().hash().empty());
567 }
Darin Petkov698d0412010-10-13 10:59:44 -0700568
Don Garrett0dd39852013-04-03 16:55:42 -0700569 EXPECT_EQ(manifest.new_image_info().channel(), "test-channel");
570 EXPECT_EQ(manifest.new_image_info().board(), "test-board");
571 EXPECT_EQ(manifest.new_image_info().version(), "test-version");
572 EXPECT_EQ(manifest.new_image_info().key(), "test-key");
573 EXPECT_EQ(manifest.new_image_info().build_channel(), "test-build-channel");
574 EXPECT_EQ(manifest.new_image_info().build_version(), "test-build-version");
575
576 if (!full_rootfs) {
577
578 if (noop) {
579 EXPECT_EQ(manifest.old_image_info().channel(), "test-channel");
580 EXPECT_EQ(manifest.old_image_info().board(), "test-board");
581 EXPECT_EQ(manifest.old_image_info().version(), "test-version");
582 EXPECT_EQ(manifest.old_image_info().key(), "test-key");
583 EXPECT_EQ(manifest.old_image_info().build_channel(),
584 "test-build-channel");
585 EXPECT_EQ(manifest.old_image_info().build_version(),
586 "test-build-version");
587 } else {
588 EXPECT_EQ(manifest.old_image_info().channel(), "src-channel");
589 EXPECT_EQ(manifest.old_image_info().board(), "src-board");
590 EXPECT_EQ(manifest.old_image_info().version(), "src-version");
591 EXPECT_EQ(manifest.old_image_info().key(), "src-key");
592 EXPECT_EQ(manifest.old_image_info().build_channel(),
593 "src-build-channel");
594 EXPECT_EQ(manifest.old_image_info().build_version(),
595 "src-build-version");
596 }
597 }
598
599
Darin Petkov7a22d792010-11-08 14:10:00 -0800600 if (full_rootfs) {
601 EXPECT_FALSE(manifest.has_old_rootfs_info());
Don Garrett0dd39852013-04-03 16:55:42 -0700602 EXPECT_FALSE(manifest.has_old_image_info());
603 EXPECT_TRUE(manifest.has_new_image_info());
Darin Petkov7a22d792010-11-08 14:10:00 -0800604 } else {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800605 EXPECT_EQ(state->image_size, manifest.old_rootfs_info().size());
Darin Petkov7a22d792010-11-08 14:10:00 -0800606 EXPECT_FALSE(manifest.old_rootfs_info().hash().empty());
607 }
608
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800609 EXPECT_EQ(state->new_kernel_data.size(), manifest.new_kernel_info().size());
610 EXPECT_EQ(state->image_size, manifest.new_rootfs_info().size());
Darin Petkov36a58222010-10-07 22:00:09 -0700611
Darin Petkov36a58222010-10-07 22:00:09 -0700612 EXPECT_FALSE(manifest.new_kernel_info().hash().empty());
Darin Petkov36a58222010-10-07 22:00:09 -0700613 EXPECT_FALSE(manifest.new_rootfs_info().hash().empty());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700614 }
615
Darin Petkov73058b42010-10-06 16:32:19 -0700616 PrefsMock prefs;
617 EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800618 state->metadata_size)).WillOnce(Return(true));
Darin Petkov73058b42010-10-06 16:32:19 -0700619 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
620 .WillRepeatedly(Return(true));
Darin Petkov9b230572010-10-08 10:20:09 -0700621 EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
622 .WillOnce(Return(false));
Darin Petkov73058b42010-10-06 16:32:19 -0700623 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
624 .WillRepeatedly(Return(true));
David Zeuthen41996ad2013-09-24 15:43:24 -0700625 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataLength, _))
626 .WillRepeatedly(Return(true));
Darin Petkov437adc42010-10-07 13:12:24 -0700627 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
Darin Petkov73058b42010-10-06 16:32:19 -0700628 .WillRepeatedly(Return(true));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800629 if (op_hash_test == kValidOperationData && signature_test != kSignatureNone) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800630 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
631 .WillOnce(Return(true));
Darin Petkov4f0a07b2011-05-25 16:47:20 -0700632 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
633 .WillOnce(Return(true));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800634 }
Darin Petkov73058b42010-10-06 16:32:19 -0700635
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700636 // Update the A image in place.
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700637 InstallPlan install_plan;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800638 install_plan.hash_checks_mandatory = hash_checks_mandatory;
639 install_plan.metadata_size = state->metadata_size;
Don Garrettb8dd1d92013-11-22 17:40:02 -0800640 install_plan.is_full_update = full_kernel && full_rootfs;
641
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800642 LOG(INFO) << "Setting payload metadata size in Omaha = "
643 << state->metadata_size;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700644 ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
Alex Vakulenko75039d72014-03-25 12:36:28 -0700645 state->delta.data(),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800646 state->metadata_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700647 kUnittestPrivateKeyPath,
Jay Srinivasanf4318702012-09-24 11:56:24 -0700648 &install_plan.metadata_signature));
649 EXPECT_FALSE(install_plan.metadata_signature.empty());
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700650
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800651 *performer = new DeltaPerformer(&prefs,
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700652 &state->fake_system_state,
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800653 &install_plan);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700654 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800655 (*performer)->set_public_key_path(kUnittestPublicKeyPath);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700656
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800657 EXPECT_EQ(state->image_size,
658 OmahaHashCalculator::RawHashOfFile(state->a_img,
659 state->image_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700660 &install_plan.rootfs_hash));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800661 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(state->old_kernel_data,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700662 &install_plan.kernel_hash));
663
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800664 EXPECT_EQ(0, (*performer)->Open(state->a_img.c_str(), 0, 0));
665 EXPECT_TRUE((*performer)->OpenKernel(state->old_kernel.c_str()));
666
David Zeuthena99981f2013-04-29 13:42:47 -0700667 ErrorCode expected_error, actual_error;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800668 bool continue_writing;
669 switch(op_hash_test) {
670 case kInvalidOperationData: {
671 // Muck with some random offset post the metadata size so that
672 // some operation hash will result in a mismatch.
673 int some_offset = state->metadata_size + 300;
674 LOG(INFO) << "Tampered value at offset: " << some_offset;
675 state->delta[some_offset]++;
David Zeuthena99981f2013-04-29 13:42:47 -0700676 expected_error = kErrorCodeDownloadOperationHashMismatch;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800677 continue_writing = false;
678 break;
679 }
680
681 case kValidOperationData:
682 default:
683 // no change.
David Zeuthena99981f2013-04-29 13:42:47 -0700684 expected_error = kErrorCodeSuccess;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800685 continue_writing = true;
686 break;
687 }
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700688
689 // Write at some number of bytes per operation. Arbitrarily chose 5.
690 const size_t kBytesPerWrite = 5;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800691 for (size_t i = 0; i < state->delta.size(); i += kBytesPerWrite) {
692 size_t count = min(state->delta.size() - i, kBytesPerWrite);
693 bool write_succeeded = ((*performer)->Write(&state->delta[i],
694 count,
695 &actual_error));
696 // Normally write_succeeded should be true every time and
David Zeuthena99981f2013-04-29 13:42:47 -0700697 // actual_error should be kErrorCodeSuccess. If so, continue the loop.
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800698 // But if we seeded an operation hash error above, then write_succeeded
699 // will be false. The failure may happen at any operation n. So, all
700 // Writes until n-1 should succeed and the nth operation will fail with
701 // actual_error. In this case, we should bail out of the loop because
702 // we cannot proceed applying the delta.
703 if (!write_succeeded) {
704 LOG(INFO) << "Write failed. Checking if it failed with expected error";
705 EXPECT_EQ(expected_error, actual_error);
706 if (!continue_writing) {
707 LOG(INFO) << "Cannot continue writing. Bailing out.";
708 break;
709 }
710 }
711
David Zeuthena99981f2013-04-29 13:42:47 -0700712 EXPECT_EQ(kErrorCodeSuccess, actual_error);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700713 }
714
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800715 // If we had continued all the way through, Close should succeed.
716 // Otherwise, it should fail. Check appropriately.
717 bool close_result = (*performer)->Close();
718 if (continue_writing)
719 EXPECT_EQ(0, close_result);
720 else
721 EXPECT_LE(0, close_result);
722}
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700723
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800724void VerifyPayloadResult(DeltaPerformer* performer,
725 DeltaState* state,
David Zeuthena99981f2013-04-29 13:42:47 -0700726 ErrorCode expected_result) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800727 if (!performer) {
728 EXPECT_TRUE(!"Skipping payload verification since performer is NULL.");
729 return;
730 }
731
David Zeuthena99981f2013-04-29 13:42:47 -0700732 int expected_times = (expected_result == kErrorCodeSuccess) ? 1 : 0;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700733 EXPECT_CALL(*(state->fake_system_state.mock_payload_state()),
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800734 DownloadComplete()).Times(expected_times);
735
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800736 LOG(INFO) << "Verifying payload for expected result "
737 << expected_result;
738 EXPECT_EQ(expected_result, performer->VerifyPayload(
739 OmahaHashCalculator::OmahaHashOfData(state->delta),
740 state->delta.size()));
741 LOG(INFO) << "Verified payload.";
742
David Zeuthena99981f2013-04-29 13:42:47 -0700743 if (expected_result != kErrorCodeSuccess) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800744 // no need to verify new partition if VerifyPayload failed.
745 return;
746 }
747
748 CompareFilesByBlock(state->old_kernel, state->new_kernel);
749 CompareFilesByBlock(state->a_img, state->b_img);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700750
751 vector<char> updated_kernel_partition;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800752 EXPECT_TRUE(utils::ReadFile(state->old_kernel, &updated_kernel_partition));
Alex Vakulenko75039d72014-03-25 12:36:28 -0700753 EXPECT_EQ(0, strncmp(updated_kernel_partition.data(), kNewDataString,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800754 strlen(kNewDataString)));
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700755
756 uint64_t new_kernel_size;
757 vector<char> new_kernel_hash;
758 uint64_t new_rootfs_size;
759 vector<char> new_rootfs_hash;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800760 EXPECT_TRUE(performer->GetNewPartitionInfo(&new_kernel_size,
Don Garrett0dd39852013-04-03 16:55:42 -0700761 &new_kernel_hash,
762 &new_rootfs_size,
763 &new_rootfs_hash));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800764 EXPECT_EQ(kDefaultKernelSize, new_kernel_size);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700765 vector<char> expected_new_kernel_hash;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800766 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(state->new_kernel_data,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700767 &expected_new_kernel_hash));
768 EXPECT_TRUE(expected_new_kernel_hash == new_kernel_hash);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800769 EXPECT_EQ(state->image_size, new_rootfs_size);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700770 vector<char> expected_new_rootfs_hash;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800771 EXPECT_EQ(state->image_size,
772 OmahaHashCalculator::RawHashOfFile(state->b_img,
773 state->image_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700774 &expected_new_rootfs_hash));
775 EXPECT_TRUE(expected_new_rootfs_hash == new_rootfs_hash);
776}
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800777
778void VerifyPayload(DeltaPerformer* performer,
779 DeltaState* state,
780 SignatureTest signature_test) {
David Zeuthena99981f2013-04-29 13:42:47 -0700781 ErrorCode expected_result = kErrorCodeSuccess;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800782 switch (signature_test) {
783 case kSignatureNone:
David Zeuthena99981f2013-04-29 13:42:47 -0700784 expected_result = kErrorCodeSignedDeltaPayloadExpectedError;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800785 break;
786 case kSignatureGeneratedShellBadKey:
David Zeuthena99981f2013-04-29 13:42:47 -0700787 expected_result = kErrorCodeDownloadPayloadPubKeyVerificationError;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800788 break;
789 default: break; // appease gcc
790 }
791
792 VerifyPayloadResult(performer, state, expected_result);
793}
794
795void DoSmallImageTest(bool full_kernel, bool full_rootfs, bool noop,
Darin Petkov8e447e02013-04-16 16:23:50 +0200796 off_t chunk_size,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800797 SignatureTest signature_test,
798 bool hash_checks_mandatory) {
799 DeltaState state;
Alex Deymo52146ce2014-05-29 11:09:45 -0700800 DeltaPerformer *performer = nullptr;
Darin Petkov8e447e02013-04-16 16:23:50 +0200801 GenerateDeltaFile(full_kernel, full_rootfs, noop, chunk_size,
802 signature_test, &state);
Don Garrett0dd39852013-04-03 16:55:42 -0700803
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800804 ScopedPathUnlinker a_img_unlinker(state.a_img);
805 ScopedPathUnlinker b_img_unlinker(state.b_img);
806 ScopedPathUnlinker delta_unlinker(state.delta_path);
807 ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
808 ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
809 ApplyDeltaFile(full_kernel, full_rootfs, noop, signature_test,
810 &state, hash_checks_mandatory, kValidOperationData,
811 &performer);
812 VerifyPayload(performer, &state, signature_test);
Alex Deymo52146ce2014-05-29 11:09:45 -0700813 delete performer;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800814}
815
816// Calls delta performer's Write method by pretending to pass in bytes from a
817// delta file whose metadata size is actual_metadata_size and tests if all
818// checks are correctly performed if the install plan contains
819// expected_metadata_size and that the result of the parsing are as per
820// hash_checks_mandatory flag.
821void DoMetadataSizeTest(uint64_t expected_metadata_size,
822 uint64_t actual_metadata_size,
823 bool hash_checks_mandatory) {
824 PrefsMock prefs;
825 InstallPlan install_plan;
826 install_plan.hash_checks_mandatory = hash_checks_mandatory;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700827 FakeSystemState fake_system_state;
828 DeltaPerformer performer(&prefs, &fake_system_state, &install_plan);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800829 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0));
830 EXPECT_TRUE(performer.OpenKernel("/dev/null"));
831
832 // Set a valid magic string and version number 1.
833 EXPECT_TRUE(performer.Write("CrAU", 4));
834 uint64_t version = htobe64(1);
835 EXPECT_TRUE(performer.Write(&version, 8));
836
837 install_plan.metadata_size = expected_metadata_size;
David Zeuthena99981f2013-04-29 13:42:47 -0700838 ErrorCode error_code;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800839 // When filling in size in manifest, exclude the size of the 20-byte header.
840 uint64_t size_in_manifest = htobe64(actual_metadata_size - 20);
841 bool result = performer.Write(&size_in_manifest, 8, &error_code);
842 if (expected_metadata_size == actual_metadata_size ||
843 !hash_checks_mandatory) {
844 EXPECT_TRUE(result);
845 } else {
846 EXPECT_FALSE(result);
David Zeuthena99981f2013-04-29 13:42:47 -0700847 EXPECT_EQ(kErrorCodeDownloadInvalidMetadataSize, error_code);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800848 }
849
850 EXPECT_LT(performer.Close(), 0);
851}
852
853// Generates a valid delta file but tests the delta performer by suppling
854// different metadata signatures as per omaha_metadata_signature flag and
855// sees if the result of the parsing are as per hash_checks_mandatory flag.
856void DoMetadataSignatureTest(MetadataSignatureTest metadata_signature_test,
857 SignatureTest signature_test,
858 bool hash_checks_mandatory) {
859 DeltaState state;
860
861 // Using kSignatureNone since it doesn't affect the results of our test.
862 // If we've to use other signature options, then we'd have to get the
863 // metadata size again after adding the signing operation to the manifest.
Darin Petkov8e447e02013-04-16 16:23:50 +0200864 GenerateDeltaFile(true, true, false, -1, signature_test, &state);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800865
866 ScopedPathUnlinker a_img_unlinker(state.a_img);
867 ScopedPathUnlinker b_img_unlinker(state.b_img);
868 ScopedPathUnlinker delta_unlinker(state.delta_path);
869 ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
870 ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
871
872 // Loads the payload and parses the manifest.
873 vector<char> payload;
874 EXPECT_TRUE(utils::ReadFile(state.delta_path, &payload));
875 LOG(INFO) << "Payload size: " << payload.size();
876
877 InstallPlan install_plan;
878 install_plan.hash_checks_mandatory = hash_checks_mandatory;
879 install_plan.metadata_size = state.metadata_size;
880
881 DeltaPerformer::MetadataParseResult expected_result, actual_result;
David Zeuthena99981f2013-04-29 13:42:47 -0700882 ErrorCode expected_error, actual_error;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800883
884 // Fill up the metadata signature in install plan according to the test.
885 switch (metadata_signature_test) {
886 case kEmptyMetadataSignature:
887 install_plan.metadata_signature.clear();
888 expected_result = DeltaPerformer::kMetadataParseError;
David Zeuthena99981f2013-04-29 13:42:47 -0700889 expected_error = kErrorCodeDownloadMetadataSignatureMissingError;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800890 break;
891
892 case kInvalidMetadataSignature:
893 install_plan.metadata_signature = kBogusMetadataSignature1;
894 expected_result = DeltaPerformer::kMetadataParseError;
David Zeuthena99981f2013-04-29 13:42:47 -0700895 expected_error = kErrorCodeDownloadMetadataSignatureMismatch;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800896 break;
897
898 case kValidMetadataSignature:
899 default:
900 // Set the install plan's metadata size to be the same as the one
901 // in the manifest so that we pass the metadata size checks. Only
902 // then we can get to manifest signature checks.
903 ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
Alex Vakulenko75039d72014-03-25 12:36:28 -0700904 payload.data(),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800905 state.metadata_size,
906 kUnittestPrivateKeyPath,
907 &install_plan.metadata_signature));
908 EXPECT_FALSE(install_plan.metadata_signature.empty());
909 expected_result = DeltaPerformer::kMetadataParseSuccess;
David Zeuthena99981f2013-04-29 13:42:47 -0700910 expected_error = kErrorCodeSuccess;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800911 break;
912 }
913
914 // Ignore the expected result/error if hash checks are not mandatory.
915 if (!hash_checks_mandatory) {
916 expected_result = DeltaPerformer::kMetadataParseSuccess;
David Zeuthena99981f2013-04-29 13:42:47 -0700917 expected_error = kErrorCodeSuccess;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800918 }
919
920 // Create the delta performer object.
921 PrefsMock prefs;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800922 DeltaPerformer delta_performer(&prefs,
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700923 &state.fake_system_state,
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800924 &install_plan);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800925
926 // Use the public key corresponding to the private key used above to
927 // sign the metadata.
928 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
929 delta_performer.set_public_key_path(kUnittestPublicKeyPath);
930
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800931 // Init actual_error with an invalid value so that we make sure
932 // ParsePayloadMetadata properly populates it in all cases.
David Zeuthena99981f2013-04-29 13:42:47 -0700933 actual_error = kErrorCodeUmaReportedMax;
Gilad Arnolddaa27402014-01-23 11:56:17 -0800934 actual_result = delta_performer.ParsePayloadMetadata(payload, &actual_error);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800935
936 EXPECT_EQ(expected_result, actual_result);
937 EXPECT_EQ(expected_error, actual_error);
938
939 // Check that the parsed metadata size is what's expected. This test
940 // implicitly confirms that the metadata signature is valid, if required.
Gilad Arnoldfe133932014-01-14 12:25:50 -0800941 EXPECT_EQ(state.metadata_size, delta_performer.GetMetadataSize());
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800942}
943
944void DoOperationHashMismatchTest(OperationHashTest op_hash_test,
945 bool hash_checks_mandatory) {
946 DeltaState state;
Darin Petkov8e447e02013-04-16 16:23:50 +0200947 GenerateDeltaFile(true, true, false, -1, kSignatureGenerated, &state);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800948 ScopedPathUnlinker a_img_unlinker(state.a_img);
949 ScopedPathUnlinker b_img_unlinker(state.b_img);
950 ScopedPathUnlinker delta_unlinker(state.delta_path);
951 ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
952 ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
Alex Deymo52146ce2014-05-29 11:09:45 -0700953 DeltaPerformer *performer = nullptr;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800954 ApplyDeltaFile(true, true, false, kSignatureGenerated,
955 &state, hash_checks_mandatory, op_hash_test, &performer);
Alex Deymo52146ce2014-05-29 11:09:45 -0700956 delete performer;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800957}
958
Don Garrettb8dd1d92013-11-22 17:40:02 -0800959
960class DeltaPerformerTest : public ::testing::Test {
961
962 public:
963 // Test helper placed where it can easily be friended from DeltaPerformer.
964 static void RunManifestValidation(DeltaArchiveManifest& manifest,
965 bool full_payload,
966 ErrorCode expected) {
967 PrefsMock prefs;
968 InstallPlan install_plan;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700969 FakeSystemState fake_system_state;
970 DeltaPerformer performer(&prefs, &fake_system_state, &install_plan);
Don Garrettb8dd1d92013-11-22 17:40:02 -0800971
972 // The install plan is for Full or Delta.
973 install_plan.is_full_update = full_payload;
974
975 // The Manifest we are validating.
976 performer.manifest_.CopyFrom(manifest);
977
978 EXPECT_EQ(expected, performer.ValidateManifest());
979 }
980};
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800981
982TEST(DeltaPerformerTest, ExtentsToByteStringTest) {
983 uint64_t test[] = {1, 1, 4, 2, kSparseHole, 1, 0, 1};
984 COMPILE_ASSERT(arraysize(test) % 2 == 0, array_size_uneven);
985 const uint64_t block_size = 4096;
986 const uint64_t file_length = 5 * block_size - 13;
987
988 google::protobuf::RepeatedPtrField<Extent> extents;
989 for (size_t i = 0; i < arraysize(test); i += 2) {
990 Extent* extent = extents.Add();
991 extent->set_start_block(test[i]);
992 extent->set_num_blocks(test[i + 1]);
993 }
994
995 string expected_output = "4096:4096,16384:8192,-1:4096,0:4083";
996 string actual_output;
997 EXPECT_TRUE(DeltaPerformer::ExtentsToBsdiffPositionsString(extents,
998 block_size,
999 file_length,
1000 &actual_output));
1001 EXPECT_EQ(expected_output, actual_output);
1002}
Darin Petkov68c10d12010-10-14 09:24:37 -07001003
Don Garrettb8dd1d92013-11-22 17:40:02 -08001004TEST(DeltaPerformerTest, ValidateManifestFullGoodTest) {
1005 // The Manifest we are validating.
1006 DeltaArchiveManifest manifest;
1007 manifest.mutable_new_kernel_info();
1008 manifest.mutable_new_rootfs_info();
1009 manifest.set_minor_version(DeltaPerformer::kFullPayloadMinorVersion);
1010
1011 DeltaPerformerTest::RunManifestValidation(manifest, true, kErrorCodeSuccess);
1012}
1013
1014TEST(DeltaPerformerTest, ValidateManifestDeltaGoodTest) {
1015 // The Manifest we are validating.
1016 DeltaArchiveManifest manifest;
1017 manifest.mutable_old_kernel_info();
1018 manifest.mutable_old_rootfs_info();
1019 manifest.mutable_new_kernel_info();
1020 manifest.mutable_new_rootfs_info();
1021 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
1022
1023 DeltaPerformerTest::RunManifestValidation(manifest, false, kErrorCodeSuccess);
1024}
1025
1026TEST(DeltaPerformerTest, ValidateManifestFullUnsetMinorVersion) {
1027 // The Manifest we are validating.
1028 DeltaArchiveManifest manifest;
1029
1030 DeltaPerformerTest::RunManifestValidation(manifest, true, kErrorCodeSuccess);
1031}
1032
1033TEST(DeltaPerformerTest, ValidateManifestDeltaUnsetMinorVersion) {
1034 // The Manifest we are validating.
1035 DeltaArchiveManifest manifest;
1036
1037 DeltaPerformerTest::RunManifestValidation(
1038 manifest, false,
1039 kErrorCodeUnsupportedMinorPayloadVersion);
1040}
1041
1042TEST(DeltaPerformerTest, ValidateManifestFullOldKernelTest) {
1043 // The Manifest we are validating.
1044 DeltaArchiveManifest manifest;
1045 manifest.mutable_old_kernel_info();
1046 manifest.mutable_new_kernel_info();
1047 manifest.mutable_new_rootfs_info();
1048 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
1049
1050 DeltaPerformerTest::RunManifestValidation(
1051 manifest, true,
1052 kErrorCodePayloadMismatchedType);
1053}
1054
1055TEST(DeltaPerformerTest, ValidateManifestFullOldRootfsTest) {
1056 // The Manifest we are validating.
1057 DeltaArchiveManifest manifest;
1058 manifest.mutable_old_rootfs_info();
1059 manifest.mutable_new_kernel_info();
1060 manifest.mutable_new_rootfs_info();
1061 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
1062
1063 DeltaPerformerTest::RunManifestValidation(
1064 manifest, true,
1065 kErrorCodePayloadMismatchedType);
1066}
1067
1068TEST(DeltaPerformerTest, ValidateManifestBadMinorVersion) {
1069 // The Manifest we are validating.
1070 DeltaArchiveManifest manifest;
1071
1072 // Generate a bad version number.
1073 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion +
1074 10000);
1075
1076 DeltaPerformerTest::RunManifestValidation(
1077 manifest, false,
1078 kErrorCodeUnsupportedMinorPayloadVersion);
1079}
1080
Darin Petkov68c10d12010-10-14 09:24:37 -07001081TEST(DeltaPerformerTest, RunAsRootSmallImageTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001082 DoSmallImageTest(false, false, false, -1, kSignatureGenerator,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001083 false);
Darin Petkov8e447e02013-04-16 16:23:50 +02001084}
1085
Don Garrett2ae37872013-10-25 13:33:20 -07001086TEST(DeltaPerformerTest, RunAsRootSmallImageSignaturePlaceholderTest) {
1087 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedPlaceholder,
1088 false);
1089}
1090
1091TEST(DeltaPerformerTest, RunAsRootSmallImageSignaturePlaceholderMismatchTest) {
1092 DeltaState state;
1093 GenerateDeltaFile(false, false, false, -1,
1094 kSignatureGeneratedPlaceholderMismatch, &state);
1095}
1096
Darin Petkov8e447e02013-04-16 16:23:50 +02001097TEST(DeltaPerformerTest, RunAsRootSmallImageChunksTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001098 DoSmallImageTest(false, false, false, kBlockSize, kSignatureGenerator,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001099 false);
Darin Petkov68c10d12010-10-14 09:24:37 -07001100}
1101
1102TEST(DeltaPerformerTest, RunAsRootFullKernelSmallImageTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001103 DoSmallImageTest(true, false, false, -1, kSignatureGenerator,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001104 false);
Darin Petkov7a22d792010-11-08 14:10:00 -08001105}
1106
1107TEST(DeltaPerformerTest, RunAsRootFullSmallImageTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001108 DoSmallImageTest(true, true, false, -1, kSignatureGenerator,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001109 true);
Darin Petkov9fa7ec52010-10-18 11:45:23 -07001110}
1111
1112TEST(DeltaPerformerTest, RunAsRootNoopSmallImageTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001113 DoSmallImageTest(false, false, true, -1, kSignatureGenerator,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001114 false);
Darin Petkov9574f7e2011-01-13 10:48:12 -08001115}
1116
Darin Petkovcbfb0172011-01-14 15:24:45 -08001117TEST(DeltaPerformerTest, RunAsRootSmallImageSignNoneTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001118 DoSmallImageTest(false, false, false, -1, kSignatureNone,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001119 false);
Darin Petkovcbfb0172011-01-14 15:24:45 -08001120}
1121
1122TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001123 DoSmallImageTest(false, false, false, -1, kSignatureGenerated,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001124 true);
Darin Petkovcbfb0172011-01-14 15:24:45 -08001125}
1126
1127TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001128 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShell,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001129 false);
Andrew de los Reyes27f7d372010-10-07 11:26:07 -07001130}
1131
Darin Petkov52dcaeb2011-01-14 15:33:06 -08001132TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellBadKeyTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001133 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellBadKey,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001134 false);
Darin Petkov52dcaeb2011-01-14 15:33:06 -08001135}
1136
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -07001137TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellRotateCl1Test) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001138 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellRotateCl1,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001139 false);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -07001140}
1141
1142TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellRotateCl2Test) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001143 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellRotateCl2,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001144 false);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -07001145}
1146
Darin Petkov934bb412010-11-18 11:21:35 -08001147TEST(DeltaPerformerTest, BadDeltaMagicTest) {
1148 PrefsMock prefs;
Jay Srinivasan51dcf262012-09-13 17:24:32 -07001149 InstallPlan install_plan;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001150 FakeSystemState fake_system_state;
1151 DeltaPerformer performer(&prefs, &fake_system_state, &install_plan);
Darin Petkov934bb412010-11-18 11:21:35 -08001152 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0));
1153 EXPECT_TRUE(performer.OpenKernel("/dev/null"));
Don Garrette410e0f2011-11-10 15:39:01 -08001154 EXPECT_TRUE(performer.Write("junk", 4));
1155 EXPECT_TRUE(performer.Write("morejunk", 8));
1156 EXPECT_FALSE(performer.Write("morejunk", 8));
Darin Petkov934bb412010-11-18 11:21:35 -08001157 EXPECT_LT(performer.Close(), 0);
1158}
1159
Andrew de los Reyes353777c2010-10-08 10:34:30 -07001160TEST(DeltaPerformerTest, IsIdempotentOperationTest) {
1161 DeltaArchiveManifest_InstallOperation op;
1162 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
1163 *(op.add_dst_extents()) = ExtentForRange(0, 5);
1164 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
1165 *(op.add_src_extents()) = ExtentForRange(4, 1);
1166 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
1167 op.clear_src_extents();
1168 *(op.add_src_extents()) = ExtentForRange(5, 3);
1169 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
1170 *(op.add_dst_extents()) = ExtentForRange(20, 6);
1171 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
1172 *(op.add_src_extents()) = ExtentForRange(19, 2);
1173 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
1174}
1175
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001176TEST(DeltaPerformerTest, WriteUpdatesPayloadState) {
1177 PrefsMock prefs;
1178 InstallPlan install_plan;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001179 FakeSystemState fake_system_state;
1180 DeltaPerformer performer(&prefs, &fake_system_state, &install_plan);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001181 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0));
1182 EXPECT_TRUE(performer.OpenKernel("/dev/null"));
1183
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001184 EXPECT_CALL(*(fake_system_state.mock_payload_state()),
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001185 DownloadProgress(4)).Times(1);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001186 EXPECT_CALL(*(fake_system_state.mock_payload_state()),
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001187 DownloadProgress(8)).Times(2);
1188
1189 EXPECT_TRUE(performer.Write("junk", 4));
1190 EXPECT_TRUE(performer.Write("morejunk", 8));
1191 EXPECT_FALSE(performer.Write("morejunk", 8));
1192 EXPECT_LT(performer.Close(), 0);
1193}
1194
Jay Srinivasan738fdf32012-12-07 17:40:54 -08001195TEST(DeltaPerformerTest, MissingMandatoryMetadataSizeTest) {
1196 DoMetadataSizeTest(0, 75456, true);
Jay Srinivasan51dcf262012-09-13 17:24:32 -07001197}
1198
Jay Srinivasan738fdf32012-12-07 17:40:54 -08001199TEST(DeltaPerformerTest, MissingNonMandatoryMetadataSizeTest) {
1200 DoMetadataSizeTest(0, 123456, false);
1201}
1202
1203TEST(DeltaPerformerTest, InvalidMandatoryMetadataSizeTest) {
1204 DoMetadataSizeTest(13000, 140000, true);
1205}
1206
1207TEST(DeltaPerformerTest, InvalidNonMandatoryMetadataSizeTest) {
1208 DoMetadataSizeTest(40000, 50000, false);
1209}
1210
1211TEST(DeltaPerformerTest, ValidMandatoryMetadataSizeTest) {
1212 DoMetadataSizeTest(85376, 85376, true);
1213}
1214
1215TEST(DeltaPerformerTest, RunAsRootMandatoryEmptyMetadataSignatureTest) {
1216 DoMetadataSignatureTest(kEmptyMetadataSignature, kSignatureGenerated, true);
1217}
1218
1219TEST(DeltaPerformerTest, RunAsRootNonMandatoryEmptyMetadataSignatureTest) {
1220 DoMetadataSignatureTest(kEmptyMetadataSignature, kSignatureGenerated, false);
1221}
1222
1223TEST(DeltaPerformerTest, RunAsRootMandatoryInvalidMetadataSignatureTest) {
1224 DoMetadataSignatureTest(kInvalidMetadataSignature, kSignatureGenerated, true);
1225}
1226
1227TEST(DeltaPerformerTest, RunAsRootNonMandatoryInvalidMetadataSignatureTest) {
1228 DoMetadataSignatureTest(kInvalidMetadataSignature, kSignatureGenerated,
1229 false);
1230}
1231
1232TEST(DeltaPerformerTest, RunAsRootMandatoryValidMetadataSignature1Test) {
1233 DoMetadataSignatureTest(kValidMetadataSignature, kSignatureNone, true);
1234}
1235
1236TEST(DeltaPerformerTest, RunAsRootMandatoryValidMetadataSignature2Test) {
1237 DoMetadataSignatureTest(kValidMetadataSignature, kSignatureGenerated, true);
1238}
1239
1240TEST(DeltaPerformerTest, RunAsRootNonMandatoryValidMetadataSignatureTest) {
1241 DoMetadataSignatureTest(kValidMetadataSignature, kSignatureGenerated, false);
1242}
1243
1244TEST(DeltaPerformerTest, RunAsRootMandatoryOperationHashMismatchTest) {
1245 DoOperationHashMismatchTest(kInvalidOperationData, true);
1246}
Jay Srinivasan51dcf262012-09-13 17:24:32 -07001247
David Zeuthene7f89172013-10-31 10:21:04 -07001248TEST(DeltaPerformerTest, UsePublicKeyFromResponse) {
1249 PrefsMock prefs;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001250 FakeSystemState fake_system_state;
David Zeuthene7f89172013-10-31 10:21:04 -07001251 InstallPlan install_plan;
1252 base::FilePath key_path;
1253
1254 // The result of the GetPublicKeyResponse() method is based on three things
1255 //
1256 // 1. Whether it's an official build; and
1257 // 2. Whether the Public RSA key to be used is in the root filesystem; and
1258 // 3. Whether the reponse has a public key
1259 //
1260 // We test all eight combinations to ensure that we only use the
1261 // public key in the response if
1262 //
1263 // a. it's not an official build; and
1264 // b. there is no key in the root filesystem.
1265
1266 DeltaPerformer *performer = new DeltaPerformer(&prefs,
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001267 &fake_system_state,
David Zeuthene7f89172013-10-31 10:21:04 -07001268 &install_plan);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001269 FakeHardware* fake_hardware = fake_system_state.fake_hardware();
David Zeuthene7f89172013-10-31 10:21:04 -07001270
1271 string temp_dir;
Gilad Arnolda6742b32014-01-11 00:18:34 -08001272 EXPECT_TRUE(utils::MakeTempDirectory("PublicKeyFromResponseTests.XXXXXX",
David Zeuthene7f89172013-10-31 10:21:04 -07001273 &temp_dir));
1274 string non_existing_file = temp_dir + "/non-existing";
1275 string existing_file = temp_dir + "/existing";
Alex Vakulenko75039d72014-03-25 12:36:28 -07001276 EXPECT_EQ(0, System(base::StringPrintf("touch %s", existing_file.c_str())));
David Zeuthene7f89172013-10-31 10:21:04 -07001277
1278 // Non-official build, non-existing public-key, key in response -> true
Don Garrett6646b442013-11-13 15:29:11 -08001279 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001280 performer->public_key_path_ = non_existing_file;
1281 install_plan.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
1282 EXPECT_TRUE(performer->GetPublicKeyFromResponse(&key_path));
1283 EXPECT_FALSE(key_path.empty());
1284 EXPECT_EQ(unlink(key_path.value().c_str()), 0);
1285 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -08001286 fake_hardware->SetIsOfficialBuild(true);
David Zeuthene7f89172013-10-31 10:21:04 -07001287 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1288
1289 // Non-official build, existing public-key, key in response -> false
Don Garrett6646b442013-11-13 15:29:11 -08001290 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001291 performer->public_key_path_ = existing_file;
1292 install_plan.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
1293 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1294 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -08001295 fake_hardware->SetIsOfficialBuild(true);
David Zeuthene7f89172013-10-31 10:21:04 -07001296 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1297
1298 // Non-official build, non-existing public-key, no key in response -> false
Don Garrett6646b442013-11-13 15:29:11 -08001299 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001300 performer->public_key_path_ = non_existing_file;
1301 install_plan.public_key_rsa = "";
1302 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1303 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -08001304 fake_hardware->SetIsOfficialBuild(true);
David Zeuthene7f89172013-10-31 10:21:04 -07001305 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1306
1307 // Non-official build, existing public-key, no key in response -> false
Don Garrett6646b442013-11-13 15:29:11 -08001308 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001309 performer->public_key_path_ = existing_file;
1310 install_plan.public_key_rsa = "";
1311 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1312 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -08001313 fake_hardware->SetIsOfficialBuild(true);
David Zeuthene7f89172013-10-31 10:21:04 -07001314 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1315
1316 // Non-official build, non-existing public-key, key in response
1317 // but invalid base64 -> false
Don Garrett6646b442013-11-13 15:29:11 -08001318 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001319 performer->public_key_path_ = non_existing_file;
1320 install_plan.public_key_rsa = "not-valid-base64";
1321 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1322
1323 delete performer;
1324 EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
1325}
1326
Andrew de los Reyes09e56d62010-04-23 13:45:53 -07001327} // namespace chromeos_update_engine