blob: 4e39c0cba44702b090fef71bbfb92d1f48390e77 [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/string_util.h>
17#include <base/strings/stringprintf.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
Jay Srinivasan738fdf32012-12-07 17:40:54 -080049static const size_t kBlockSize = 4096;
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -070050static const char* kBogusMetadataSignature1 =
51 "awSFIUdUZz2VWFiR+ku0Pj00V7bPQPQFYQSXjEXr3vaw3TE4xHV5CraY3/YrZpBv"
52 "J5z4dSBskoeuaO1TNC/S6E05t+yt36tE4Fh79tMnJ/z9fogBDXWgXLEUyG78IEQr"
53 "YH6/eBsQGT2RJtBgXIXbZ9W+5G9KmGDoPOoiaeNsDuqHiBc/58OFsrxskH8E6vMS"
54 "BmMGGk82mvgzic7ApcoURbCGey1b3Mwne/hPZ/bb9CIyky8Og9IfFMdL2uAweOIR"
55 "fjoTeLYZpt+WN65Vu7jJ0cQN8e1y+2yka5112wpRf/LLtPgiAjEZnsoYpLUd7CoV"
56 "pLRtClp97kN2+tXGNBQqkA==";
Jay Srinivasan738fdf32012-12-07 17:40:54 -080057
Alex Vakulenkod2779df2014-06-16 13:19:00 -070058static const int kDefaultKernelSize = 4096; // Something small for a test
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080059static const uint8_t kNewData[] = {'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
60 'n', 'e', 'w', ' ', 'd', 'a', 't', 'a', '.'};
Jay Srinivasan738fdf32012-12-07 17:40:54 -080061
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070062namespace {
Jay Srinivasan738fdf32012-12-07 17:40:54 -080063struct DeltaState {
64 string a_img;
65 string b_img;
66 int image_size;
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070067
Jay Srinivasan738fdf32012-12-07 17:40:54 -080068 string delta_path;
69 uint64_t metadata_size;
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070070
Jay Srinivasan738fdf32012-12-07 17:40:54 -080071 string old_kernel;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080072 chromeos::Blob old_kernel_data;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070073
Jay Srinivasan738fdf32012-12-07 17:40:54 -080074 string new_kernel;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080075 chromeos::Blob new_kernel_data;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070076
Jay Srinivasan738fdf32012-12-07 17:40:54 -080077 // The in-memory copy of delta file.
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080078 chromeos::Blob delta;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -080079
80 // The mock system state object with which we initialize the
81 // delta performer.
Gilad Arnold5bb4c902014-04-10 12:32:13 -070082 FakeSystemState fake_system_state;
Jay Srinivasan738fdf32012-12-07 17:40:54 -080083};
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070084
Jay Srinivasan738fdf32012-12-07 17:40:54 -080085enum SignatureTest {
86 kSignatureNone, // No payload signing.
87 kSignatureGenerator, // Sign the payload at generation time.
88 kSignatureGenerated, // Sign the payload after it's generated.
Don Garrett2ae37872013-10-25 13:33:20 -070089 kSignatureGeneratedPlaceholder, // Insert placeholder signatures, then real.
Alex Vakulenkod2779df2014-06-16 13:19:00 -070090 kSignatureGeneratedPlaceholderMismatch, // Insert a wrong sized placeholder.
Jay Srinivasan738fdf32012-12-07 17:40:54 -080091 kSignatureGeneratedShell, // Sign the generated payload through shell cmds.
92 kSignatureGeneratedShellBadKey, // Sign with a bad key through shell cmds.
93 kSignatureGeneratedShellRotateCl1, // Rotate key, test client v1
94 kSignatureGeneratedShellRotateCl2, // Rotate key, test client v2
95};
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070096
Jay Srinivasan738fdf32012-12-07 17:40:54 -080097// Different options that determine what we should fill into the
98// install_plan.metadata_signature to simulate the contents received in the
99// Omaha response.
100enum MetadataSignatureTest {
101 kEmptyMetadataSignature,
102 kInvalidMetadataSignature,
103 kValidMetadataSignature,
104};
105
106enum OperationHashTest {
107 kInvalidOperationData,
108 kValidOperationData,
109};
110
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700111} // namespace
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800112
113static void CompareFilesByBlock(const string& a_file, const string& b_file) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800114 chromeos::Blob a_data, b_data;
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700115 EXPECT_TRUE(utils::ReadFile(a_file, &a_data)) << "file failed: " << a_file;
116 EXPECT_TRUE(utils::ReadFile(b_file, &b_data)) << "file failed: " << b_file;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700117
118 EXPECT_EQ(a_data.size(), b_data.size());
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700119 EXPECT_EQ(0, a_data.size() % kBlockSize);
120 for (size_t i = 0; i < a_data.size(); i += kBlockSize) {
121 EXPECT_EQ(0, i % kBlockSize);
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800122 chromeos::Blob a_sub(&a_data[i], &a_data[i + kBlockSize]);
123 chromeos::Blob b_sub(&b_data[i], &b_data[i + kBlockSize]);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700124 EXPECT_TRUE(a_sub == b_sub) << "Block " << (i/kBlockSize) << " differs";
125 }
126}
127
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800128static bool WriteSparseFile(const string& path, off_t size) {
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700129 int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
130 TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
131 ScopedFdCloser fd_closer(&fd);
132 off_t rc = lseek(fd, size + 1, SEEK_SET);
133 TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1));
134 int return_code = ftruncate(fd, size);
135 TEST_AND_RETURN_FALSE_ERRNO(return_code == 0);
136 return true;
137}
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700138
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800139static size_t GetSignatureSize(const string& private_key_path) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800140 const chromeos::Blob data(1, 'x');
141 chromeos::Blob hash;
Darin Petkovcbfb0172011-01-14 15:24:45 -0800142 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(data, &hash));
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800143 chromeos::Blob signature;
Darin Petkovcbfb0172011-01-14 15:24:45 -0800144 EXPECT_TRUE(PayloadSigner::SignHash(hash,
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800145 private_key_path,
Darin Petkovcbfb0172011-01-14 15:24:45 -0800146 &signature));
147 return signature.size();
148}
149
Don Garrett2ae37872013-10-25 13:33:20 -0700150static bool InsertSignaturePlaceholder(int signature_size,
151 const string& payload_path,
152 uint64_t* out_metadata_size) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800153 vector<chromeos::Blob> signatures;
154 signatures.push_back(chromeos::Blob(signature_size, 0));
Don Garrett2ae37872013-10-25 13:33:20 -0700155
156 return PayloadSigner::AddSignatureToPayload(
157 payload_path,
158 signatures,
159 payload_path,
160 out_metadata_size);
161}
162
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800163static void SignGeneratedPayload(const string& payload_path,
164 uint64_t* out_metadata_size) {
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800165 int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800166 chromeos::Blob hash;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700167 ASSERT_TRUE(PayloadSigner::HashPayloadForSigning(
168 payload_path,
169 vector<int>(1, signature_size),
170 &hash));
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800171 chromeos::Blob signature;
Darin Petkovcbfb0172011-01-14 15:24:45 -0800172 ASSERT_TRUE(PayloadSigner::SignHash(hash,
173 kUnittestPrivateKeyPath,
174 &signature));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700175 ASSERT_TRUE(PayloadSigner::AddSignatureToPayload(
176 payload_path,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800177 vector<chromeos::Blob>(1, signature),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800178 payload_path,
179 out_metadata_size));
Alex Deymo923d8fa2014-07-15 17:58:51 -0700180 EXPECT_TRUE(PayloadVerifier::VerifySignedPayload(
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700181 payload_path,
182 kUnittestPublicKeyPath,
183 kSignatureMessageOriginalVersion));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800184}
185
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800186static void SignGeneratedShellPayload(SignatureTest signature_test,
187 const string& payload_path) {
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800188 string private_key_path = kUnittestPrivateKeyPath;
189 if (signature_test == kSignatureGeneratedShellBadKey) {
Gilad Arnolda6742b32014-01-11 00:18:34 -0800190 ASSERT_TRUE(utils::MakeTempFile("key.XXXXXX",
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800191 &private_key_path,
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700192 nullptr));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800193 } else {
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700194 ASSERT_TRUE(signature_test == kSignatureGeneratedShell ||
195 signature_test == kSignatureGeneratedShellRotateCl1 ||
196 signature_test == kSignatureGeneratedShellRotateCl2);
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800197 }
198 ScopedPathUnlinker key_unlinker(private_key_path);
199 key_unlinker.set_should_remove(signature_test ==
200 kSignatureGeneratedShellBadKey);
201 // Generates a new private key that will not match the public key.
202 if (signature_test == kSignatureGeneratedShellBadKey) {
203 LOG(INFO) << "Generating a mismatched private key.";
Alex Deymo719bfff2014-07-11 12:12:32 -0700204 ASSERT_EQ(0, System(base::StringPrintf(
205 "%s genrsa -out %s 2048",
206 utils::GetPathOnBoard("openssl").c_str(), private_key_path.c_str())));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800207 }
208 int signature_size = GetSignatureSize(private_key_path);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800209 string hash_file;
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700210 ASSERT_TRUE(utils::MakeTempFile("hash.XXXXXX", &hash_file, nullptr));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800211 ScopedPathUnlinker hash_unlinker(hash_file);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700212 string signature_size_string;
213 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
214 signature_test == kSignatureGeneratedShellRotateCl2)
Alex Vakulenko75039d72014-03-25 12:36:28 -0700215 signature_size_string = base::StringPrintf("%d:%d",
216 signature_size, signature_size);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700217 else
Alex Vakulenko75039d72014-03-25 12:36:28 -0700218 signature_size_string = base::StringPrintf("%d", signature_size);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800219 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700220 System(base::StringPrintf(
Steve Fung97b6f5a2014-10-07 12:39:51 -0700221 "./delta_generator -in_file=%s -signature_size=%s "
222 "-out_hash_file=%s",
Darin Petkovcbfb0172011-01-14 15:24:45 -0800223 payload_path.c_str(),
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700224 signature_size_string.c_str(),
Darin Petkovcbfb0172011-01-14 15:24:45 -0800225 hash_file.c_str())));
226
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -0700227 // Pad the hash
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800228 chromeos::Blob hash;
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -0700229 ASSERT_TRUE(utils::ReadFile(hash_file, &hash));
Alex Deymo923d8fa2014-07-15 17:58:51 -0700230 ASSERT_TRUE(PayloadVerifier::PadRSA2048SHA256Hash(&hash));
Alex Deymo10875d92014-11-10 21:52:57 -0800231 ASSERT_TRUE(test_utils::WriteFileVector(hash_file, hash));
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -0700232
Darin Petkovcbfb0172011-01-14 15:24:45 -0800233 string sig_file;
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700234 ASSERT_TRUE(utils::MakeTempFile("signature.XXXXXX", &sig_file, nullptr));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800235 ScopedPathUnlinker sig_unlinker(sig_file);
236 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700237 System(base::StringPrintf(
Alex Deymo719bfff2014-07-11 12:12:32 -0700238 "%s rsautl -raw -sign -inkey %s -in %s -out %s",
239 utils::GetPathOnBoard("openssl").c_str(),
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800240 private_key_path.c_str(),
Darin Petkovcbfb0172011-01-14 15:24:45 -0800241 hash_file.c_str(),
242 sig_file.c_str())));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700243 string sig_file2;
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700244 ASSERT_TRUE(utils::MakeTempFile("signature.XXXXXX", &sig_file2, nullptr));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700245 ScopedPathUnlinker sig2_unlinker(sig_file2);
246 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
247 signature_test == kSignatureGeneratedShellRotateCl2) {
248 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700249 System(base::StringPrintf(
Alex Deymo719bfff2014-07-11 12:12:32 -0700250 "%s rsautl -raw -sign -inkey %s -in %s -out %s",
251 utils::GetPathOnBoard("openssl").c_str(),
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700252 kUnittestPrivateKey2Path,
253 hash_file.c_str(),
254 sig_file2.c_str())));
255 // Append second sig file to first path
256 sig_file += ":" + sig_file2;
257 }
258
Darin Petkovcbfb0172011-01-14 15:24:45 -0800259 ASSERT_EQ(0,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700260 System(base::StringPrintf(
Steve Fung97b6f5a2014-10-07 12:39:51 -0700261 "./delta_generator -in_file=%s -signature_file=%s "
262 "-out_file=%s",
Darin Petkovcbfb0172011-01-14 15:24:45 -0800263 payload_path.c_str(),
264 sig_file.c_str(),
265 payload_path.c_str())));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800266 int verify_result =
Alex Vakulenko75039d72014-03-25 12:36:28 -0700267 System(base::StringPrintf(
Steve Fung97b6f5a2014-10-07 12:39:51 -0700268 "./delta_generator -in_file=%s -public_key=%s -public_key_version=%d",
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700269 payload_path.c_str(),
270 signature_test == kSignatureGeneratedShellRotateCl2 ?
271 kUnittestPublicKey2Path : kUnittestPublicKeyPath,
272 signature_test == kSignatureGeneratedShellRotateCl2 ? 2 : 1));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800273 if (signature_test == kSignatureGeneratedShellBadKey) {
274 ASSERT_NE(0, verify_result);
275 } else {
276 ASSERT_EQ(0, verify_result);
277 }
Darin Petkovcbfb0172011-01-14 15:24:45 -0800278}
279
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800280static void GenerateDeltaFile(bool full_kernel,
281 bool full_rootfs,
282 bool noop,
Darin Petkov8e447e02013-04-16 16:23:50 +0200283 off_t chunk_size,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800284 SignatureTest signature_test,
285 DeltaState *state) {
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700286 EXPECT_TRUE(utils::MakeTempFile("a_img.XXXXXX", &state->a_img, nullptr));
287 EXPECT_TRUE(utils::MakeTempFile("b_img.XXXXXX", &state->b_img, nullptr));
Alex Deymo10875d92014-11-10 21:52:57 -0800288 test_utils::CreateExtImageAtPath(state->a_img, nullptr);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700289
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800290 state->image_size = static_cast<int>(utils::FileSize(state->a_img));
Darin Petkov7ea32332010-10-13 10:46:11 -0700291
292 // Extend the "partitions" holding the file system a bit.
293 EXPECT_EQ(0, System(base::StringPrintf(
294 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800295 state->a_img.c_str(),
296 state->image_size + 1024 * 1024 - 1)));
297 EXPECT_EQ(state->image_size + 1024 * 1024, utils::FileSize(state->a_img));
Darin Petkov7ea32332010-10-13 10:46:11 -0700298
Don Garrett0dd39852013-04-03 16:55:42 -0700299 // Create ImageInfo A & B
300 ImageInfo old_image_info;
301 ImageInfo new_image_info;
302
303 if (!full_rootfs) {
304 old_image_info.set_channel("src-channel");
305 old_image_info.set_board("src-board");
306 old_image_info.set_version("src-version");
307 old_image_info.set_key("src-key");
308 old_image_info.set_build_channel("src-build-channel");
309 old_image_info.set_build_version("src-build-version");
310 }
311
312 new_image_info.set_channel("test-channel");
313 new_image_info.set_board("test-board");
314 new_image_info.set_version("test-version");
315 new_image_info.set_key("test-key");
316 new_image_info.set_build_channel("test-build-channel");
317 new_image_info.set_build_version("test-build-version");
318
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700319 // Make some changes to the A image.
320 {
321 string a_mnt;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800322 ScopedLoopMounter b_mounter(state->a_img, &a_mnt, 0);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700323
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800324 chromeos::Blob hardtocompress;
Darin Petkov8e447e02013-04-16 16:23:50 +0200325 while (hardtocompress.size() < 3 * kBlockSize) {
326 hardtocompress.insert(hardtocompress.end(),
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800327 std::begin(kRandomString), std::end(kRandomString));
Darin Petkov8e447e02013-04-16 16:23:50 +0200328 }
Alex Vakulenko75039d72014-03-25 12:36:28 -0700329 EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800330 a_mnt.c_str()).c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700331 hardtocompress.data(),
Darin Petkov8e447e02013-04-16 16:23:50 +0200332 hardtocompress.size()));
333
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800334 chromeos::Blob zeros(16 * 1024, 0);
Darin Petkov8a075a72013-04-25 14:46:09 +0200335 EXPECT_EQ(zeros.size(),
Ben Chan736fcb52014-05-21 18:28:22 -0700336 base::WriteFile(base::FilePath(base::StringPrintf(
337 "%s/move-to-sparse", a_mnt.c_str())),
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800338 reinterpret_cast<const char*>(zeros.data()),
339 zeros.size()));
Darin Petkov8a075a72013-04-25 14:46:09 +0200340
341 EXPECT_TRUE(
Alex Vakulenko75039d72014-03-25 12:36:28 -0700342 WriteSparseFile(base::StringPrintf("%s/move-from-sparse",
343 a_mnt.c_str()), 16 * 1024));
Darin Petkov8a075a72013-04-25 14:46:09 +0200344
Alex Vakulenko75039d72014-03-25 12:36:28 -0700345 EXPECT_EQ(0,
Alex Deymo10875d92014-11-10 21:52:57 -0800346 System(base::StringPrintf("dd if=/dev/zero of=%s/move-semi-sparse"
347 " bs=1 seek=4096 count=1",
348 a_mnt.c_str()).c_str()));
Darin Petkov8a075a72013-04-25 14:46:09 +0200349
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700350 // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
351 // patch fails to zero out the final block.
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800352 chromeos::Blob ones(1024 * 1024, 0xff);
Alex Vakulenko75039d72014-03-25 12:36:28 -0700353 EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/ones",
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800354 a_mnt.c_str()).c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700355 ones.data(),
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700356 ones.size()));
357 }
358
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700359 if (noop) {
Alex Vakulenko75039d72014-03-25 12:36:28 -0700360 EXPECT_TRUE(base::CopyFile(base::FilePath(state->a_img),
361 base::FilePath(state->b_img)));
Don Garrett0dd39852013-04-03 16:55:42 -0700362 old_image_info = new_image_info;
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700363 } else {
Alex Deymo10875d92014-11-10 21:52:57 -0800364 test_utils::CreateExtImageAtPath(state->b_img, nullptr);
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700365 EXPECT_EQ(0, System(base::StringPrintf(
366 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800367 state->b_img.c_str(),
368 state->image_size + 1024 * 1024 - 1)));
369 EXPECT_EQ(state->image_size + 1024 * 1024, utils::FileSize(state->b_img));
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700370
371 // Make some changes to the B image.
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700372 string b_mnt;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800373 ScopedLoopMounter b_mounter(state->b_img, &b_mnt, 0);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700374
Alex Deymo10875d92014-11-10 21:52:57 -0800375 EXPECT_EQ(0, System(base::StringPrintf("cp %s/hello %s/hello2",
Alex Vakulenko75039d72014-03-25 12:36:28 -0700376 b_mnt.c_str(),
377 b_mnt.c_str()).c_str()));
Alex Deymo10875d92014-11-10 21:52:57 -0800378 EXPECT_EQ(0, System(base::StringPrintf("rm %s/hello",
Alex Vakulenko75039d72014-03-25 12:36:28 -0700379 b_mnt.c_str()).c_str()));
Alex Deymo10875d92014-11-10 21:52:57 -0800380 EXPECT_EQ(0, System(base::StringPrintf("mv %s/hello2 %s/hello",
Alex Vakulenko75039d72014-03-25 12:36:28 -0700381 b_mnt.c_str(),
382 b_mnt.c_str()).c_str()));
Alex Deymo10875d92014-11-10 21:52:57 -0800383 EXPECT_EQ(0, System(base::StringPrintf("echo foo > %s/foo",
Alex Vakulenko75039d72014-03-25 12:36:28 -0700384 b_mnt.c_str()).c_str()));
Alex Deymo10875d92014-11-10 21:52:57 -0800385 EXPECT_EQ(0, System(base::StringPrintf("touch %s/emptyfile",
Alex Vakulenko75039d72014-03-25 12:36:28 -0700386 b_mnt.c_str()).c_str()));
387 EXPECT_TRUE(WriteSparseFile(base::StringPrintf("%s/fullsparse",
388 b_mnt.c_str()),
389 1024 * 1024));
Darin Petkov8a075a72013-04-25 14:46:09 +0200390
391 EXPECT_TRUE(
Alex Vakulenko75039d72014-03-25 12:36:28 -0700392 WriteSparseFile(base::StringPrintf("%s/move-to-sparse", b_mnt.c_str()),
Darin Petkov8a075a72013-04-25 14:46:09 +0200393 16 * 1024));
394
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800395 chromeos::Blob zeros(16 * 1024, 0);
Darin Petkov8a075a72013-04-25 14:46:09 +0200396 EXPECT_EQ(zeros.size(),
Ben Chan736fcb52014-05-21 18:28:22 -0700397 base::WriteFile(base::FilePath(base::StringPrintf(
398 "%s/move-from-sparse", b_mnt.c_str())),
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800399 reinterpret_cast<const char*>(zeros.data()),
400 zeros.size()));
Darin Petkov8a075a72013-04-25 14:46:09 +0200401
Alex Deymo10875d92014-11-10 21:52:57 -0800402 EXPECT_EQ(0, System(base::StringPrintf("dd if=/dev/zero "
Alex Vakulenko75039d72014-03-25 12:36:28 -0700403 "of=%s/move-semi-sparse "
404 "bs=1 seek=4096 count=1",
405 b_mnt.c_str()).c_str()));
Darin Petkov8a075a72013-04-25 14:46:09 +0200406
Alex Deymo10875d92014-11-10 21:52:57 -0800407 EXPECT_EQ(0, System(base::StringPrintf("dd if=/dev/zero "
Alex Vakulenko75039d72014-03-25 12:36:28 -0700408 "of=%s/partsparse bs=1 "
409 "seek=4096 count=1",
410 b_mnt.c_str()).c_str()));
Alex Deymo10875d92014-11-10 21:52:57 -0800411 EXPECT_EQ(0, System(base::StringPrintf("cp %s/srchardlink0 %s/tmp && "
Alex Vakulenko75039d72014-03-25 12:36:28 -0700412 "mv %s/tmp %s/srchardlink1",
413 b_mnt.c_str(),
414 b_mnt.c_str(),
415 b_mnt.c_str(),
416 b_mnt.c_str()).c_str()));
Alex Deymo10875d92014-11-10 21:52:57 -0800417 EXPECT_EQ(0, System(
418 base::StringPrintf("rm %s/boguslink && echo foobar > %s/boguslink",
419 b_mnt.c_str(), b_mnt.c_str()).c_str()));
Darin Petkov8e447e02013-04-16 16:23:50 +0200420
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800421 chromeos::Blob hardtocompress;
Darin Petkov8e447e02013-04-16 16:23:50 +0200422 while (hardtocompress.size() < 3 * kBlockSize) {
423 hardtocompress.insert(hardtocompress.end(),
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800424 std::begin(kRandomString), std::end(kRandomString));
Darin Petkov8e447e02013-04-16 16:23:50 +0200425 }
Alex Vakulenko75039d72014-03-25 12:36:28 -0700426 EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700427 b_mnt.c_str()).c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700428 hardtocompress.data(),
Darin Petkov8e447e02013-04-16 16:23:50 +0200429 hardtocompress.size()));
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700430 }
431
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700432 string old_kernel;
Gilad Arnolda6742b32014-01-11 00:18:34 -0800433 EXPECT_TRUE(utils::MakeTempFile("old_kernel.XXXXXX",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800434 &state->old_kernel,
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700435 nullptr));
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700436
437 string new_kernel;
Gilad Arnolda6742b32014-01-11 00:18:34 -0800438 EXPECT_TRUE(utils::MakeTempFile("new_kernel.XXXXXX",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800439 &state->new_kernel,
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700440 nullptr));
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700441
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800442 state->old_kernel_data.resize(kDefaultKernelSize);
443 state->new_kernel_data.resize(state->old_kernel_data.size());
Alex Deymo10875d92014-11-10 21:52:57 -0800444 test_utils::FillWithData(&state->old_kernel_data);
445 test_utils::FillWithData(&state->new_kernel_data);
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700446
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700447 // change the new kernel data
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800448 std::copy(std::begin(kNewData), std::end(kNewData),
449 state->new_kernel_data.begin());
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700450
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700451 if (noop) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800452 state->old_kernel_data = state->new_kernel_data;
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700453 }
454
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700455 // Write kernels to disk
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800456 EXPECT_TRUE(utils::WriteFile(state->old_kernel.c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700457 state->old_kernel_data.data(),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800458 state->old_kernel_data.size()));
459 EXPECT_TRUE(utils::WriteFile(state->new_kernel.c_str(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700460 state->new_kernel_data.data(),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800461 state->new_kernel_data.size()));
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700462
Gilad Arnolda6742b32014-01-11 00:18:34 -0800463 EXPECT_TRUE(utils::MakeTempFile("delta.XXXXXX",
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800464 &state->delta_path,
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700465 nullptr));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800466 LOG(INFO) << "delta path: " << state->delta_path;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700467 {
468 string a_mnt, b_mnt;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800469 ScopedLoopMounter a_mounter(state->a_img, &a_mnt, MS_RDONLY);
470 ScopedLoopMounter b_mounter(state->b_img, &b_mnt, MS_RDONLY);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800471 const string private_key =
472 signature_test == kSignatureGenerator ? kUnittestPrivateKeyPath : "";
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700473 EXPECT_TRUE(
Darin Petkov68c10d12010-10-14 09:24:37 -0700474 DeltaDiffGenerator::GenerateDeltaUpdateFile(
Darin Petkov7a22d792010-11-08 14:10:00 -0800475 full_rootfs ? "" : a_mnt,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800476 full_rootfs ? "" : state->a_img,
Darin Petkov68c10d12010-10-14 09:24:37 -0700477 b_mnt,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800478 state->b_img,
479 full_kernel ? "" : state->old_kernel,
480 state->new_kernel,
481 state->delta_path,
482 private_key,
Darin Petkov8e447e02013-04-16 16:23:50 +0200483 chunk_size,
Chris Sosad5ae1562013-04-23 13:20:18 -0700484 kRootFSPartitionSize,
Allie Woodb8ccad02015-02-09 14:33:40 -0800485 DeltaPerformer::kSupportedMinorPayloadVersion,
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700486 full_rootfs ? nullptr : &old_image_info,
Don Garrett0dd39852013-04-03 16:55:42 -0700487 &new_image_info,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800488 &state->metadata_size));
Darin Petkov9574f7e2011-01-13 10:48:12 -0800489 }
490
Don Garrett2ae37872013-10-25 13:33:20 -0700491 if (signature_test == kSignatureGeneratedPlaceholder ||
492 signature_test == kSignatureGeneratedPlaceholderMismatch) {
Don Garrett2ae37872013-10-25 13:33:20 -0700493 int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
494 LOG(INFO) << "Inserting placeholder signature.";
495 ASSERT_TRUE(InsertSignaturePlaceholder(signature_size, state->delta_path,
496 &state->metadata_size));
497
498 if (signature_test == kSignatureGeneratedPlaceholderMismatch) {
499 signature_size -= 1;
500 LOG(INFO) << "Inserting mismatched placeholder signature.";
501 ASSERT_FALSE(InsertSignaturePlaceholder(signature_size, state->delta_path,
502 &state->metadata_size));
503 return;
504 }
505 }
506
507 if (signature_test == kSignatureGenerated ||
508 signature_test == kSignatureGeneratedPlaceholder ||
509 signature_test == kSignatureGeneratedPlaceholderMismatch) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800510 // Generate the signed payload and update the metadata size in state to
511 // reflect the new size after adding the signature operation to the
512 // manifest.
Don Garrett2ae37872013-10-25 13:33:20 -0700513 LOG(INFO) << "Signing payload.";
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800514 SignGeneratedPayload(state->delta_path, &state->metadata_size);
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800515 } else if (signature_test == kSignatureGeneratedShell ||
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700516 signature_test == kSignatureGeneratedShellBadKey ||
517 signature_test == kSignatureGeneratedShellRotateCl1 ||
518 signature_test == kSignatureGeneratedShellRotateCl2) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800519 SignGeneratedShellPayload(signature_test, state->delta_path);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700520 }
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800521}
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700522
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800523static void ApplyDeltaFile(bool full_kernel, bool full_rootfs, bool noop,
524 SignatureTest signature_test, DeltaState* state,
525 bool hash_checks_mandatory,
526 OperationHashTest op_hash_test,
527 DeltaPerformer** performer) {
Darin Petkov36a58222010-10-07 22:00:09 -0700528 // Check the metadata.
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700529 {
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700530 DeltaArchiveManifest manifest;
Alex Deymo923d8fa2014-07-15 17:58:51 -0700531 EXPECT_TRUE(PayloadVerifier::LoadPayload(state->delta_path,
532 &state->delta,
533 &manifest,
534 &state->metadata_size));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800535 LOG(INFO) << "Metadata size: " << state->metadata_size;
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700536
Don Garrett0dd39852013-04-03 16:55:42 -0700537
538
Darin Petkovcbfb0172011-01-14 15:24:45 -0800539 if (signature_test == kSignatureNone) {
540 EXPECT_FALSE(manifest.has_signatures_offset());
541 EXPECT_FALSE(manifest.has_signatures_size());
542 } else {
543 EXPECT_TRUE(manifest.has_signatures_offset());
544 EXPECT_TRUE(manifest.has_signatures_size());
545 Signatures sigs_message;
546 EXPECT_TRUE(sigs_message.ParseFromArray(
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800547 &state->delta[state->metadata_size + manifest.signatures_offset()],
Darin Petkovcbfb0172011-01-14 15:24:45 -0800548 manifest.signatures_size()));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700549 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
550 signature_test == kSignatureGeneratedShellRotateCl2)
551 EXPECT_EQ(2, sigs_message.signatures_size());
552 else
553 EXPECT_EQ(1, sigs_message.signatures_size());
Darin Petkovcbfb0172011-01-14 15:24:45 -0800554 const Signatures_Signature& signature = sigs_message.signatures(0);
555 EXPECT_EQ(1, signature.version());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700556
Darin Petkovcbfb0172011-01-14 15:24:45 -0800557 uint64_t expected_sig_data_length = 0;
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700558 vector<string> key_paths{kUnittestPrivateKeyPath};
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700559 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
560 signature_test == kSignatureGeneratedShellRotateCl2) {
561 key_paths.push_back(kUnittestPrivateKey2Path);
562 }
Darin Petkovcbfb0172011-01-14 15:24:45 -0800563 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700564 key_paths,
565 &expected_sig_data_length));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800566 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
567 EXPECT_FALSE(signature.data().empty());
568 }
Darin Petkov36a58222010-10-07 22:00:09 -0700569
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700570 if (noop) {
Gilad Arnold063181c2015-02-05 12:24:49 -0800571 EXPECT_EQ(0, manifest.install_operations_size());
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700572 EXPECT_EQ(1, manifest.kernel_install_operations_size());
573 }
574
Darin Petkovd43d6902010-10-14 11:17:50 -0700575 if (full_kernel) {
576 EXPECT_FALSE(manifest.has_old_kernel_info());
577 } else {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800578 EXPECT_EQ(state->old_kernel_data.size(),
579 manifest.old_kernel_info().size());
Darin Petkovd43d6902010-10-14 11:17:50 -0700580 EXPECT_FALSE(manifest.old_kernel_info().hash().empty());
581 }
Darin Petkov698d0412010-10-13 10:59:44 -0700582
Don Garrett0dd39852013-04-03 16:55:42 -0700583 EXPECT_EQ(manifest.new_image_info().channel(), "test-channel");
584 EXPECT_EQ(manifest.new_image_info().board(), "test-board");
585 EXPECT_EQ(manifest.new_image_info().version(), "test-version");
586 EXPECT_EQ(manifest.new_image_info().key(), "test-key");
587 EXPECT_EQ(manifest.new_image_info().build_channel(), "test-build-channel");
588 EXPECT_EQ(manifest.new_image_info().build_version(), "test-build-version");
589
590 if (!full_rootfs) {
Don Garrett0dd39852013-04-03 16:55:42 -0700591 if (noop) {
592 EXPECT_EQ(manifest.old_image_info().channel(), "test-channel");
593 EXPECT_EQ(manifest.old_image_info().board(), "test-board");
594 EXPECT_EQ(manifest.old_image_info().version(), "test-version");
595 EXPECT_EQ(manifest.old_image_info().key(), "test-key");
596 EXPECT_EQ(manifest.old_image_info().build_channel(),
597 "test-build-channel");
598 EXPECT_EQ(manifest.old_image_info().build_version(),
599 "test-build-version");
600 } else {
601 EXPECT_EQ(manifest.old_image_info().channel(), "src-channel");
602 EXPECT_EQ(manifest.old_image_info().board(), "src-board");
603 EXPECT_EQ(manifest.old_image_info().version(), "src-version");
604 EXPECT_EQ(manifest.old_image_info().key(), "src-key");
605 EXPECT_EQ(manifest.old_image_info().build_channel(),
606 "src-build-channel");
607 EXPECT_EQ(manifest.old_image_info().build_version(),
608 "src-build-version");
609 }
610 }
611
612
Darin Petkov7a22d792010-11-08 14:10:00 -0800613 if (full_rootfs) {
614 EXPECT_FALSE(manifest.has_old_rootfs_info());
Don Garrett0dd39852013-04-03 16:55:42 -0700615 EXPECT_FALSE(manifest.has_old_image_info());
616 EXPECT_TRUE(manifest.has_new_image_info());
Darin Petkov7a22d792010-11-08 14:10:00 -0800617 } else {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800618 EXPECT_EQ(state->image_size, manifest.old_rootfs_info().size());
Darin Petkov7a22d792010-11-08 14:10:00 -0800619 EXPECT_FALSE(manifest.old_rootfs_info().hash().empty());
620 }
621
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800622 EXPECT_EQ(state->new_kernel_data.size(), manifest.new_kernel_info().size());
623 EXPECT_EQ(state->image_size, manifest.new_rootfs_info().size());
Darin Petkov36a58222010-10-07 22:00:09 -0700624
Darin Petkov36a58222010-10-07 22:00:09 -0700625 EXPECT_FALSE(manifest.new_kernel_info().hash().empty());
Darin Petkov36a58222010-10-07 22:00:09 -0700626 EXPECT_FALSE(manifest.new_rootfs_info().hash().empty());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700627 }
628
Alex Deymo8427b4a2014-11-05 14:00:32 -0800629 MockPrefs prefs;
Darin Petkov73058b42010-10-06 16:32:19 -0700630 EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800631 state->metadata_size)).WillOnce(Return(true));
Darin Petkov73058b42010-10-06 16:32:19 -0700632 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
633 .WillRepeatedly(Return(true));
Darin Petkov9b230572010-10-08 10:20:09 -0700634 EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
635 .WillOnce(Return(false));
Darin Petkov73058b42010-10-06 16:32:19 -0700636 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
637 .WillRepeatedly(Return(true));
David Zeuthen41996ad2013-09-24 15:43:24 -0700638 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataLength, _))
639 .WillRepeatedly(Return(true));
Darin Petkov437adc42010-10-07 13:12:24 -0700640 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
Darin Petkov73058b42010-10-06 16:32:19 -0700641 .WillRepeatedly(Return(true));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800642 if (op_hash_test == kValidOperationData && signature_test != kSignatureNone) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800643 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
644 .WillOnce(Return(true));
Darin Petkov4f0a07b2011-05-25 16:47:20 -0700645 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
646 .WillOnce(Return(true));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800647 }
Darin Petkov73058b42010-10-06 16:32:19 -0700648
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700649 // Update the A image in place.
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700650 InstallPlan install_plan;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800651 install_plan.hash_checks_mandatory = hash_checks_mandatory;
652 install_plan.metadata_size = state->metadata_size;
Don Garrettb8dd1d92013-11-22 17:40:02 -0800653 install_plan.is_full_update = full_kernel && full_rootfs;
654
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800655 LOG(INFO) << "Setting payload metadata size in Omaha = "
656 << state->metadata_size;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700657 ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
Alex Vakulenko75039d72014-03-25 12:36:28 -0700658 state->delta.data(),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800659 state->metadata_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700660 kUnittestPrivateKeyPath,
Jay Srinivasanf4318702012-09-24 11:56:24 -0700661 &install_plan.metadata_signature));
662 EXPECT_FALSE(install_plan.metadata_signature.empty());
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700663
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800664 *performer = new DeltaPerformer(&prefs,
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700665 &state->fake_system_state,
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800666 &install_plan);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700667 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800668 (*performer)->set_public_key_path(kUnittestPublicKeyPath);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700669
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800670 EXPECT_EQ(state->image_size,
671 OmahaHashCalculator::RawHashOfFile(state->a_img,
672 state->image_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700673 &install_plan.rootfs_hash));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800674 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(state->old_kernel_data,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700675 &install_plan.kernel_hash));
676
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800677 EXPECT_EQ(0, (*performer)->Open(state->a_img.c_str(), 0, 0));
678 EXPECT_TRUE((*performer)->OpenKernel(state->old_kernel.c_str()));
679
David Zeuthena99981f2013-04-29 13:42:47 -0700680 ErrorCode expected_error, actual_error;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800681 bool continue_writing;
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700682 switch (op_hash_test) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800683 case kInvalidOperationData: {
684 // Muck with some random offset post the metadata size so that
685 // some operation hash will result in a mismatch.
686 int some_offset = state->metadata_size + 300;
687 LOG(INFO) << "Tampered value at offset: " << some_offset;
688 state->delta[some_offset]++;
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700689 expected_error = ErrorCode::kDownloadOperationHashMismatch;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800690 continue_writing = false;
691 break;
692 }
693
694 case kValidOperationData:
695 default:
696 // no change.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700697 expected_error = ErrorCode::kSuccess;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800698 continue_writing = true;
699 break;
700 }
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700701
702 // Write at some number of bytes per operation. Arbitrarily chose 5.
703 const size_t kBytesPerWrite = 5;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800704 for (size_t i = 0; i < state->delta.size(); i += kBytesPerWrite) {
Alex Deymof329b932014-10-30 01:37:48 -0700705 size_t count = std::min(state->delta.size() - i, kBytesPerWrite);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800706 bool write_succeeded = ((*performer)->Write(&state->delta[i],
707 count,
708 &actual_error));
709 // Normally write_succeeded should be true every time and
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700710 // actual_error should be ErrorCode::kSuccess. If so, continue the loop.
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800711 // But if we seeded an operation hash error above, then write_succeeded
712 // will be false. The failure may happen at any operation n. So, all
713 // Writes until n-1 should succeed and the nth operation will fail with
714 // actual_error. In this case, we should bail out of the loop because
715 // we cannot proceed applying the delta.
716 if (!write_succeeded) {
717 LOG(INFO) << "Write failed. Checking if it failed with expected error";
718 EXPECT_EQ(expected_error, actual_error);
719 if (!continue_writing) {
720 LOG(INFO) << "Cannot continue writing. Bailing out.";
721 break;
722 }
723 }
724
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700725 EXPECT_EQ(ErrorCode::kSuccess, actual_error);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700726 }
727
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800728 // If we had continued all the way through, Close should succeed.
729 // Otherwise, it should fail. Check appropriately.
730 bool close_result = (*performer)->Close();
731 if (continue_writing)
732 EXPECT_EQ(0, close_result);
733 else
734 EXPECT_LE(0, close_result);
735}
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700736
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800737void VerifyPayloadResult(DeltaPerformer* performer,
738 DeltaState* state,
David Zeuthena99981f2013-04-29 13:42:47 -0700739 ErrorCode expected_result) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800740 if (!performer) {
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700741 EXPECT_TRUE(!"Skipping payload verification since performer is null.");
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800742 return;
743 }
744
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700745 int expected_times = (expected_result == ErrorCode::kSuccess) ? 1 : 0;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700746 EXPECT_CALL(*(state->fake_system_state.mock_payload_state()),
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800747 DownloadComplete()).Times(expected_times);
748
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800749 LOG(INFO) << "Verifying payload for expected result "
750 << expected_result;
751 EXPECT_EQ(expected_result, performer->VerifyPayload(
752 OmahaHashCalculator::OmahaHashOfData(state->delta),
753 state->delta.size()));
754 LOG(INFO) << "Verified payload.";
755
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700756 if (expected_result != ErrorCode::kSuccess) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800757 // no need to verify new partition if VerifyPayload failed.
758 return;
759 }
760
761 CompareFilesByBlock(state->old_kernel, state->new_kernel);
762 CompareFilesByBlock(state->a_img, state->b_img);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700763
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800764 chromeos::Blob updated_kernel_partition;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800765 EXPECT_TRUE(utils::ReadFile(state->old_kernel, &updated_kernel_partition));
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800766 ASSERT_GE(updated_kernel_partition.size(), arraysize(kNewData));
767 EXPECT_TRUE(std::equal(std::begin(kNewData), std::end(kNewData),
768 updated_kernel_partition.begin()));
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700769
770 uint64_t new_kernel_size;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800771 chromeos::Blob new_kernel_hash;
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700772 uint64_t new_rootfs_size;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800773 chromeos::Blob new_rootfs_hash;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800774 EXPECT_TRUE(performer->GetNewPartitionInfo(&new_kernel_size,
Don Garrett0dd39852013-04-03 16:55:42 -0700775 &new_kernel_hash,
776 &new_rootfs_size,
777 &new_rootfs_hash));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800778 EXPECT_EQ(kDefaultKernelSize, new_kernel_size);
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800779 chromeos::Blob expected_new_kernel_hash;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800780 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(state->new_kernel_data,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700781 &expected_new_kernel_hash));
782 EXPECT_TRUE(expected_new_kernel_hash == new_kernel_hash);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800783 EXPECT_EQ(state->image_size, new_rootfs_size);
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800784 chromeos::Blob expected_new_rootfs_hash;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800785 EXPECT_EQ(state->image_size,
786 OmahaHashCalculator::RawHashOfFile(state->b_img,
787 state->image_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700788 &expected_new_rootfs_hash));
789 EXPECT_TRUE(expected_new_rootfs_hash == new_rootfs_hash);
790}
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800791
792void VerifyPayload(DeltaPerformer* performer,
793 DeltaState* state,
794 SignatureTest signature_test) {
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700795 ErrorCode expected_result = ErrorCode::kSuccess;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800796 switch (signature_test) {
797 case kSignatureNone:
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700798 expected_result = ErrorCode::kSignedDeltaPayloadExpectedError;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800799 break;
800 case kSignatureGeneratedShellBadKey:
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700801 expected_result = ErrorCode::kDownloadPayloadPubKeyVerificationError;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800802 break;
803 default: break; // appease gcc
804 }
805
806 VerifyPayloadResult(performer, state, expected_result);
807}
808
809void DoSmallImageTest(bool full_kernel, bool full_rootfs, bool noop,
Darin Petkov8e447e02013-04-16 16:23:50 +0200810 off_t chunk_size,
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800811 SignatureTest signature_test,
812 bool hash_checks_mandatory) {
813 DeltaState state;
Alex Deymo52146ce2014-05-29 11:09:45 -0700814 DeltaPerformer *performer = nullptr;
Darin Petkov8e447e02013-04-16 16:23:50 +0200815 GenerateDeltaFile(full_kernel, full_rootfs, noop, chunk_size,
816 signature_test, &state);
Don Garrett0dd39852013-04-03 16:55:42 -0700817
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800818 ScopedPathUnlinker a_img_unlinker(state.a_img);
819 ScopedPathUnlinker b_img_unlinker(state.b_img);
820 ScopedPathUnlinker delta_unlinker(state.delta_path);
821 ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
822 ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
823 ApplyDeltaFile(full_kernel, full_rootfs, noop, signature_test,
824 &state, hash_checks_mandatory, kValidOperationData,
825 &performer);
826 VerifyPayload(performer, &state, signature_test);
Alex Deymo52146ce2014-05-29 11:09:45 -0700827 delete performer;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800828}
829
830// Calls delta performer's Write method by pretending to pass in bytes from a
831// delta file whose metadata size is actual_metadata_size and tests if all
832// checks are correctly performed if the install plan contains
833// expected_metadata_size and that the result of the parsing are as per
834// hash_checks_mandatory flag.
835void DoMetadataSizeTest(uint64_t expected_metadata_size,
836 uint64_t actual_metadata_size,
837 bool hash_checks_mandatory) {
Alex Deymo8427b4a2014-11-05 14:00:32 -0800838 MockPrefs prefs;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800839 InstallPlan install_plan;
840 install_plan.hash_checks_mandatory = hash_checks_mandatory;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700841 FakeSystemState fake_system_state;
842 DeltaPerformer performer(&prefs, &fake_system_state, &install_plan);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800843 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0));
844 EXPECT_TRUE(performer.OpenKernel("/dev/null"));
845
846 // Set a valid magic string and version number 1.
847 EXPECT_TRUE(performer.Write("CrAU", 4));
848 uint64_t version = htobe64(1);
849 EXPECT_TRUE(performer.Write(&version, 8));
850
851 install_plan.metadata_size = expected_metadata_size;
David Zeuthena99981f2013-04-29 13:42:47 -0700852 ErrorCode error_code;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800853 // When filling in size in manifest, exclude the size of the 20-byte header.
854 uint64_t size_in_manifest = htobe64(actual_metadata_size - 20);
855 bool result = performer.Write(&size_in_manifest, 8, &error_code);
856 if (expected_metadata_size == actual_metadata_size ||
857 !hash_checks_mandatory) {
858 EXPECT_TRUE(result);
859 } else {
860 EXPECT_FALSE(result);
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700861 EXPECT_EQ(ErrorCode::kDownloadInvalidMetadataSize, error_code);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800862 }
863
864 EXPECT_LT(performer.Close(), 0);
865}
866
867// Generates a valid delta file but tests the delta performer by suppling
868// different metadata signatures as per omaha_metadata_signature flag and
869// sees if the result of the parsing are as per hash_checks_mandatory flag.
870void DoMetadataSignatureTest(MetadataSignatureTest metadata_signature_test,
871 SignatureTest signature_test,
872 bool hash_checks_mandatory) {
873 DeltaState state;
874
875 // Using kSignatureNone since it doesn't affect the results of our test.
876 // If we've to use other signature options, then we'd have to get the
877 // metadata size again after adding the signing operation to the manifest.
Darin Petkov8e447e02013-04-16 16:23:50 +0200878 GenerateDeltaFile(true, true, false, -1, signature_test, &state);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800879
880 ScopedPathUnlinker a_img_unlinker(state.a_img);
881 ScopedPathUnlinker b_img_unlinker(state.b_img);
882 ScopedPathUnlinker delta_unlinker(state.delta_path);
883 ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
884 ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
885
886 // Loads the payload and parses the manifest.
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800887 chromeos::Blob payload;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800888 EXPECT_TRUE(utils::ReadFile(state.delta_path, &payload));
889 LOG(INFO) << "Payload size: " << payload.size();
890
891 InstallPlan install_plan;
892 install_plan.hash_checks_mandatory = hash_checks_mandatory;
893 install_plan.metadata_size = state.metadata_size;
894
895 DeltaPerformer::MetadataParseResult expected_result, actual_result;
David Zeuthena99981f2013-04-29 13:42:47 -0700896 ErrorCode expected_error, actual_error;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800897
898 // Fill up the metadata signature in install plan according to the test.
899 switch (metadata_signature_test) {
900 case kEmptyMetadataSignature:
901 install_plan.metadata_signature.clear();
902 expected_result = DeltaPerformer::kMetadataParseError;
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700903 expected_error = ErrorCode::kDownloadMetadataSignatureMissingError;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800904 break;
905
906 case kInvalidMetadataSignature:
907 install_plan.metadata_signature = kBogusMetadataSignature1;
908 expected_result = DeltaPerformer::kMetadataParseError;
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700909 expected_error = ErrorCode::kDownloadMetadataSignatureMismatch;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800910 break;
911
912 case kValidMetadataSignature:
913 default:
914 // Set the install plan's metadata size to be the same as the one
915 // in the manifest so that we pass the metadata size checks. Only
916 // then we can get to manifest signature checks.
917 ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
Alex Vakulenko75039d72014-03-25 12:36:28 -0700918 payload.data(),
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800919 state.metadata_size,
920 kUnittestPrivateKeyPath,
921 &install_plan.metadata_signature));
922 EXPECT_FALSE(install_plan.metadata_signature.empty());
923 expected_result = DeltaPerformer::kMetadataParseSuccess;
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700924 expected_error = ErrorCode::kSuccess;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800925 break;
926 }
927
928 // Ignore the expected result/error if hash checks are not mandatory.
929 if (!hash_checks_mandatory) {
930 expected_result = DeltaPerformer::kMetadataParseSuccess;
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700931 expected_error = ErrorCode::kSuccess;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800932 }
933
934 // Create the delta performer object.
Alex Deymo8427b4a2014-11-05 14:00:32 -0800935 MockPrefs prefs;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800936 DeltaPerformer delta_performer(&prefs,
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700937 &state.fake_system_state,
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800938 &install_plan);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800939
940 // Use the public key corresponding to the private key used above to
941 // sign the metadata.
942 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
943 delta_performer.set_public_key_path(kUnittestPublicKeyPath);
944
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800945 // Init actual_error with an invalid value so that we make sure
946 // ParsePayloadMetadata properly populates it in all cases.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700947 actual_error = ErrorCode::kUmaReportedMax;
Gilad Arnolddaa27402014-01-23 11:56:17 -0800948 actual_result = delta_performer.ParsePayloadMetadata(payload, &actual_error);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800949
950 EXPECT_EQ(expected_result, actual_result);
951 EXPECT_EQ(expected_error, actual_error);
952
953 // Check that the parsed metadata size is what's expected. This test
954 // implicitly confirms that the metadata signature is valid, if required.
Gilad Arnoldfe133932014-01-14 12:25:50 -0800955 EXPECT_EQ(state.metadata_size, delta_performer.GetMetadataSize());
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800956}
957
958void DoOperationHashMismatchTest(OperationHashTest op_hash_test,
959 bool hash_checks_mandatory) {
960 DeltaState state;
Darin Petkov8e447e02013-04-16 16:23:50 +0200961 GenerateDeltaFile(true, true, false, -1, kSignatureGenerated, &state);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800962 ScopedPathUnlinker a_img_unlinker(state.a_img);
963 ScopedPathUnlinker b_img_unlinker(state.b_img);
964 ScopedPathUnlinker delta_unlinker(state.delta_path);
965 ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
966 ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
Alex Deymo52146ce2014-05-29 11:09:45 -0700967 DeltaPerformer *performer = nullptr;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800968 ApplyDeltaFile(true, true, false, kSignatureGenerated,
969 &state, hash_checks_mandatory, op_hash_test, &performer);
Alex Deymo52146ce2014-05-29 11:09:45 -0700970 delete performer;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800971}
972
Don Garrettb8dd1d92013-11-22 17:40:02 -0800973
974class DeltaPerformerTest : public ::testing::Test {
Don Garrettb8dd1d92013-11-22 17:40:02 -0800975 public:
976 // Test helper placed where it can easily be friended from DeltaPerformer.
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700977 static void RunManifestValidation(const DeltaArchiveManifest& manifest,
Don Garrettb8dd1d92013-11-22 17:40:02 -0800978 bool full_payload,
979 ErrorCode expected) {
Alex Deymo8427b4a2014-11-05 14:00:32 -0800980 MockPrefs prefs;
Don Garrettb8dd1d92013-11-22 17:40:02 -0800981 InstallPlan install_plan;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700982 FakeSystemState fake_system_state;
983 DeltaPerformer performer(&prefs, &fake_system_state, &install_plan);
Don Garrettb8dd1d92013-11-22 17:40:02 -0800984
985 // The install plan is for Full or Delta.
986 install_plan.is_full_update = full_payload;
987
988 // The Manifest we are validating.
989 performer.manifest_.CopyFrom(manifest);
990
991 EXPECT_EQ(expected, performer.ValidateManifest());
992 }
993};
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800994
995TEST(DeltaPerformerTest, ExtentsToByteStringTest) {
996 uint64_t test[] = {1, 1, 4, 2, kSparseHole, 1, 0, 1};
997 COMPILE_ASSERT(arraysize(test) % 2 == 0, array_size_uneven);
998 const uint64_t block_size = 4096;
999 const uint64_t file_length = 5 * block_size - 13;
1000
1001 google::protobuf::RepeatedPtrField<Extent> extents;
1002 for (size_t i = 0; i < arraysize(test); i += 2) {
1003 Extent* extent = extents.Add();
1004 extent->set_start_block(test[i]);
1005 extent->set_num_blocks(test[i + 1]);
1006 }
1007
1008 string expected_output = "4096:4096,16384:8192,-1:4096,0:4083";
1009 string actual_output;
1010 EXPECT_TRUE(DeltaPerformer::ExtentsToBsdiffPositionsString(extents,
1011 block_size,
1012 file_length,
1013 &actual_output));
1014 EXPECT_EQ(expected_output, actual_output);
1015}
Darin Petkov68c10d12010-10-14 09:24:37 -07001016
Don Garrettb8dd1d92013-11-22 17:40:02 -08001017TEST(DeltaPerformerTest, ValidateManifestFullGoodTest) {
1018 // The Manifest we are validating.
1019 DeltaArchiveManifest manifest;
1020 manifest.mutable_new_kernel_info();
1021 manifest.mutable_new_rootfs_info();
1022 manifest.set_minor_version(DeltaPerformer::kFullPayloadMinorVersion);
1023
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001024 DeltaPerformerTest::RunManifestValidation(manifest, true,
1025 ErrorCode::kSuccess);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001026}
1027
1028TEST(DeltaPerformerTest, ValidateManifestDeltaGoodTest) {
1029 // The Manifest we are validating.
1030 DeltaArchiveManifest manifest;
1031 manifest.mutable_old_kernel_info();
1032 manifest.mutable_old_rootfs_info();
1033 manifest.mutable_new_kernel_info();
1034 manifest.mutable_new_rootfs_info();
1035 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
1036
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001037 DeltaPerformerTest::RunManifestValidation(manifest, false,
1038 ErrorCode::kSuccess);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001039}
1040
1041TEST(DeltaPerformerTest, ValidateManifestFullUnsetMinorVersion) {
1042 // The Manifest we are validating.
1043 DeltaArchiveManifest manifest;
1044
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001045 DeltaPerformerTest::RunManifestValidation(manifest, true,
1046 ErrorCode::kSuccess);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001047}
1048
1049TEST(DeltaPerformerTest, ValidateManifestDeltaUnsetMinorVersion) {
1050 // The Manifest we are validating.
1051 DeltaArchiveManifest manifest;
1052
1053 DeltaPerformerTest::RunManifestValidation(
1054 manifest, false,
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001055 ErrorCode::kUnsupportedMinorPayloadVersion);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001056}
1057
1058TEST(DeltaPerformerTest, ValidateManifestFullOldKernelTest) {
1059 // The Manifest we are validating.
1060 DeltaArchiveManifest manifest;
1061 manifest.mutable_old_kernel_info();
1062 manifest.mutable_new_kernel_info();
1063 manifest.mutable_new_rootfs_info();
1064 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
1065
1066 DeltaPerformerTest::RunManifestValidation(
1067 manifest, true,
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001068 ErrorCode::kPayloadMismatchedType);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001069}
1070
1071TEST(DeltaPerformerTest, ValidateManifestFullOldRootfsTest) {
1072 // The Manifest we are validating.
1073 DeltaArchiveManifest manifest;
1074 manifest.mutable_old_rootfs_info();
1075 manifest.mutable_new_kernel_info();
1076 manifest.mutable_new_rootfs_info();
1077 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
1078
1079 DeltaPerformerTest::RunManifestValidation(
1080 manifest, true,
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001081 ErrorCode::kPayloadMismatchedType);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001082}
1083
1084TEST(DeltaPerformerTest, ValidateManifestBadMinorVersion) {
1085 // The Manifest we are validating.
1086 DeltaArchiveManifest manifest;
1087
1088 // Generate a bad version number.
1089 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion +
1090 10000);
1091
1092 DeltaPerformerTest::RunManifestValidation(
1093 manifest, false,
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001094 ErrorCode::kUnsupportedMinorPayloadVersion);
Don Garrettb8dd1d92013-11-22 17:40:02 -08001095}
1096
Darin Petkov68c10d12010-10-14 09:24:37 -07001097TEST(DeltaPerformerTest, RunAsRootSmallImageTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001098 DoSmallImageTest(false, false, false, -1, kSignatureGenerator,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001099 false);
Darin Petkov8e447e02013-04-16 16:23:50 +02001100}
1101
Don Garrett2ae37872013-10-25 13:33:20 -07001102TEST(DeltaPerformerTest, RunAsRootSmallImageSignaturePlaceholderTest) {
1103 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedPlaceholder,
1104 false);
1105}
1106
1107TEST(DeltaPerformerTest, RunAsRootSmallImageSignaturePlaceholderMismatchTest) {
1108 DeltaState state;
1109 GenerateDeltaFile(false, false, false, -1,
1110 kSignatureGeneratedPlaceholderMismatch, &state);
1111}
1112
Darin Petkov8e447e02013-04-16 16:23:50 +02001113TEST(DeltaPerformerTest, RunAsRootSmallImageChunksTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001114 DoSmallImageTest(false, false, false, kBlockSize, kSignatureGenerator,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001115 false);
Darin Petkov68c10d12010-10-14 09:24:37 -07001116}
1117
1118TEST(DeltaPerformerTest, RunAsRootFullKernelSmallImageTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001119 DoSmallImageTest(true, false, false, -1, kSignatureGenerator,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001120 false);
Darin Petkov7a22d792010-11-08 14:10:00 -08001121}
1122
1123TEST(DeltaPerformerTest, RunAsRootFullSmallImageTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001124 DoSmallImageTest(true, true, false, -1, kSignatureGenerator,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001125 true);
Darin Petkov9fa7ec52010-10-18 11:45:23 -07001126}
1127
1128TEST(DeltaPerformerTest, RunAsRootNoopSmallImageTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001129 DoSmallImageTest(false, false, true, -1, kSignatureGenerator,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001130 false);
Darin Petkov9574f7e2011-01-13 10:48:12 -08001131}
1132
Darin Petkovcbfb0172011-01-14 15:24:45 -08001133TEST(DeltaPerformerTest, RunAsRootSmallImageSignNoneTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001134 DoSmallImageTest(false, false, false, -1, kSignatureNone,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001135 false);
Darin Petkovcbfb0172011-01-14 15:24:45 -08001136}
1137
1138TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001139 DoSmallImageTest(false, false, false, -1, kSignatureGenerated,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001140 true);
Darin Petkovcbfb0172011-01-14 15:24:45 -08001141}
1142
1143TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001144 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShell,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001145 false);
Andrew de los Reyes27f7d372010-10-07 11:26:07 -07001146}
1147
Darin Petkov52dcaeb2011-01-14 15:33:06 -08001148TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellBadKeyTest) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001149 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellBadKey,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001150 false);
Darin Petkov52dcaeb2011-01-14 15:33:06 -08001151}
1152
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -07001153TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellRotateCl1Test) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001154 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellRotateCl1,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001155 false);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -07001156}
1157
1158TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellRotateCl2Test) {
Darin Petkov8e447e02013-04-16 16:23:50 +02001159 DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellRotateCl2,
Gilad Arnold434eb0c2013-07-22 06:47:52 -07001160 false);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -07001161}
1162
Darin Petkov934bb412010-11-18 11:21:35 -08001163TEST(DeltaPerformerTest, BadDeltaMagicTest) {
Alex Deymo8427b4a2014-11-05 14:00:32 -08001164 MockPrefs prefs;
Jay Srinivasan51dcf262012-09-13 17:24:32 -07001165 InstallPlan install_plan;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001166 FakeSystemState fake_system_state;
1167 DeltaPerformer performer(&prefs, &fake_system_state, &install_plan);
Darin Petkov934bb412010-11-18 11:21:35 -08001168 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0));
1169 EXPECT_TRUE(performer.OpenKernel("/dev/null"));
Don Garrette410e0f2011-11-10 15:39:01 -08001170 EXPECT_TRUE(performer.Write("junk", 4));
1171 EXPECT_TRUE(performer.Write("morejunk", 8));
1172 EXPECT_FALSE(performer.Write("morejunk", 8));
Darin Petkov934bb412010-11-18 11:21:35 -08001173 EXPECT_LT(performer.Close(), 0);
1174}
1175
Andrew de los Reyes353777c2010-10-08 10:34:30 -07001176TEST(DeltaPerformerTest, IsIdempotentOperationTest) {
1177 DeltaArchiveManifest_InstallOperation op;
1178 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
1179 *(op.add_dst_extents()) = ExtentForRange(0, 5);
1180 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
1181 *(op.add_src_extents()) = ExtentForRange(4, 1);
1182 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
1183 op.clear_src_extents();
1184 *(op.add_src_extents()) = ExtentForRange(5, 3);
1185 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
1186 *(op.add_dst_extents()) = ExtentForRange(20, 6);
1187 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
1188 *(op.add_src_extents()) = ExtentForRange(19, 2);
1189 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
1190}
1191
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001192TEST(DeltaPerformerTest, WriteUpdatesPayloadState) {
Alex Deymo8427b4a2014-11-05 14:00:32 -08001193 MockPrefs prefs;
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001194 InstallPlan install_plan;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001195 FakeSystemState fake_system_state;
1196 DeltaPerformer performer(&prefs, &fake_system_state, &install_plan);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001197 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0));
1198 EXPECT_TRUE(performer.OpenKernel("/dev/null"));
1199
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001200 EXPECT_CALL(*(fake_system_state.mock_payload_state()),
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001201 DownloadProgress(4)).Times(1);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001202 EXPECT_CALL(*(fake_system_state.mock_payload_state()),
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -08001203 DownloadProgress(8)).Times(2);
1204
1205 EXPECT_TRUE(performer.Write("junk", 4));
1206 EXPECT_TRUE(performer.Write("morejunk", 8));
1207 EXPECT_FALSE(performer.Write("morejunk", 8));
1208 EXPECT_LT(performer.Close(), 0);
1209}
1210
Jay Srinivasan738fdf32012-12-07 17:40:54 -08001211TEST(DeltaPerformerTest, MissingMandatoryMetadataSizeTest) {
1212 DoMetadataSizeTest(0, 75456, true);
Jay Srinivasan51dcf262012-09-13 17:24:32 -07001213}
1214
Jay Srinivasan738fdf32012-12-07 17:40:54 -08001215TEST(DeltaPerformerTest, MissingNonMandatoryMetadataSizeTest) {
1216 DoMetadataSizeTest(0, 123456, false);
1217}
1218
1219TEST(DeltaPerformerTest, InvalidMandatoryMetadataSizeTest) {
1220 DoMetadataSizeTest(13000, 140000, true);
1221}
1222
1223TEST(DeltaPerformerTest, InvalidNonMandatoryMetadataSizeTest) {
1224 DoMetadataSizeTest(40000, 50000, false);
1225}
1226
1227TEST(DeltaPerformerTest, ValidMandatoryMetadataSizeTest) {
1228 DoMetadataSizeTest(85376, 85376, true);
1229}
1230
1231TEST(DeltaPerformerTest, RunAsRootMandatoryEmptyMetadataSignatureTest) {
1232 DoMetadataSignatureTest(kEmptyMetadataSignature, kSignatureGenerated, true);
1233}
1234
1235TEST(DeltaPerformerTest, RunAsRootNonMandatoryEmptyMetadataSignatureTest) {
1236 DoMetadataSignatureTest(kEmptyMetadataSignature, kSignatureGenerated, false);
1237}
1238
1239TEST(DeltaPerformerTest, RunAsRootMandatoryInvalidMetadataSignatureTest) {
1240 DoMetadataSignatureTest(kInvalidMetadataSignature, kSignatureGenerated, true);
1241}
1242
1243TEST(DeltaPerformerTest, RunAsRootNonMandatoryInvalidMetadataSignatureTest) {
1244 DoMetadataSignatureTest(kInvalidMetadataSignature, kSignatureGenerated,
1245 false);
1246}
1247
1248TEST(DeltaPerformerTest, RunAsRootMandatoryValidMetadataSignature1Test) {
1249 DoMetadataSignatureTest(kValidMetadataSignature, kSignatureNone, true);
1250}
1251
1252TEST(DeltaPerformerTest, RunAsRootMandatoryValidMetadataSignature2Test) {
1253 DoMetadataSignatureTest(kValidMetadataSignature, kSignatureGenerated, true);
1254}
1255
1256TEST(DeltaPerformerTest, RunAsRootNonMandatoryValidMetadataSignatureTest) {
1257 DoMetadataSignatureTest(kValidMetadataSignature, kSignatureGenerated, false);
1258}
1259
1260TEST(DeltaPerformerTest, RunAsRootMandatoryOperationHashMismatchTest) {
1261 DoOperationHashMismatchTest(kInvalidOperationData, true);
1262}
Jay Srinivasan51dcf262012-09-13 17:24:32 -07001263
David Zeuthene7f89172013-10-31 10:21:04 -07001264TEST(DeltaPerformerTest, UsePublicKeyFromResponse) {
Alex Deymo8427b4a2014-11-05 14:00:32 -08001265 MockPrefs prefs;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001266 FakeSystemState fake_system_state;
David Zeuthene7f89172013-10-31 10:21:04 -07001267 InstallPlan install_plan;
1268 base::FilePath key_path;
1269
1270 // The result of the GetPublicKeyResponse() method is based on three things
1271 //
1272 // 1. Whether it's an official build; and
1273 // 2. Whether the Public RSA key to be used is in the root filesystem; and
Alex Vakulenko072359c2014-07-18 11:41:07 -07001274 // 3. Whether the response has a public key
David Zeuthene7f89172013-10-31 10:21:04 -07001275 //
1276 // We test all eight combinations to ensure that we only use the
1277 // public key in the response if
1278 //
1279 // a. it's not an official build; and
1280 // b. there is no key in the root filesystem.
1281
1282 DeltaPerformer *performer = new DeltaPerformer(&prefs,
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001283 &fake_system_state,
David Zeuthene7f89172013-10-31 10:21:04 -07001284 &install_plan);
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001285 FakeHardware* fake_hardware = fake_system_state.fake_hardware();
David Zeuthene7f89172013-10-31 10:21:04 -07001286
1287 string temp_dir;
Gilad Arnolda6742b32014-01-11 00:18:34 -08001288 EXPECT_TRUE(utils::MakeTempDirectory("PublicKeyFromResponseTests.XXXXXX",
David Zeuthene7f89172013-10-31 10:21:04 -07001289 &temp_dir));
1290 string non_existing_file = temp_dir + "/non-existing";
1291 string existing_file = temp_dir + "/existing";
Alex Vakulenko75039d72014-03-25 12:36:28 -07001292 EXPECT_EQ(0, System(base::StringPrintf("touch %s", existing_file.c_str())));
David Zeuthene7f89172013-10-31 10:21:04 -07001293
1294 // Non-official build, non-existing public-key, key in response -> true
Don Garrett6646b442013-11-13 15:29:11 -08001295 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001296 performer->public_key_path_ = non_existing_file;
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001297 install_plan.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
David Zeuthene7f89172013-10-31 10:21:04 -07001298 EXPECT_TRUE(performer->GetPublicKeyFromResponse(&key_path));
1299 EXPECT_FALSE(key_path.empty());
1300 EXPECT_EQ(unlink(key_path.value().c_str()), 0);
1301 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -08001302 fake_hardware->SetIsOfficialBuild(true);
David Zeuthene7f89172013-10-31 10:21:04 -07001303 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1304
1305 // Non-official build, existing public-key, key in response -> false
Don Garrett6646b442013-11-13 15:29:11 -08001306 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001307 performer->public_key_path_ = existing_file;
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001308 install_plan.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
David Zeuthene7f89172013-10-31 10:21:04 -07001309 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1310 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -08001311 fake_hardware->SetIsOfficialBuild(true);
David Zeuthene7f89172013-10-31 10:21:04 -07001312 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1313
1314 // Non-official build, non-existing public-key, no key in response -> false
Don Garrett6646b442013-11-13 15:29:11 -08001315 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001316 performer->public_key_path_ = non_existing_file;
1317 install_plan.public_key_rsa = "";
1318 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1319 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -08001320 fake_hardware->SetIsOfficialBuild(true);
David Zeuthene7f89172013-10-31 10:21:04 -07001321 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1322
1323 // Non-official build, existing public-key, no key in response -> false
Don Garrett6646b442013-11-13 15:29:11 -08001324 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001325 performer->public_key_path_ = existing_file;
1326 install_plan.public_key_rsa = "";
1327 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1328 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -08001329 fake_hardware->SetIsOfficialBuild(true);
David Zeuthene7f89172013-10-31 10:21:04 -07001330 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1331
1332 // Non-official build, non-existing public-key, key in response
1333 // but invalid base64 -> false
Don Garrett6646b442013-11-13 15:29:11 -08001334 fake_hardware->SetIsOfficialBuild(false);
David Zeuthene7f89172013-10-31 10:21:04 -07001335 performer->public_key_path_ = non_existing_file;
1336 install_plan.public_key_rsa = "not-valid-base64";
1337 EXPECT_FALSE(performer->GetPublicKeyFromResponse(&key_path));
1338
1339 delete performer;
Alex Deymo10875d92014-11-10 21:52:57 -08001340 EXPECT_TRUE(test_utils::RecursiveUnlinkDir(temp_dir));
David Zeuthene7f89172013-10-31 10:21:04 -07001341}
1342
Allie Wood78750a42015-02-11 15:42:11 -08001343TEST(DeltaPerformerTest, MinorVersionsMatch) {
1344 // Test that the minor version in update_engine.conf that is installed to
1345 // the image matches the supported delta minor version in the update engine.
1346 uint32_t minor_version;
1347 base::FilePath conf_path("update_engine.conf");
1348 EXPECT_TRUE(utils::GetMinorVersion(conf_path, &minor_version));
1349 ASSERT_EQ(DeltaPerformer::kSupportedMinorPayloadVersion, minor_version);
1350}
1351
Andrew de los Reyes09e56d62010-04-23 13:45:53 -07001352} // namespace chromeos_update_engine