blob: fc2ac7eaa12290cfa60017410f97a614a8113566 [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
Alex Deymo8427b4a2014-11-05 14:00:32 -08005#include "update_engine/delta_performer.h"
6
Andrew de los Reyes09e56d62010-04-23 13:45:53 -07007#include <inttypes.h>
Alex Deymo161c4a12014-05-16 15:56:21 -07008#include <sys/mount.h>
Andrew de los Reyes09e56d62010-04-23 13:45:53 -07009
10#include <algorithm>
11#include <string>
12#include <vector>
13
Allie Wood78750a42015-02-11 15:42:11 -080014#include <base/files/file_path.h>
Ben Chan06c76a42014-09-05 08:21:06 -070015#include <base/files/file_util.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070016#include <base/strings/stringprintf.h>
Alex Deymof1cbe172015-03-05 15:58:37 -080017#include <base/strings/string_util.h>
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070018#include <google/protobuf/repeated_field.h>
19#include <gtest/gtest.h>
20
Jay Srinivasand29695d2013-04-08 15:08:05 -070021#include "update_engine/constants.h"
Andrew de los Reyes353777c2010-10-08 10:34:30 -070022#include "update_engine/extent_ranges.h"
David Zeuthene7f89172013-10-31 10:21:04 -070023#include "update_engine/fake_hardware.h"
Gilad Arnold5bb4c902014-04-10 12:32:13 -070024#include "update_engine/fake_system_state.h"
Alex Deymo8427b4a2014-11-05 14:00:32 -080025#include "update_engine/mock_prefs.h"
Alex Deymo161c4a12014-05-16 15:56:21 -070026#include "update_engine/payload_constants.h"
27#include "update_engine/payload_generator/delta_diff_generator.h"
Alex Deymo923d8fa2014-07-15 17:58:51 -070028#include "update_engine/payload_generator/payload_signer.h"
29#include "update_engine/payload_verifier.h"
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070030#include "update_engine/test_utils.h"
31#include "update_engine/update_metadata.pb.h"
32#include "update_engine/utils.h"
33
34namespace chromeos_update_engine {
35
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070036using std::string;
37using std::vector;
Darin Petkov73058b42010-10-06 16:32:19 -070038using testing::Return;
Alex Deymo161c4a12014-05-16 15:56:21 -070039using testing::_;
Alex Deymo10875d92014-11-10 21:52:57 -080040using test_utils::kRandomString;
41using test_utils::ScopedLoopMounter;
42using test_utils::System;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070043
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070044extern const char* kUnittestPrivateKeyPath;
Darin Petkovd7061ab2010-10-06 14:37:09 -070045extern const char* kUnittestPublicKeyPath;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -070046extern const char* kUnittestPrivateKey2Path;
47extern const char* kUnittestPublicKey2Path;
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070048
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -070049static const char* kBogusMetadataSignature1 =
50 "awSFIUdUZz2VWFiR+ku0Pj00V7bPQPQFYQSXjEXr3vaw3TE4xHV5CraY3/YrZpBv"
51 "J5z4dSBskoeuaO1TNC/S6E05t+yt36tE4Fh79tMnJ/z9fogBDXWgXLEUyG78IEQr"
52 "YH6/eBsQGT2RJtBgXIXbZ9W+5G9KmGDoPOoiaeNsDuqHiBc/58OFsrxskH8E6vMS"
53 "BmMGGk82mvgzic7ApcoURbCGey1b3Mwne/hPZ/bb9CIyky8Og9IfFMdL2uAweOIR"
54 "fjoTeLYZpt+WN65Vu7jJ0cQN8e1y+2yka5112wpRf/LLtPgiAjEZnsoYpLUd7CoV"
55 "pLRtClp97kN2+tXGNBQqkA==";
Jay Srinivasan738fdf32012-12-07 17:40:54 -080056
Alex Vakulenkod2779df2014-06-16 13:19:00 -070057static const int kDefaultKernelSize = 4096; // Something small for a test
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080058static const uint8_t kNewData[] = {'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
59 'n', 'e', 'w', ' ', 'd', 'a', 't', 'a', '.'};
Jay Srinivasan738fdf32012-12-07 17:40:54 -080060
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070061namespace {
Jay Srinivasan738fdf32012-12-07 17:40:54 -080062struct DeltaState {
63 string a_img;
64 string b_img;
65 int image_size;
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070066
Jay Srinivasan738fdf32012-12-07 17:40:54 -080067 string delta_path;
68 uint64_t metadata_size;
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070069
Jay Srinivasan738fdf32012-12-07 17:40:54 -080070 string old_kernel;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080071 chromeos::Blob old_kernel_data;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070072
Jay Srinivasan738fdf32012-12-07 17:40:54 -080073 string new_kernel;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080074 chromeos::Blob new_kernel_data;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070075
Jay Srinivasan738fdf32012-12-07 17:40:54 -080076 // The in-memory copy of delta file.
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080077 chromeos::Blob delta;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080078
79 // The mock system state object with which we initialize the
80 // delta performer.
Gilad Arnold5bb4c902014-04-10 12:32:13 -070081 FakeSystemState fake_system_state;
Jay Srinivasan738fdf32012-12-07 17:40:54 -080082};
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070083
Jay Srinivasan738fdf32012-12-07 17:40:54 -080084enum SignatureTest {
85 kSignatureNone, // No payload signing.
86 kSignatureGenerator, // Sign the payload at generation time.
87 kSignatureGenerated, // Sign the payload after it's generated.
Don Garrett2ae37872013-10-25 13:33:20 -070088 kSignatureGeneratedPlaceholder, // Insert placeholder signatures, then real.
Alex Vakulenkod2779df2014-06-16 13:19:00 -070089 kSignatureGeneratedPlaceholderMismatch, // Insert a wrong sized placeholder.
Jay Srinivasan738fdf32012-12-07 17:40:54 -080090 kSignatureGeneratedShell, // Sign the generated payload through shell cmds.
91 kSignatureGeneratedShellBadKey, // Sign with a bad key through shell cmds.
92 kSignatureGeneratedShellRotateCl1, // Rotate key, test client v1
93 kSignatureGeneratedShellRotateCl2, // Rotate key, test client v2
94};
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070095
Jay Srinivasan738fdf32012-12-07 17:40:54 -080096// Different options that determine what we should fill into the
97// install_plan.metadata_signature to simulate the contents received in the
98// Omaha response.
99enum MetadataSignatureTest {
100 kEmptyMetadataSignature,
101 kInvalidMetadataSignature,
102 kValidMetadataSignature,
103};
104
105enum OperationHashTest {
106 kInvalidOperationData,
107 kValidOperationData,
108};
109
Allie Woodfdf00512015-03-02 13:34:55 -0800110// Chuck size used for full payloads during test.
111size_t kDefaultFullChunkSize = 1024 * 1024;
112
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700113} // namespace
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800114
Allie Woodfdf00512015-03-02 13:34:55 -0800115class DeltaPerformerTest : public ::testing::Test {
116 public:
117 // Test helper placed where it can easily be friended from DeltaPerformer.
118 static void RunManifestValidation(const DeltaArchiveManifest& manifest,
119 bool full_payload,
120 ErrorCode expected) {
121 MockPrefs prefs;
122 InstallPlan install_plan;
123 FakeSystemState fake_system_state;
124 DeltaPerformer performer(&prefs, &fake_system_state, &install_plan);
125
126 // The install plan is for Full or Delta.
127 install_plan.is_full_update = full_payload;
128
129 // The Manifest we are validating.
130 performer.manifest_.CopyFrom(manifest);
131
132 EXPECT_EQ(expected, performer.ValidateManifest());
133 }
134
135 static void SetSupportedVersion(DeltaPerformer* performer,
136 uint64_t minor_version) {
137 performer->supported_minor_version_ = minor_version;
138 }
139};
140
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800141static void CompareFilesByBlock(const string& a_file, const string& b_file) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800142 chromeos::Blob a_data, b_data;
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700143 EXPECT_TRUE(utils::ReadFile(a_file, &a_data)) << "file failed: " << a_file;
144 EXPECT_TRUE(utils::ReadFile(b_file, &b_data)) << "file failed: " << b_file;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700145
146 EXPECT_EQ(a_data.size(), b_data.size());
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700147 EXPECT_EQ(0, a_data.size() % kBlockSize);
148 for (size_t i = 0; i < a_data.size(); i += kBlockSize) {
149 EXPECT_EQ(0, i % kBlockSize);
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800150 chromeos::Blob a_sub(&a_data[i], &a_data[i + kBlockSize]);
151 chromeos::Blob b_sub(&b_data[i], &b_data[i + kBlockSize]);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700152 EXPECT_TRUE(a_sub == b_sub) << "Block " << (i/kBlockSize) << " differs";
153 }
154}
155
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800156static bool WriteSparseFile(const string& path, off_t size) {
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700157 int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
158 TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
159 ScopedFdCloser fd_closer(&fd);
160 off_t rc = lseek(fd, size + 1, SEEK_SET);
161 TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1));
162 int return_code = ftruncate(fd, size);
163 TEST_AND_RETURN_FALSE_ERRNO(return_code == 0);
164 return true;
165}
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700166
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800167static size_t GetSignatureSize(const string& private_key_path) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800168 const chromeos::Blob data(1, 'x');
169 chromeos::Blob hash;
Darin Petkovcbfb0172011-01-14 15:24:45 -0800170 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(data, &hash));
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800171 chromeos::Blob signature;
Darin Petkovcbfb0172011-01-14 15:24:45 -0800172 EXPECT_TRUE(PayloadSigner::SignHash(hash,
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800173 private_key_path,
Darin Petkovcbfb0172011-01-14 15:24:45 -0800174 &signature));
175 return signature.size();
176}
177
Don Garrett2ae37872013-10-25 13:33:20 -0700178static bool InsertSignaturePlaceholder(int signature_size,
179 const string& payload_path,
180 uint64_t* out_metadata_size) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800181 vector<chromeos::Blob> signatures;
182 signatures.push_back(chromeos::Blob(signature_size, 0));
Don Garrett2ae37872013-10-25 13:33:20 -0700183
184 return PayloadSigner::AddSignatureToPayload(
185 payload_path,
186 signatures,
187 payload_path,
188 out_metadata_size);
189}
190
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800191static void SignGeneratedPayload(const string& payload_path,
192 uint64_t* out_metadata_size) {
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800193 int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800194 chromeos::Blob hash;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700195 ASSERT_TRUE(PayloadSigner::HashPayloadForSigning(
196 payload_path,
197 vector<int>(1, signature_size),
198 &hash));
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800199 chromeos::Blob signature;
Darin Petkovcbfb0172011-01-14 15:24:45 -0800200 ASSERT_TRUE(PayloadSigner::SignHash(hash,
201 kUnittestPrivateKeyPath,
202 &signature));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700203 ASSERT_TRUE(PayloadSigner::AddSignatureToPayload(
204 payload_path,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800205 vector<chromeos::Blob>(1, signature),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800206 payload_path,
207 out_metadata_size));
Alex Deymo923d8fa2014-07-15 17:58:51 -0700208 EXPECT_TRUE(PayloadVerifier::VerifySignedPayload(
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700209 payload_path,
210 kUnittestPublicKeyPath,
211 kSignatureMessageOriginalVersion));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800212}
213
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800214static void SignGeneratedShellPayload(SignatureTest signature_test,
215 const string& payload_path) {
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800216 string private_key_path = kUnittestPrivateKeyPath;
217 if (signature_test == kSignatureGeneratedShellBadKey) {
Gilad Arnolda6742b32014-01-11 00:18:34 -0800218 ASSERT_TRUE(utils::MakeTempFile("key.XXXXXX",
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800219 &private_key_path,
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700220 nullptr));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800221 } else {
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700222 ASSERT_TRUE(signature_test == kSignatureGeneratedShell ||
223 signature_test == kSignatureGeneratedShellRotateCl1 ||
224 signature_test == kSignatureGeneratedShellRotateCl2);
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800225 }
226 ScopedPathUnlinker key_unlinker(private_key_path);
227 key_unlinker.set_should_remove(signature_test ==
228 kSignatureGeneratedShellBadKey);
229 // Generates a new private key that will not match the public key.
230 if (signature_test == kSignatureGeneratedShellBadKey) {
231 LOG(INFO) << "Generating a mismatched private key.";
Alex Deymo719bfff2014-07-11 12:12:32 -0700232 ASSERT_EQ(0, System(base::StringPrintf(
233 "%s genrsa -out %s 2048",
234 utils::GetPathOnBoard("openssl").c_str(), private_key_path.c_str())));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800235 }
236 int signature_size = GetSignatureSize(private_key_path);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800237 string hash_file;
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700238 ASSERT_TRUE(utils::MakeTempFile("hash.XXXXXX", &hash_file, nullptr));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800239 ScopedPathUnlinker hash_unlinker(hash_file);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700240 string signature_size_string;
241 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
242 signature_test == kSignatureGeneratedShellRotateCl2)
Alex Vakulenko75039d72014-03-25 12:36:28 -0700243 signature_size_string = base::StringPrintf("%d:%d",
244 signature_size, signature_size);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700245 else
Alex Vakulenko75039d72014-03-25 12:36:28 -0700246 signature_size_string = base::StringPrintf("%d", signature_size);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800247 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700248 System(base::StringPrintf(
Steve Fung97b6f5a2014-10-07 12:39:51 -0700249 "./delta_generator -in_file=%s -signature_size=%s "
250 "-out_hash_file=%s",
Darin Petkovcbfb0172011-01-14 15:24:45 -0800251 payload_path.c_str(),
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700252 signature_size_string.c_str(),
Darin Petkovcbfb0172011-01-14 15:24:45 -0800253 hash_file.c_str())));
254
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -0700255 // Pad the hash
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800256 chromeos::Blob hash;
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -0700257 ASSERT_TRUE(utils::ReadFile(hash_file, &hash));
Alex Deymo923d8fa2014-07-15 17:58:51 -0700258 ASSERT_TRUE(PayloadVerifier::PadRSA2048SHA256Hash(&hash));
Alex Deymo10875d92014-11-10 21:52:57 -0800259 ASSERT_TRUE(test_utils::WriteFileVector(hash_file, hash));
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -0700260
Darin Petkovcbfb0172011-01-14 15:24:45 -0800261 string sig_file;
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700262 ASSERT_TRUE(utils::MakeTempFile("signature.XXXXXX", &sig_file, nullptr));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800263 ScopedPathUnlinker sig_unlinker(sig_file);
264 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700265 System(base::StringPrintf(
Alex Deymo719bfff2014-07-11 12:12:32 -0700266 "%s rsautl -raw -sign -inkey %s -in %s -out %s",
267 utils::GetPathOnBoard("openssl").c_str(),
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800268 private_key_path.c_str(),
Darin Petkovcbfb0172011-01-14 15:24:45 -0800269 hash_file.c_str(),
270 sig_file.c_str())));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700271 string sig_file2;
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700272 ASSERT_TRUE(utils::MakeTempFile("signature.XXXXXX", &sig_file2, nullptr));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700273 ScopedPathUnlinker sig2_unlinker(sig_file2);
274 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
275 signature_test == kSignatureGeneratedShellRotateCl2) {
276 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700277 System(base::StringPrintf(
Alex Deymo719bfff2014-07-11 12:12:32 -0700278 "%s rsautl -raw -sign -inkey %s -in %s -out %s",
279 utils::GetPathOnBoard("openssl").c_str(),
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700280 kUnittestPrivateKey2Path,
281 hash_file.c_str(),
282 sig_file2.c_str())));
283 // Append second sig file to first path
284 sig_file += ":" + sig_file2;
285 }
286
Darin Petkovcbfb0172011-01-14 15:24:45 -0800287 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700288 System(base::StringPrintf(
Steve Fung97b6f5a2014-10-07 12:39:51 -0700289 "./delta_generator -in_file=%s -signature_file=%s "
290 "-out_file=%s",
Darin Petkovcbfb0172011-01-14 15:24:45 -0800291 payload_path.c_str(),
292 sig_file.c_str(),
293 payload_path.c_str())));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800294 int verify_result =
Alex Vakulenko75039d72014-03-25 12:36:28 -0700295 System(base::StringPrintf(
Steve Fung97b6f5a2014-10-07 12:39:51 -0700296 "./delta_generator -in_file=%s -public_key=%s -public_key_version=%d",
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700297 payload_path.c_str(),
298 signature_test == kSignatureGeneratedShellRotateCl2 ?
299 kUnittestPublicKey2Path : kUnittestPublicKeyPath,
300 signature_test == kSignatureGeneratedShellRotateCl2 ? 2 : 1));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800301 if (signature_test == kSignatureGeneratedShellBadKey) {
302 ASSERT_NE(0, verify_result);
303 } else {
304 ASSERT_EQ(0, verify_result);
305 }
Darin Petkovcbfb0172011-01-14 15:24:45 -0800306}
307
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800308static void GenerateDeltaFile(bool full_kernel,
309 bool full_rootfs,
310 bool noop,
Darin Petkov8e447e02013-04-16 16:23:50 +0200311 off_t chunk_size,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800312 SignatureTest signature_test,
Allie Woodfdf00512015-03-02 13:34:55 -0800313 DeltaState *state,
314 uint32_t minor_version) {
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700315 EXPECT_TRUE(utils::MakeTempFile("a_img.XXXXXX", &state->a_img, nullptr));
316 EXPECT_TRUE(utils::MakeTempFile("b_img.XXXXXX", &state->b_img, nullptr));
Alex Deymo10875d92014-11-10 21:52:57 -0800317 test_utils::CreateExtImageAtPath(state->a_img, nullptr);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700318
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800319 state->image_size = static_cast<int>(utils::FileSize(state->a_img));
Darin Petkov7ea32332010-10-13 10:46:11 -0700320
321 // Extend the "partitions" holding the file system a bit.
322 EXPECT_EQ(0, System(base::StringPrintf(
Alex Deymo1f93d032015-03-10 18:58:32 -0700323 "dd if=/dev/zero of=%s seek=%d bs=1 count=1 status=none",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800324 state->a_img.c_str(),
325 state->image_size + 1024 * 1024 - 1)));
326 EXPECT_EQ(state->image_size + 1024 * 1024, utils::FileSize(state->a_img));
Darin Petkov7ea32332010-10-13 10:46:11 -0700327
Don Garrett0dd39852013-04-03 16:55:42 -0700328 // Create ImageInfo A & B
329 ImageInfo old_image_info;
330 ImageInfo new_image_info;
331
332 if (!full_rootfs) {
333 old_image_info.set_channel("src-channel");
334 old_image_info.set_board("src-board");
335 old_image_info.set_version("src-version");
336 old_image_info.set_key("src-key");
337 old_image_info.set_build_channel("src-build-channel");
338 old_image_info.set_build_version("src-build-version");
339 }
340
341 new_image_info.set_channel("test-channel");
342 new_image_info.set_board("test-board");
343 new_image_info.set_version("test-version");
344 new_image_info.set_key("test-key");
345 new_image_info.set_build_channel("test-build-channel");
346 new_image_info.set_build_version("test-build-version");
347
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700348 // Make some changes to the A image.
349 {
350 string a_mnt;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800351 ScopedLoopMounter b_mounter(state->a_img, &a_mnt, 0);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700352
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800353 chromeos::Blob hardtocompress;
Darin Petkov8e447e02013-04-16 16:23:50 +0200354 while (hardtocompress.size() < 3 * kBlockSize) {
355 hardtocompress.insert(hardtocompress.end(),
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800356 std::begin(kRandomString), std::end(kRandomString));
Darin Petkov8e447e02013-04-16 16:23:50 +0200357 }
Alex Vakulenko75039d72014-03-25 12:36:28 -0700358 EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800359 a_mnt.c_str()).c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700360 hardtocompress.data(),
Darin Petkov8e447e02013-04-16 16:23:50 +0200361 hardtocompress.size()));
362
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800363 chromeos::Blob zeros(16 * 1024, 0);
Darin Petkov8a075a72013-04-25 14:46:09 +0200364 EXPECT_EQ(zeros.size(),
Ben Chan736fcb52014-05-21 18:28:22 -0700365 base::WriteFile(base::FilePath(base::StringPrintf(
366 "%s/move-to-sparse", a_mnt.c_str())),
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800367 reinterpret_cast<const char*>(zeros.data()),
368 zeros.size()));
Darin Petkov8a075a72013-04-25 14:46:09 +0200369
370 EXPECT_TRUE(
Alex Vakulenko75039d72014-03-25 12:36:28 -0700371 WriteSparseFile(base::StringPrintf("%s/move-from-sparse",
372 a_mnt.c_str()), 16 * 1024));
Darin Petkov8a075a72013-04-25 14:46:09 +0200373
Alex Vakulenko75039d72014-03-25 12:36:28 -0700374 EXPECT_EQ(0,
Alex Deymo10875d92014-11-10 21:52:57 -0800375 System(base::StringPrintf("dd if=/dev/zero of=%s/move-semi-sparse"
Alex Deymo1f93d032015-03-10 18:58:32 -0700376 " bs=1 seek=4096 count=1 status=none",
Alex Deymo10875d92014-11-10 21:52:57 -0800377 a_mnt.c_str()).c_str()));
Darin Petkov8a075a72013-04-25 14:46:09 +0200378
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700379 // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
380 // patch fails to zero out the final block.
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800381 chromeos::Blob ones(1024 * 1024, 0xff);
Alex Vakulenko75039d72014-03-25 12:36:28 -0700382 EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/ones",
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800383 a_mnt.c_str()).c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700384 ones.data(),
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700385 ones.size()));
386 }
387
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700388 if (noop) {
Alex Vakulenko75039d72014-03-25 12:36:28 -0700389 EXPECT_TRUE(base::CopyFile(base::FilePath(state->a_img),
390 base::FilePath(state->b_img)));
Don Garrett0dd39852013-04-03 16:55:42 -0700391 old_image_info = new_image_info;
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700392 } else {
Alex Deymo10875d92014-11-10 21:52:57 -0800393 test_utils::CreateExtImageAtPath(state->b_img, nullptr);
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700394 EXPECT_EQ(0, System(base::StringPrintf(
Alex Deymo1f93d032015-03-10 18:58:32 -0700395 "dd if=/dev/zero of=%s seek=%d bs=1 count=1 status=none",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800396 state->b_img.c_str(),
397 state->image_size + 1024 * 1024 - 1)));
398 EXPECT_EQ(state->image_size + 1024 * 1024, utils::FileSize(state->b_img));
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700399
400 // Make some changes to the B image.
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700401 string b_mnt;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800402 ScopedLoopMounter b_mounter(state->b_img, &b_mnt, 0);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700403
Alex Deymo10875d92014-11-10 21:52:57 -0800404 EXPECT_EQ(0, System(base::StringPrintf("cp %s/hello %s/hello2",
Alex Vakulenko75039d72014-03-25 12:36:28 -0700405 b_mnt.c_str(),
406 b_mnt.c_str()).c_str()));
Alex Deymo10875d92014-11-10 21:52:57 -0800407 EXPECT_EQ(0, System(base::StringPrintf("rm %s/hello",
Alex Vakulenko75039d72014-03-25 12:36:28 -0700408 b_mnt.c_str()).c_str()));
Alex Deymo10875d92014-11-10 21:52:57 -0800409 EXPECT_EQ(0, System(base::StringPrintf("mv %s/hello2 %s/hello",
Alex Vakulenko75039d72014-03-25 12:36:28 -0700410 b_mnt.c_str(),
411 b_mnt.c_str()).c_str()));
Alex Deymo10875d92014-11-10 21:52:57 -0800412 EXPECT_EQ(0, System(base::StringPrintf("echo foo > %s/foo",
Alex Vakulenko75039d72014-03-25 12:36:28 -0700413 b_mnt.c_str()).c_str()));
Alex Deymo10875d92014-11-10 21:52:57 -0800414 EXPECT_EQ(0, System(base::StringPrintf("touch %s/emptyfile",
Alex Vakulenko75039d72014-03-25 12:36:28 -0700415 b_mnt.c_str()).c_str()));
416 EXPECT_TRUE(WriteSparseFile(base::StringPrintf("%s/fullsparse",
417 b_mnt.c_str()),
418 1024 * 1024));
Darin Petkov8a075a72013-04-25 14:46:09 +0200419
420 EXPECT_TRUE(
Alex Vakulenko75039d72014-03-25 12:36:28 -0700421 WriteSparseFile(base::StringPrintf("%s/move-to-sparse", b_mnt.c_str()),
Darin Petkov8a075a72013-04-25 14:46:09 +0200422 16 * 1024));
423
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800424 chromeos::Blob zeros(16 * 1024, 0);
Darin Petkov8a075a72013-04-25 14:46:09 +0200425 EXPECT_EQ(zeros.size(),
Ben Chan736fcb52014-05-21 18:28:22 -0700426 base::WriteFile(base::FilePath(base::StringPrintf(
427 "%s/move-from-sparse", b_mnt.c_str())),
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800428 reinterpret_cast<const char*>(zeros.data()),
429 zeros.size()));
Darin Petkov8a075a72013-04-25 14:46:09 +0200430
Alex Deymo10875d92014-11-10 21:52:57 -0800431 EXPECT_EQ(0, System(base::StringPrintf("dd if=/dev/zero "
Alex Vakulenko75039d72014-03-25 12:36:28 -0700432 "of=%s/move-semi-sparse "
Alex Deymo1f93d032015-03-10 18:58:32 -0700433 "bs=1 seek=4096 count=1 status=none",
Alex Vakulenko75039d72014-03-25 12:36:28 -0700434 b_mnt.c_str()).c_str()));
Darin Petkov8a075a72013-04-25 14:46:09 +0200435
Alex Deymo10875d92014-11-10 21:52:57 -0800436 EXPECT_EQ(0, System(base::StringPrintf("dd if=/dev/zero "
Alex Vakulenko75039d72014-03-25 12:36:28 -0700437 "of=%s/partsparse bs=1 "
Alex Deymo1f93d032015-03-10 18:58:32 -0700438 "seek=4096 count=1 status=none",
Alex Vakulenko75039d72014-03-25 12:36:28 -0700439 b_mnt.c_str()).c_str()));
Alex Deymo10875d92014-11-10 21:52:57 -0800440 EXPECT_EQ(0, System(base::StringPrintf("cp %s/srchardlink0 %s/tmp && "
Alex Vakulenko75039d72014-03-25 12:36:28 -0700441 "mv %s/tmp %s/srchardlink1",
442 b_mnt.c_str(),
443 b_mnt.c_str(),
444 b_mnt.c_str(),
445 b_mnt.c_str()).c_str()));
Alex Deymo10875d92014-11-10 21:52:57 -0800446 EXPECT_EQ(0, System(
447 base::StringPrintf("rm %s/boguslink && echo foobar > %s/boguslink",
448 b_mnt.c_str(), b_mnt.c_str()).c_str()));
Darin Petkov8e447e02013-04-16 16:23:50 +0200449
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800450 chromeos::Blob hardtocompress;
Darin Petkov8e447e02013-04-16 16:23:50 +0200451 while (hardtocompress.size() < 3 * kBlockSize) {
452 hardtocompress.insert(hardtocompress.end(),
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800453 std::begin(kRandomString), std::end(kRandomString));
Darin Petkov8e447e02013-04-16 16:23:50 +0200454 }
Alex Vakulenko75039d72014-03-25 12:36:28 -0700455 EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700456 b_mnt.c_str()).c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700457 hardtocompress.data(),
Darin Petkov8e447e02013-04-16 16:23:50 +0200458 hardtocompress.size()));
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700459 }
460
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700461 string old_kernel;
Gilad Arnolda6742b32014-01-11 00:18:34 -0800462 EXPECT_TRUE(utils::MakeTempFile("old_kernel.XXXXXX",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800463 &state->old_kernel,
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700464 nullptr));
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700465
466 string new_kernel;
Gilad Arnolda6742b32014-01-11 00:18:34 -0800467 EXPECT_TRUE(utils::MakeTempFile("new_kernel.XXXXXX",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800468 &state->new_kernel,
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700469 nullptr));
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700470
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800471 state->old_kernel_data.resize(kDefaultKernelSize);
472 state->new_kernel_data.resize(state->old_kernel_data.size());
Alex Deymo10875d92014-11-10 21:52:57 -0800473 test_utils::FillWithData(&state->old_kernel_data);
474 test_utils::FillWithData(&state->new_kernel_data);
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700475
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700476 // change the new kernel data
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800477 std::copy(std::begin(kNewData), std::end(kNewData),
478 state->new_kernel_data.begin());
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700479
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700480 if (noop) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800481 state->old_kernel_data = state->new_kernel_data;
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700482 }
483
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700484 // Write kernels to disk
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800485 EXPECT_TRUE(utils::WriteFile(state->old_kernel.c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700486 state->old_kernel_data.data(),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800487 state->old_kernel_data.size()));
488 EXPECT_TRUE(utils::WriteFile(state->new_kernel.c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700489 state->new_kernel_data.data(),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800490 state->new_kernel_data.size()));
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700491
Gilad Arnolda6742b32014-01-11 00:18:34 -0800492 EXPECT_TRUE(utils::MakeTempFile("delta.XXXXXX",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800493 &state->delta_path,
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700494 nullptr));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800495 LOG(INFO) << "delta path: " << state->delta_path;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700496 {
497 string a_mnt, b_mnt;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800498 ScopedLoopMounter a_mounter(state->a_img, &a_mnt, MS_RDONLY);
499 ScopedLoopMounter b_mounter(state->b_img, &b_mnt, MS_RDONLY);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800500 const string private_key =
501 signature_test == kSignatureGenerator ? kUnittestPrivateKeyPath : "";
Alex Deymof1cbe172015-03-05 15:58:37 -0800502
503 PayloadGenerationConfig payload_config;
504 payload_config.is_delta = !full_rootfs;
505 payload_config.chunk_size = chunk_size;
Alex Deymo9b244df2015-03-11 21:51:18 -0700506 payload_config.rootfs_partition_size = kRootFSPartitionSize;
Allie Woodfdf00512015-03-02 13:34:55 -0800507 payload_config.minor_version = minor_version;
Alex Deymof1cbe172015-03-05 15:58:37 -0800508 if (!full_rootfs) {
509 payload_config.source.rootfs_part = state->a_img;
510 payload_config.source.rootfs_mountpt = a_mnt;
511 if (!full_kernel)
512 payload_config.source.kernel_part = state->old_kernel;
513 payload_config.source.image_info = old_image_info;
514 EXPECT_TRUE(payload_config.source.LoadImageSize());
515
Alex Deymof1cbe172015-03-05 15:58:37 -0800516 } else {
Allie Woodfdf00512015-03-02 13:34:55 -0800517 if (payload_config.chunk_size == -1)
518 payload_config.chunk_size = kDefaultFullChunkSize;
Alex Deymof1cbe172015-03-05 15:58:37 -0800519 }
520 payload_config.target.rootfs_part = state->b_img;
521 payload_config.target.rootfs_mountpt = b_mnt;
522 payload_config.target.kernel_part = state->new_kernel;
523 payload_config.target.image_info = new_image_info;
524 EXPECT_TRUE(payload_config.target.LoadImageSize());
525
526 EXPECT_TRUE(payload_config.Validate());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700527 EXPECT_TRUE(
Darin Petkov68c10d12010-10-14 09:24:37 -0700528 DeltaDiffGenerator::GenerateDeltaUpdateFile(
Alex Deymof1cbe172015-03-05 15:58:37 -0800529 payload_config,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800530 state->delta_path,
531 private_key,
532 &state->metadata_size));
Darin Petkov9574f7e2011-01-13 10:48:12 -0800533 }
534
Don Garrett2ae37872013-10-25 13:33:20 -0700535 if (signature_test == kSignatureGeneratedPlaceholder ||
536 signature_test == kSignatureGeneratedPlaceholderMismatch) {
Don Garrett2ae37872013-10-25 13:33:20 -0700537 int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
538 LOG(INFO) << "Inserting placeholder signature.";
539 ASSERT_TRUE(InsertSignaturePlaceholder(signature_size, state->delta_path,
540 &state->metadata_size));
541
542 if (signature_test == kSignatureGeneratedPlaceholderMismatch) {
543 signature_size -= 1;
544 LOG(INFO) << "Inserting mismatched placeholder signature.";
545 ASSERT_FALSE(InsertSignaturePlaceholder(signature_size, state->delta_path,
546 &state->metadata_size));
547 return;
548 }
549 }
550
551 if (signature_test == kSignatureGenerated ||
552 signature_test == kSignatureGeneratedPlaceholder ||
553 signature_test == kSignatureGeneratedPlaceholderMismatch) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800554 // Generate the signed payload and update the metadata size in state to
555 // reflect the new size after adding the signature operation to the
556 // manifest.
Don Garrett2ae37872013-10-25 13:33:20 -0700557 LOG(INFO) << "Signing payload.";
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800558 SignGeneratedPayload(state->delta_path, &state->metadata_size);
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800559 } else if (signature_test == kSignatureGeneratedShell ||
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700560 signature_test == kSignatureGeneratedShellBadKey ||
561 signature_test == kSignatureGeneratedShellRotateCl1 ||
562 signature_test == kSignatureGeneratedShellRotateCl2) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800563 SignGeneratedShellPayload(signature_test, state->delta_path);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700564 }
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800565}
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700566
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800567static void ApplyDeltaFile(bool full_kernel, bool full_rootfs, bool noop,
568 SignatureTest signature_test, DeltaState* state,
569 bool hash_checks_mandatory,
570 OperationHashTest op_hash_test,
Allie Woodfdf00512015-03-02 13:34:55 -0800571 DeltaPerformer** performer,
572 uint32_t minor_version) {
Darin Petkov36a58222010-10-07 22:00:09 -0700573 // Check the metadata.
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700574 {
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700575 DeltaArchiveManifest manifest;
Alex Deymo923d8fa2014-07-15 17:58:51 -0700576 EXPECT_TRUE(PayloadVerifier::LoadPayload(state->delta_path,
577 &state->delta,
578 &manifest,
579 &state->metadata_size));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800580 LOG(INFO) << "Metadata size: " << state->metadata_size;
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700581
Don Garrett0dd39852013-04-03 16:55:42 -0700582
583
Darin Petkovcbfb0172011-01-14 15:24:45 -0800584 if (signature_test == kSignatureNone) {
585 EXPECT_FALSE(manifest.has_signatures_offset());
586 EXPECT_FALSE(manifest.has_signatures_size());
587 } else {
588 EXPECT_TRUE(manifest.has_signatures_offset());
589 EXPECT_TRUE(manifest.has_signatures_size());
590 Signatures sigs_message;
591 EXPECT_TRUE(sigs_message.ParseFromArray(
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800592 &state->delta[state->metadata_size + manifest.signatures_offset()],
Darin Petkovcbfb0172011-01-14 15:24:45 -0800593 manifest.signatures_size()));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700594 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
595 signature_test == kSignatureGeneratedShellRotateCl2)
596 EXPECT_EQ(2, sigs_message.signatures_size());
597 else
598 EXPECT_EQ(1, sigs_message.signatures_size());
Darin Petkovcbfb0172011-01-14 15:24:45 -0800599 const Signatures_Signature& signature = sigs_message.signatures(0);
600 EXPECT_EQ(1, signature.version());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700601
Darin Petkovcbfb0172011-01-14 15:24:45 -0800602 uint64_t expected_sig_data_length = 0;
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700603 vector<string> key_paths{kUnittestPrivateKeyPath};
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700604 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
605 signature_test == kSignatureGeneratedShellRotateCl2) {
606 key_paths.push_back(kUnittestPrivateKey2Path);
607 }
Darin Petkovcbfb0172011-01-14 15:24:45 -0800608 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700609 key_paths,
610 &expected_sig_data_length));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800611 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
612 EXPECT_FALSE(signature.data().empty());
613 }
Darin Petkov36a58222010-10-07 22:00:09 -0700614
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700615 if (noop) {
Gilad Arnold063181c2015-02-05 12:24:49 -0800616 EXPECT_EQ(0, manifest.install_operations_size());
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700617 EXPECT_EQ(1, manifest.kernel_install_operations_size());
618 }
619
Darin Petkovd43d6902010-10-14 11:17:50 -0700620 if (full_kernel) {
621 EXPECT_FALSE(manifest.has_old_kernel_info());
622 } else {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800623 EXPECT_EQ(state->old_kernel_data.size(),
624 manifest.old_kernel_info().size());
Darin Petkovd43d6902010-10-14 11:17:50 -0700625 EXPECT_FALSE(manifest.old_kernel_info().hash().empty());
626 }
Darin Petkov698d0412010-10-13 10:59:44 -0700627
Don Garrett0dd39852013-04-03 16:55:42 -0700628 EXPECT_EQ(manifest.new_image_info().channel(), "test-channel");
629 EXPECT_EQ(manifest.new_image_info().board(), "test-board");
630 EXPECT_EQ(manifest.new_image_info().version(), "test-version");
631 EXPECT_EQ(manifest.new_image_info().key(), "test-key");
632 EXPECT_EQ(manifest.new_image_info().build_channel(), "test-build-channel");
633 EXPECT_EQ(manifest.new_image_info().build_version(), "test-build-version");
634
635 if (!full_rootfs) {
Don Garrett0dd39852013-04-03 16:55:42 -0700636 if (noop) {
637 EXPECT_EQ(manifest.old_image_info().channel(), "test-channel");
638 EXPECT_EQ(manifest.old_image_info().board(), "test-board");
639 EXPECT_EQ(manifest.old_image_info().version(), "test-version");
640 EXPECT_EQ(manifest.old_image_info().key(), "test-key");
641 EXPECT_EQ(manifest.old_image_info().build_channel(),
642 "test-build-channel");
643 EXPECT_EQ(manifest.old_image_info().build_version(),
644 "test-build-version");
645 } else {
646 EXPECT_EQ(manifest.old_image_info().channel(), "src-channel");
647 EXPECT_EQ(manifest.old_image_info().board(), "src-board");
648 EXPECT_EQ(manifest.old_image_info().version(), "src-version");
649 EXPECT_EQ(manifest.old_image_info().key(), "src-key");
650 EXPECT_EQ(manifest.old_image_info().build_channel(),
651 "src-build-channel");
652 EXPECT_EQ(manifest.old_image_info().build_version(),
653 "src-build-version");
654 }
655 }
656
657
Darin Petkov7a22d792010-11-08 14:10:00 -0800658 if (full_rootfs) {
659 EXPECT_FALSE(manifest.has_old_rootfs_info());
Don Garrett0dd39852013-04-03 16:55:42 -0700660 EXPECT_FALSE(manifest.has_old_image_info());
661 EXPECT_TRUE(manifest.has_new_image_info());
Darin Petkov7a22d792010-11-08 14:10:00 -0800662 } else {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800663 EXPECT_EQ(state->image_size, manifest.old_rootfs_info().size());
Darin Petkov7a22d792010-11-08 14:10:00 -0800664 EXPECT_FALSE(manifest.old_rootfs_info().hash().empty());
665 }
666
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800667 EXPECT_EQ(state->new_kernel_data.size(), manifest.new_kernel_info().size());
668 EXPECT_EQ(state->image_size, manifest.new_rootfs_info().size());
Darin Petkov36a58222010-10-07 22:00:09 -0700669
Darin Petkov36a58222010-10-07 22:00:09 -0700670 EXPECT_FALSE(manifest.new_kernel_info().hash().empty());
Darin Petkov36a58222010-10-07 22:00:09 -0700671 EXPECT_FALSE(manifest.new_rootfs_info().hash().empty());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700672 }
673
Alex Deymo8427b4a2014-11-05 14:00:32 -0800674 MockPrefs prefs;
Darin Petkov73058b42010-10-06 16:32:19 -0700675 EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800676 state->metadata_size)).WillOnce(Return(true));
Darin Petkov73058b42010-10-06 16:32:19 -0700677 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
678 .WillRepeatedly(Return(true));
Darin Petkov9b230572010-10-08 10:20:09 -0700679 EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
680 .WillOnce(Return(false));
Darin Petkov73058b42010-10-06 16:32:19 -0700681 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
682 .WillRepeatedly(Return(true));
David Zeuthen41996ad2013-09-24 15:43:24 -0700683 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataLength, _))
684 .WillRepeatedly(Return(true));
Darin Petkov437adc42010-10-07 13:12:24 -0700685 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
Darin Petkov73058b42010-10-06 16:32:19 -0700686 .WillRepeatedly(Return(true));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800687 if (op_hash_test == kValidOperationData && signature_test != kSignatureNone) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800688 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
689 .WillOnce(Return(true));
Darin Petkov4f0a07b2011-05-25 16:47:20 -0700690 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
691 .WillOnce(Return(true));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800692 }
Darin Petkov73058b42010-10-06 16:32:19 -0700693
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700694 // Update the A image in place.
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700695 InstallPlan install_plan;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800696 install_plan.hash_checks_mandatory = hash_checks_mandatory;
697 install_plan.metadata_size = state->metadata_size;
Don Garrettb8dd1d92013-11-22 17:40:02 -0800698 install_plan.is_full_update = full_kernel && full_rootfs;
Allie Woodfdf00512015-03-02 13:34:55 -0800699 install_plan.source_path = state->a_img.c_str();
700 install_plan.kernel_source_path = state->old_kernel.c_str();
Don Garrettb8dd1d92013-11-22 17:40:02 -0800701
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800702 LOG(INFO) << "Setting payload metadata size in Omaha = "
703 << state->metadata_size;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700704 ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
Alex Vakulenko75039d72014-03-25 12:36:28 -0700705 state->delta.data(),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800706 state->metadata_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700707 kUnittestPrivateKeyPath,
Jay Srinivasanf4318702012-09-24 11:56:24 -0700708 &install_plan.metadata_signature));
709 EXPECT_FALSE(install_plan.metadata_signature.empty());
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700710
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800711 *performer = new DeltaPerformer(&prefs,
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700712 &state->fake_system_state,
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800713 &install_plan);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700714 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800715 (*performer)->set_public_key_path(kUnittestPublicKeyPath);
Allie Woodfdf00512015-03-02 13:34:55 -0800716 DeltaPerformerTest::SetSupportedVersion(*performer, minor_version);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700717
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800718 EXPECT_EQ(state->image_size,
719 OmahaHashCalculator::RawHashOfFile(state->a_img,
720 state->image_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700721 &install_plan.rootfs_hash));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800722 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(state->old_kernel_data,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700723 &install_plan.kernel_hash));
724
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800725 EXPECT_EQ(0, (*performer)->Open(state->a_img.c_str(), 0, 0));
726 EXPECT_TRUE((*performer)->OpenKernel(state->old_kernel.c_str()));
727
David Zeuthena99981f2013-04-29 13:42:47 -0700728 ErrorCode expected_error, actual_error;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800729 bool continue_writing;
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700730 switch (op_hash_test) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800731 case kInvalidOperationData: {
732 // Muck with some random offset post the metadata size so that
733 // some operation hash will result in a mismatch.
734 int some_offset = state->metadata_size + 300;
735 LOG(INFO) << "Tampered value at offset: " << some_offset;
736 state->delta[some_offset]++;
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700737 expected_error = ErrorCode::kDownloadOperationHashMismatch;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800738 continue_writing = false;
739 break;
740 }
741
742 case kValidOperationData:
743 default:
744 // no change.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700745 expected_error = ErrorCode::kSuccess;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800746 continue_writing = true;
747 break;
748 }
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700749
Allie Woodfdf00512015-03-02 13:34:55 -0800750 // For now, source operations are not implemented, so we expect an error.
751 if (minor_version == kSourceMinorPayloadVersion) {
752 expected_error = ErrorCode::kDownloadOperationExecutionError;
753 continue_writing = false;
754 }
755
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700756 // Write at some number of bytes per operation. Arbitrarily chose 5.
757 const size_t kBytesPerWrite = 5;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800758 for (size_t i = 0; i < state->delta.size(); i += kBytesPerWrite) {
Alex Deymof329b932014-10-30 01:37:48 -0700759 size_t count = std::min(state->delta.size() - i, kBytesPerWrite);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800760 bool write_succeeded = ((*performer)->Write(&state->delta[i],
761 count,
762 &actual_error));
763 // Normally write_succeeded should be true every time and
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700764 // actual_error should be ErrorCode::kSuccess. If so, continue the loop.
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800765 // But if we seeded an operation hash error above, then write_succeeded
766 // will be false. The failure may happen at any operation n. So, all
767 // Writes until n-1 should succeed and the nth operation will fail with
768 // actual_error. In this case, we should bail out of the loop because
769 // we cannot proceed applying the delta.
770 if (!write_succeeded) {
771 LOG(INFO) << "Write failed. Checking if it failed with expected error";
772 EXPECT_EQ(expected_error, actual_error);
773 if (!continue_writing) {
774 LOG(INFO) << "Cannot continue writing. Bailing out.";
775 break;
776 }
777 }
778
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700779 EXPECT_EQ(ErrorCode::kSuccess, actual_error);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700780 }
781
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800782 // If we had continued all the way through, Close should succeed.
783 // Otherwise, it should fail. Check appropriately.
784 bool close_result = (*performer)->Close();
785 if (continue_writing)
786 EXPECT_EQ(0, close_result);
787 else
788 EXPECT_LE(0, close_result);
789}
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700790
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800791void VerifyPayloadResult(DeltaPerformer* performer,
792 DeltaState* state,
David Zeuthena99981f2013-04-29 13:42:47 -0700793 ErrorCode expected_result) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800794 if (!performer) {
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700795 EXPECT_TRUE(!"Skipping payload verification since performer is null.");
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800796 return;
797 }
798
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700799 int expected_times = (expected_result == ErrorCode::kSuccess) ? 1 : 0;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700800 EXPECT_CALL(*(state->fake_system_state.mock_payload_state()),
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800801 DownloadComplete()).Times(expected_times);
802
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800803 LOG(INFO) << "Verifying payload for expected result "
804 << expected_result;
805 EXPECT_EQ(expected_result, performer->VerifyPayload(
806 OmahaHashCalculator::OmahaHashOfData(state->delta),
807 state->delta.size()));
808 LOG(INFO) << "Verified payload.";
809
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700810 if (expected_result != ErrorCode::kSuccess) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800811 // no need to verify new partition if VerifyPayload failed.
812 return;
813 }
814
815 CompareFilesByBlock(state->old_kernel, state->new_kernel);
816 CompareFilesByBlock(state->a_img, state->b_img);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700817
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800818 chromeos::Blob updated_kernel_partition;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800819 EXPECT_TRUE(utils::ReadFile(state->old_kernel, &updated_kernel_partition));
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800820 ASSERT_GE(updated_kernel_partition.size(), arraysize(kNewData));
821 EXPECT_TRUE(std::equal(std::begin(kNewData), std::end(kNewData),
822 updated_kernel_partition.begin()));
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700823
824 uint64_t new_kernel_size;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800825 chromeos::Blob new_kernel_hash;
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700826 uint64_t new_rootfs_size;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800827 chromeos::Blob new_rootfs_hash;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800828 EXPECT_TRUE(performer->GetNewPartitionInfo(&new_kernel_size,
Don Garrett0dd39852013-04-03 16:55:42 -0700829 &new_kernel_hash,
830 &new_rootfs_size,
831 &new_rootfs_hash));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800832 EXPECT_EQ(kDefaultKernelSize, new_kernel_size);
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800833 chromeos::Blob expected_new_kernel_hash;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800834 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(state->new_kernel_data,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700835 &expected_new_kernel_hash));
836 EXPECT_TRUE(expected_new_kernel_hash == new_kernel_hash);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800837 EXPECT_EQ(state->image_size, new_rootfs_size);
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800838 chromeos::Blob expected_new_rootfs_hash;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800839 EXPECT_EQ(state->image_size,
840 OmahaHashCalculator::RawHashOfFile(state->b_img,
841 state->image_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700842 &expected_new_rootfs_hash));
843 EXPECT_TRUE(expected_new_rootfs_hash == new_rootfs_hash);
844}
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800845
846void VerifyPayload(DeltaPerformer* performer,
847 DeltaState* state,
848 SignatureTest signature_test) {
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700849 ErrorCode expected_result = ErrorCode::kSuccess;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800850 switch (signature_test) {
851 case kSignatureNone:
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700852 expected_result = ErrorCode::kSignedDeltaPayloadExpectedError;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800853 break;
854 case kSignatureGeneratedShellBadKey:
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700855 expected_result = ErrorCode::kDownloadPayloadPubKeyVerificationError;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800856 break;
857 default: break; // appease gcc
858 }
859
860 VerifyPayloadResult(performer, state, expected_result);
861}
862
863void DoSmallImageTest(bool full_kernel, bool full_rootfs, bool noop,
Darin Petkov8e447e02013-04-16 16:23:50 +0200864 off_t chunk_size,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800865 SignatureTest signature_test,
Allie Woodfdf00512015-03-02 13:34:55 -0800866 bool hash_checks_mandatory, uint32_t minor_version) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800867 DeltaState state;
Alex Deymo52146ce2014-05-29 11:09:45 -0700868 DeltaPerformer *performer = nullptr;
Darin Petkov8e447e02013-04-16 16:23:50 +0200869 GenerateDeltaFile(full_kernel, full_rootfs, noop, chunk_size,
Allie Woodfdf00512015-03-02 13:34:55 -0800870 signature_test, &state, minor_version);
Don Garrett0dd39852013-04-03 16:55:42 -0700871
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800872 ScopedPathUnlinker a_img_unlinker(state.a_img);
873 ScopedPathUnlinker b_img_unlinker(state.b_img);
874 ScopedPathUnlinker delta_unlinker(state.delta_path);
875 ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
876 ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
877 ApplyDeltaFile(full_kernel, full_rootfs, noop, signature_test,
878 &state, hash_checks_mandatory, kValidOperationData,
Allie Woodfdf00512015-03-02 13:34:55 -0800879 &performer, minor_version);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800880 VerifyPayload(performer, &state, signature_test);
Alex Deymo52146ce2014-05-29 11:09:45 -0700881 delete performer;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800882}
883
884// Calls delta performer's Write method by pretending to pass in bytes from a
885// delta file whose metadata size is actual_metadata_size and tests if all
886// checks are correctly performed if the install plan contains
887// expected_metadata_size and that the result of the parsing are as per
888// hash_checks_mandatory flag.
889void DoMetadataSizeTest(uint64_t expected_metadata_size,
890 uint64_t actual_metadata_size,
891 bool hash_checks_mandatory) {
Alex Deymo8427b4a2014-11-05 14:00:32 -0800892 MockPrefs prefs;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800893 InstallPlan install_plan;
894 install_plan.hash_checks_mandatory = hash_checks_mandatory;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700895 FakeSystemState fake_system_state;
896 DeltaPerformer performer(&prefs, &fake_system_state, &install_plan);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800897 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0));
898 EXPECT_TRUE(performer.OpenKernel("/dev/null"));
899
900 // Set a valid magic string and version number 1.
901 EXPECT_TRUE(performer.Write("CrAU", 4));
902 uint64_t version = htobe64(1);
903 EXPECT_TRUE(performer.Write(&version, 8));
904
905 install_plan.metadata_size = expected_metadata_size;
David Zeuthena99981f2013-04-29 13:42:47 -0700906 ErrorCode error_code;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800907 // When filling in size in manifest, exclude the size of the 20-byte header.
908 uint64_t size_in_manifest = htobe64(actual_metadata_size - 20);
909 bool result = performer.Write(&size_in_manifest, 8, &error_code);
910 if (expected_metadata_size == actual_metadata_size ||
911 !hash_checks_mandatory) {
912 EXPECT_TRUE(result);
913 } else {
914 EXPECT_FALSE(result);
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700915 EXPECT_EQ(ErrorCode::kDownloadInvalidMetadataSize, error_code);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800916 }
917
918 EXPECT_LT(performer.Close(), 0);
919}
920
921// Generates a valid delta file but tests the delta performer by suppling
922// different metadata signatures as per omaha_metadata_signature flag and
923// sees if the result of the parsing are as per hash_checks_mandatory flag.
924void DoMetadataSignatureTest(MetadataSignatureTest metadata_signature_test,
925 SignatureTest signature_test,
926 bool hash_checks_mandatory) {
927 DeltaState state;
928
929 // Using kSignatureNone since it doesn't affect the results of our test.
930 // If we've to use other signature options, then we'd have to get the
931 // metadata size again after adding the signing operation to the manifest.
Allie Woodfdf00512015-03-02 13:34:55 -0800932 GenerateDeltaFile(true, true, false, -1, signature_test, &state,
933 DeltaPerformer::kFullPayloadMinorVersion);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800934
935 ScopedPathUnlinker a_img_unlinker(state.a_img);
936 ScopedPathUnlinker b_img_unlinker(state.b_img);
937 ScopedPathUnlinker delta_unlinker(state.delta_path);
938 ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
939 ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
940
941 // Loads the payload and parses the manifest.
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800942 chromeos::Blob payload;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800943 EXPECT_TRUE(utils::ReadFile(state.delta_path, &payload));
944 LOG(INFO) << "Payload size: " << payload.size();
945
946 InstallPlan install_plan;
947 install_plan.hash_checks_mandatory = hash_checks_mandatory;
948 install_plan.metadata_size = state.metadata_size;
949
950 DeltaPerformer::MetadataParseResult expected_result, actual_result;
David Zeuthena99981f2013-04-29 13:42:47 -0700951 ErrorCode expected_error, actual_error;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800952
953 // Fill up the metadata signature in install plan according to the test.
954 switch (metadata_signature_test) {
955 case kEmptyMetadataSignature:
956 install_plan.metadata_signature.clear();
957 expected_result = DeltaPerformer::kMetadataParseError;
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700958 expected_error = ErrorCode::kDownloadMetadataSignatureMissingError;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800959 break;
960
961 case kInvalidMetadataSignature:
962 install_plan.metadata_signature = kBogusMetadataSignature1;
963 expected_result = DeltaPerformer::kMetadataParseError;
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700964 expected_error = ErrorCode::kDownloadMetadataSignatureMismatch;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800965 break;
966
967 case kValidMetadataSignature:
968 default:
969 // Set the install plan's metadata size to be the same as the one
970 // in the manifest so that we pass the metadata size checks. Only
971 // then we can get to manifest signature checks.
972 ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
Alex Vakulenko75039d72014-03-25 12:36:28 -0700973 payload.data(),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800974 state.metadata_size,
975 kUnittestPrivateKeyPath,
976 &install_plan.metadata_signature));
977 EXPECT_FALSE(install_plan.metadata_signature.empty());
978 expected_result = DeltaPerformer::kMetadataParseSuccess;
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700979 expected_error = ErrorCode::kSuccess;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800980 break;
981 }
982
983 // Ignore the expected result/error if hash checks are not mandatory.
984 if (!hash_checks_mandatory) {
985 expected_result = DeltaPerformer::kMetadataParseSuccess;
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700986 expected_error = ErrorCode::kSuccess;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800987 }
988
989 // Create the delta performer object.
Alex Deymo8427b4a2014-11-05 14:00:32 -0800990 MockPrefs prefs;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800991 DeltaPerformer delta_performer(&prefs,
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700992 &state.fake_system_state,
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800993 &install_plan);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800994
995 // Use the public key corresponding to the private key used above to
996 // sign the metadata.
997 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
998 delta_performer.set_public_key_path(kUnittestPublicKeyPath);
999
Jay Srinivasan738fdf32012-12-07 17:40:54 -08001000 // Init actual_error with an invalid value so that we make sure
1001 // ParsePayloadMetadata properly populates it in all cases.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001002 actual_error = ErrorCode::kUmaReportedMax;
Gilad Arnolddaa27402014-01-23 11:56:17 -08001003 actual_result = delta_performer.ParsePayloadMetadata(payload, &actual_error);
Jay Srinivasan738fdf32012-12-07 17:40:54 -08001004
1005 EXPECT_EQ(expected_result, actual_result);
1006 EXPECT_EQ(expected_error, actual_error);
1007
1008 // Check that the parsed metadata size is what's expected. This test
1009 // implicitly confirms that the metadata signature is valid, if required.
Gilad Arnoldfe133932014-01-14 12:25:50 -08001010 EXPECT_EQ(state.metadata_size, delta_performer.GetMetadataSize());
Jay Srinivasan738fdf32012-12-07 17:40:54 -08001011}
1012
1013void DoOperationHashMismatchTest(OperationHashTest op_hash_test,
1014 bool hash_checks_mandatory) {
1015 DeltaState state;
Allie Woodfdf00512015-03-02 13:34:55 -08001016 uint64_t minor_version = DeltaPerformer::kFullPayloadMinorVersion;
1017 GenerateDeltaFile(true, true, false, -1, kSignatureGenerated, &state,
1018 minor_version);
Jay Srinivasan738fdf32012-12-07 17:40:54 -08001019 ScopedPathUnlinker a_img_unlinker(state.a_img);
1020 ScopedPathUnlinker b_img_unlinker(state.b_img);
1021 ScopedPathUnlinker delta_unlinker(state.delta_path);
1022 ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
1023 ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
Alex Deymo52146ce2014-05-29 11:09:45 -07001024 DeltaPerformer *performer = nullptr;
Allie Woodfdf00512015-03-02 13:34:55 -08001025 ApplyDeltaFile(true, true, false, kSignatureGenerated, &state,
1026 hash_checks_mandatory, op_hash_test, &performer,
1027 minor_version);
Alex Deymo52146ce2014-05-29 11:09:45 -07001028 delete performer;
Jay Srinivasan738fdf32012-12-07 17:40:54 -08001029}
1030
Jay Srinivasan738fdf32012-12-07 17:40:54 -08001031TEST(DeltaPerformerTest, ExtentsToByteStringTest) {
1032 uint64_t test[] = {1, 1, 4, 2, kSparseHole, 1, 0, 1};
1033 COMPILE_ASSERT(arraysize(test) % 2 == 0, array_size_uneven);
1034 const uint64_t block_size = 4096;
1035 const uint64_t file_length = 5 * block_size - 13;
1036
1037 google::protobuf::RepeatedPtrField<Extent> extents;
1038 for (size_t i = 0; i < arraysize(test); i += 2) {
1039 Extent* extent = extents.Add();
1040 extent->set_start_block(test[i]);
1041 extent->set_num_blocks(test[i + 1]);
1042 }
1043
1044 string expected_output = "4096:4096,16384:8192,-1:4096,0:4083";
1045 string actual_output;
1046 EXPECT_TRUE(DeltaPerformer::ExtentsToBsdiffPositionsString(extents,
1047 block_size,
1048 file_length,
1049 &actual_output));
1050 EXPECT_EQ(expected_output, actual_output);
1051}
Darin Petkov68c10d12010-10-14 09:24:37 -07001052
Don Garrettb8dd1d92013-11-22 17:40:02 -08001053TEST(DeltaPerformerTest, ValidateManifestFullGoodTest) {
1054 // The Manifest we are validating.
1055 DeltaArchiveManifest manifest;
1056 manifest.mutable_new_kernel_info();
1057 manifest.mutable_new_rootfs_info();
1058 manifest.set_minor_version(DeltaPerformer::kFullPayloadMinorVersion);
1059
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001060 DeltaPerformerTest::RunManifestValidation(manifest, true,
1061 ErrorCode::kSuccess);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001062}
1063
1064TEST(DeltaPerformerTest, ValidateManifestDeltaGoodTest) {
1065 // The Manifest we are validating.
1066 DeltaArchiveManifest manifest;
1067 manifest.mutable_old_kernel_info();
1068 manifest.mutable_old_rootfs_info();
1069 manifest.mutable_new_kernel_info();
1070 manifest.mutable_new_rootfs_info();
1071 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
1072
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001073 DeltaPerformerTest::RunManifestValidation(manifest, false,
1074 ErrorCode::kSuccess);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001075}
1076
1077TEST(DeltaPerformerTest, ValidateManifestFullUnsetMinorVersion) {
1078 // The Manifest we are validating.
1079 DeltaArchiveManifest manifest;
1080
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001081 DeltaPerformerTest::RunManifestValidation(manifest, true,
1082 ErrorCode::kSuccess);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001083}
1084
1085TEST(DeltaPerformerTest, ValidateManifestDeltaUnsetMinorVersion) {
1086 // The Manifest we are validating.
1087 DeltaArchiveManifest manifest;
1088
1089 DeltaPerformerTest::RunManifestValidation(
1090 manifest, false,
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001091 ErrorCode::kUnsupportedMinorPayloadVersion);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001092}
1093
1094TEST(DeltaPerformerTest, ValidateManifestFullOldKernelTest) {
1095 // The Manifest we are validating.
1096 DeltaArchiveManifest manifest;
1097 manifest.mutable_old_kernel_info();
1098 manifest.mutable_new_kernel_info();
1099 manifest.mutable_new_rootfs_info();
1100 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
1101
1102 DeltaPerformerTest::RunManifestValidation(
1103 manifest, true,
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001104 ErrorCode::kPayloadMismatchedType);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001105}
1106
1107TEST(DeltaPerformerTest, ValidateManifestFullOldRootfsTest) {
1108 // The Manifest we are validating.
1109 DeltaArchiveManifest manifest;
1110 manifest.mutable_old_rootfs_info();
1111 manifest.mutable_new_kernel_info();
1112 manifest.mutable_new_rootfs_info();
1113 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
1114
1115 DeltaPerformerTest::RunManifestValidation(
1116 manifest, true,
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001117 ErrorCode::kPayloadMismatchedType);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001118}
1119
1120TEST(DeltaPerformerTest, ValidateManifestBadMinorVersion) {
1121 // The Manifest we are validating.
1122 DeltaArchiveManifest manifest;
1123
1124 // Generate a bad version number.
1125 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion +
1126 10000);
1127
1128 DeltaPerformerTest::RunManifestValidation(
1129 manifest, false,
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001130 ErrorCode::kUnsupportedMinorPayloadVersion);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001131}
1132
Darin Petkov68c10d12010-10-14 09:24:37 -07001133TEST(DeltaPerformerTest, RunAsRootSmallImageTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001134 DoSmallImageTest(false, false, false, -1, kSignatureGenerator,
Allie Woodfdf00512015-03-02 13:34:55 -08001135 false, kInPlaceMinorPayloadVersion);
Darin Petkov8e447e02013-04-16 16:23:50 +02001136}
1137
Don Garrett2ae37872013-10-25 13:33:20 -07001138TEST(DeltaPerformerTest, RunAsRootSmallImageSignaturePlaceholderTest) {
1139 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedPlaceholder,
Allie Woodfdf00512015-03-02 13:34:55 -08001140 false, kInPlaceMinorPayloadVersion);
Don Garrett2ae37872013-10-25 13:33:20 -07001141}
1142
1143TEST(DeltaPerformerTest, RunAsRootSmallImageSignaturePlaceholderMismatchTest) {
1144 DeltaState state;
1145 GenerateDeltaFile(false, false, false, -1,
Allie Woodfdf00512015-03-02 13:34:55 -08001146 kSignatureGeneratedPlaceholderMismatch, &state,
1147 kInPlaceMinorPayloadVersion);
Don Garrett2ae37872013-10-25 13:33:20 -07001148}
1149
Darin Petkov8e447e02013-04-16 16:23:50 +02001150TEST(DeltaPerformerTest, RunAsRootSmallImageChunksTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001151 DoSmallImageTest(false, false, false, kBlockSize, kSignatureGenerator,
Allie Woodfdf00512015-03-02 13:34:55 -08001152 false, kInPlaceMinorPayloadVersion);
Darin Petkov68c10d12010-10-14 09:24:37 -07001153}
1154
1155TEST(DeltaPerformerTest, RunAsRootFullKernelSmallImageTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001156 DoSmallImageTest(true, false, false, -1, kSignatureGenerator,
Allie Woodfdf00512015-03-02 13:34:55 -08001157 false, kInPlaceMinorPayloadVersion);
Darin Petkov7a22d792010-11-08 14:10:00 -08001158}
1159
1160TEST(DeltaPerformerTest, RunAsRootFullSmallImageTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001161 DoSmallImageTest(true, true, false, -1, kSignatureGenerator,
Allie Woodfdf00512015-03-02 13:34:55 -08001162 true, DeltaPerformer::kFullPayloadMinorVersion);
Darin Petkov9fa7ec52010-10-18 11:45:23 -07001163}
1164
1165TEST(DeltaPerformerTest, RunAsRootNoopSmallImageTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001166 DoSmallImageTest(false, false, true, -1, kSignatureGenerator,
Allie Woodfdf00512015-03-02 13:34:55 -08001167 false, kInPlaceMinorPayloadVersion);
Darin Petkov9574f7e2011-01-13 10:48:12 -08001168}
1169
Darin Petkovcbfb0172011-01-14 15:24:45 -08001170TEST(DeltaPerformerTest, RunAsRootSmallImageSignNoneTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001171 DoSmallImageTest(false, false, false, -1, kSignatureNone,
Allie Woodfdf00512015-03-02 13:34:55 -08001172 false, kInPlaceMinorPayloadVersion);
Darin Petkovcbfb0172011-01-14 15:24:45 -08001173}
1174
1175TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001176 DoSmallImageTest(false, false, false, -1, kSignatureGenerated,
Allie Woodfdf00512015-03-02 13:34:55 -08001177 true, kInPlaceMinorPayloadVersion);
Darin Petkovcbfb0172011-01-14 15:24:45 -08001178}
1179
1180TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001181 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShell,
Allie Woodfdf00512015-03-02 13:34:55 -08001182 false, kInPlaceMinorPayloadVersion);
Andrew de los Reyes27f7d372010-10-07 11:26:07 -07001183}
1184
Darin Petkov52dcaeb2011-01-14 15:33:06 -08001185TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellBadKeyTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001186 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellBadKey,
Allie Woodfdf00512015-03-02 13:34:55 -08001187 false, kInPlaceMinorPayloadVersion);
Darin Petkov52dcaeb2011-01-14 15:33:06 -08001188}
1189
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -07001190TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellRotateCl1Test) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001191 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellRotateCl1,
Allie Woodfdf00512015-03-02 13:34:55 -08001192 false, kInPlaceMinorPayloadVersion);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -07001193}
1194
1195TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellRotateCl2Test) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001196 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellRotateCl2,
Allie Woodfdf00512015-03-02 13:34:55 -08001197 false, kInPlaceMinorPayloadVersion);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -07001198}
1199
Darin Petkov934bb412010-11-18 11:21:35 -08001200TEST(DeltaPerformerTest, BadDeltaMagicTest) {
Alex Deymo8427b4a2014-11-05 14:00:32 -08001201 MockPrefs prefs;
Jay Srinivasan51dcf262012-09-13 17:24:32 -07001202 InstallPlan install_plan;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001203 FakeSystemState fake_system_state;
1204 DeltaPerformer performer(&prefs, &fake_system_state, &install_plan);
Darin Petkov934bb412010-11-18 11:21:35 -08001205 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0));
1206 EXPECT_TRUE(performer.OpenKernel("/dev/null"));
Don Garrette410e0f2011-11-10 15:39:01 -08001207 EXPECT_TRUE(performer.Write("junk", 4));
1208 EXPECT_TRUE(performer.Write("morejunk", 8));
1209 EXPECT_FALSE(performer.Write("morejunk", 8));
Darin Petkov934bb412010-11-18 11:21:35 -08001210 EXPECT_LT(performer.Close(), 0);
1211}
1212
Andrew de los Reyes353777c2010-10-08 10:34:30 -07001213TEST(DeltaPerformerTest, IsIdempotentOperationTest) {
1214 DeltaArchiveManifest_InstallOperation op;
1215 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
1216 *(op.add_dst_extents()) = ExtentForRange(0, 5);
1217 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
1218 *(op.add_src_extents()) = ExtentForRange(4, 1);
1219 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
1220 op.clear_src_extents();
1221 *(op.add_src_extents()) = ExtentForRange(5, 3);
1222 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
1223 *(op.add_dst_extents()) = ExtentForRange(20, 6);
1224 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
1225 *(op.add_src_extents()) = ExtentForRange(19, 2);
1226 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
1227}
1228
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001229TEST(DeltaPerformerTest, WriteUpdatesPayloadState) {
Alex Deymo8427b4a2014-11-05 14:00:32 -08001230 MockPrefs prefs;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001231 InstallPlan install_plan;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001232 FakeSystemState fake_system_state;
1233 DeltaPerformer performer(&prefs, &fake_system_state, &install_plan);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001234 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0));
1235 EXPECT_TRUE(performer.OpenKernel("/dev/null"));
1236
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001237 EXPECT_CALL(*(fake_system_state.mock_payload_state()),
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001238 DownloadProgress(4)).Times(1);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001239 EXPECT_CALL(*(fake_system_state.mock_payload_state()),
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001240 DownloadProgress(8)).Times(2);
1241
1242 EXPECT_TRUE(performer.Write("junk", 4));
1243 EXPECT_TRUE(performer.Write("morejunk", 8));
1244 EXPECT_FALSE(performer.Write("morejunk", 8));
1245 EXPECT_LT(performer.Close(), 0);
1246}
1247
Jay Srinivasan738fdf32012-12-07 17:40:54 -08001248TEST(DeltaPerformerTest, MissingMandatoryMetadataSizeTest) {
1249 DoMetadataSizeTest(0, 75456, true);
Jay Srinivasan51dcf262012-09-13 17:24:32 -07001250}
1251
Jay Srinivasan738fdf32012-12-07 17:40:54 -08001252TEST(DeltaPerformerTest, MissingNonMandatoryMetadataSizeTest) {
1253 DoMetadataSizeTest(0, 123456, false);
1254}
1255
1256TEST(DeltaPerformerTest, InvalidMandatoryMetadataSizeTest) {
1257 DoMetadataSizeTest(13000, 140000, true);
1258}
1259
1260TEST(DeltaPerformerTest, InvalidNonMandatoryMetadataSizeTest) {
1261 DoMetadataSizeTest(40000, 50000, false);
1262}
1263
1264TEST(DeltaPerformerTest, ValidMandatoryMetadataSizeTest) {
1265 DoMetadataSizeTest(85376, 85376, true);
1266}
1267
1268TEST(DeltaPerformerTest, RunAsRootMandatoryEmptyMetadataSignatureTest) {
1269 DoMetadataSignatureTest(kEmptyMetadataSignature, kSignatureGenerated, true);
1270}
1271
1272TEST(DeltaPerformerTest, RunAsRootNonMandatoryEmptyMetadataSignatureTest) {
1273 DoMetadataSignatureTest(kEmptyMetadataSignature, kSignatureGenerated, false);
1274}
1275
1276TEST(DeltaPerformerTest, RunAsRootMandatoryInvalidMetadataSignatureTest) {
1277 DoMetadataSignatureTest(kInvalidMetadataSignature, kSignatureGenerated, true);
1278}
1279
1280TEST(DeltaPerformerTest, RunAsRootNonMandatoryInvalidMetadataSignatureTest) {
1281 DoMetadataSignatureTest(kInvalidMetadataSignature, kSignatureGenerated,
1282 false);
1283}
1284
1285TEST(DeltaPerformerTest, RunAsRootMandatoryValidMetadataSignature1Test) {
1286 DoMetadataSignatureTest(kValidMetadataSignature, kSignatureNone, true);
1287}
1288
1289TEST(DeltaPerformerTest, RunAsRootMandatoryValidMetadataSignature2Test) {
1290 DoMetadataSignatureTest(kValidMetadataSignature, kSignatureGenerated, true);
1291}
1292
1293TEST(DeltaPerformerTest, RunAsRootNonMandatoryValidMetadataSignatureTest) {
1294 DoMetadataSignatureTest(kValidMetadataSignature, kSignatureGenerated, false);
1295}
1296
1297TEST(DeltaPerformerTest, RunAsRootMandatoryOperationHashMismatchTest) {
1298 DoOperationHashMismatchTest(kInvalidOperationData, true);
1299}
Jay Srinivasan51dcf262012-09-13 17:24:32 -07001300
David Zeuthene7f89172013-10-31 10:21:04 -07001301TEST(DeltaPerformerTest, UsePublicKeyFromResponse) {
Alex Deymo8427b4a2014-11-05 14:00:32 -08001302 MockPrefs prefs;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001303 FakeSystemState fake_system_state;
David Zeuthene7f89172013-10-31 10:21:04 -07001304 InstallPlan install_plan;
1305 base::FilePath key_path;
1306
1307 // The result of the GetPublicKeyResponse() method is based on three things
1308 //
1309 // 1. Whether it's an official build; and
1310 // 2. Whether the Public RSA key to be used is in the root filesystem; and
Alex Vakulenko072359c2014-07-18 11:41:07 -07001311 // 3. Whether the response has a public key
David Zeuthene7f89172013-10-31 10:21:04 -07001312 //
1313 // We test all eight combinations to ensure that we only use the
1314 // public key in the response if
1315 //
1316 // a. it's not an official build; and
1317 // b. there is no key in the root filesystem.
1318
1319 DeltaPerformer *performer = new DeltaPerformer(&prefs,
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001320 &fake_system_state,
David Zeuthene7f89172013-10-31 10:21:04 -07001321 &install_plan);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001322 FakeHardware* fake_hardware = fake_system_state.fake_hardware();
David Zeuthene7f89172013-10-31 10:21:04 -07001323
1324 string temp_dir;
Gilad Arnolda6742b32014-01-11 00:18:34 -08001325 EXPECT_TRUE(utils::MakeTempDirectory("PublicKeyFromResponseTests.XXXXXX",
David Zeuthene7f89172013-10-31 10:21:04 -07001326 &temp_dir));
1327 string non_existing_file = temp_dir + "/non-existing";
1328 string existing_file = temp_dir + "/existing";
Alex Vakulenko75039d72014-03-25 12:36:28 -07001329 EXPECT_EQ(0, System(base::StringPrintf("touch %s", existing_file.c_str())));
David Zeuthene7f89172013-10-31 10:21:04 -07001330
1331 // Non-official build, non-existing public-key, key in response -> true
Don Garrett6646b442013-11-13 15:29:11 -08001332 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001333 performer->public_key_path_ = non_existing_file;
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001334 install_plan.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
David Zeuthene7f89172013-10-31 10:21:04 -07001335 EXPECT_TRUE(performer->GetPublicKeyFromResponse(&key_path));
1336 EXPECT_FALSE(key_path.empty());
1337 EXPECT_EQ(unlink(key_path.value().c_str()), 0);
1338 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -08001339 fake_hardware->SetIsOfficialBuild(true);
David Zeuthene7f89172013-10-31 10:21:04 -07001340 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1341
1342 // Non-official build, existing public-key, key in response -> false
Don Garrett6646b442013-11-13 15:29:11 -08001343 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001344 performer->public_key_path_ = existing_file;
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001345 install_plan.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
David Zeuthene7f89172013-10-31 10:21:04 -07001346 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1347 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -08001348 fake_hardware->SetIsOfficialBuild(true);
David Zeuthene7f89172013-10-31 10:21:04 -07001349 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1350
1351 // Non-official build, non-existing public-key, no key in response -> false
Don Garrett6646b442013-11-13 15:29:11 -08001352 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001353 performer->public_key_path_ = non_existing_file;
1354 install_plan.public_key_rsa = "";
1355 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1356 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -08001357 fake_hardware->SetIsOfficialBuild(true);
David Zeuthene7f89172013-10-31 10:21:04 -07001358 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1359
1360 // Non-official build, existing public-key, no key in response -> false
Don Garrett6646b442013-11-13 15:29:11 -08001361 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001362 performer->public_key_path_ = existing_file;
1363 install_plan.public_key_rsa = "";
1364 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1365 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -08001366 fake_hardware->SetIsOfficialBuild(true);
David Zeuthene7f89172013-10-31 10:21:04 -07001367 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1368
1369 // Non-official build, non-existing public-key, key in response
1370 // but invalid base64 -> false
Don Garrett6646b442013-11-13 15:29:11 -08001371 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001372 performer->public_key_path_ = non_existing_file;
1373 install_plan.public_key_rsa = "not-valid-base64";
1374 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1375
1376 delete performer;
Alex Deymo10875d92014-11-10 21:52:57 -08001377 EXPECT_TRUE(test_utils::RecursiveUnlinkDir(temp_dir));
David Zeuthene7f89172013-10-31 10:21:04 -07001378}
1379
Allie Woodfdf00512015-03-02 13:34:55 -08001380TEST(DeltaPerformerTest, RunAsRootSourceOperationsTest) {
1381 // Make sure we can generate a payload with the new source ops and minor
1382 // version 2. For now, we expect ApplyDeltaFile to fail because the ops are
1383 // not yet implemented, but eventually we can verify the resulting payload.
1384 DeltaState state;
1385 DeltaPerformer* performer = nullptr;
1386 GenerateDeltaFile(false, false, false, -1, kSignatureNone, &state,
1387 kSourceMinorPayloadVersion);
1388 ScopedPathUnlinker a_img_unlinker(state.a_img);
1389 ScopedPathUnlinker b_img_unlinker(state.b_img);
1390 ScopedPathUnlinker delta_unlinker(state.delta_path);
1391 ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
1392 ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
1393 ApplyDeltaFile(false, false, false, kSignatureNone, &state, false,
1394 kValidOperationData, &performer, kSourceMinorPayloadVersion);
1395 delete performer;
1396}
1397
Allie Wood78750a42015-02-11 15:42:11 -08001398TEST(DeltaPerformerTest, MinorVersionsMatch) {
1399 // Test that the minor version in update_engine.conf that is installed to
1400 // the image matches the supported delta minor version in the update engine.
1401 uint32_t minor_version;
1402 base::FilePath conf_path("update_engine.conf");
1403 EXPECT_TRUE(utils::GetMinorVersion(conf_path, &minor_version));
1404 ASSERT_EQ(DeltaPerformer::kSupportedMinorPayloadVersion, minor_version);
1405}
1406
Andrew de los Reyes09e56d62010-04-23 13:45:53 -07001407} // namespace chromeos_update_engine