| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <sys/mount.h> | 5 #include <sys/mount.h> |
| 6 #include <inttypes.h> | 6 #include <inttypes.h> |
| 7 | 7 |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 return true; | 93 return true; |
| 94 } | 94 } |
| 95 } // namespace {} | 95 } // namespace {} |
| 96 | 96 |
| 97 namespace { | 97 namespace { |
| 98 enum SignatureTest { | 98 enum SignatureTest { |
| 99 kSignatureNone, // No payload signing. | 99 kSignatureNone, // No payload signing. |
| 100 kSignatureGenerator, // Sign the payload at generation time. | 100 kSignatureGenerator, // Sign the payload at generation time. |
| 101 kSignatureGenerated, // Sign the payload after it's generated. | 101 kSignatureGenerated, // Sign the payload after it's generated. |
| 102 kSignatureGeneratedShell, // Sign the generated payload through shell cmds. | 102 kSignatureGeneratedShell, // Sign the generated payload through shell cmds. |
| 103 kSignatureGeneratedShellBadKey, // Sign with a bad key through shell cmds. |
| 103 }; | 104 }; |
| 104 | 105 |
| 105 size_t GetSignatureSize() { | 106 size_t GetSignatureSize(const string& private_key_path) { |
| 106 const vector<char> data(1, 'x'); | 107 const vector<char> data(1, 'x'); |
| 107 vector<char> hash; | 108 vector<char> hash; |
| 108 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(data, &hash)); | 109 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(data, &hash)); |
| 109 vector<char> signature; | 110 vector<char> signature; |
| 110 EXPECT_TRUE(PayloadSigner::SignHash(hash, | 111 EXPECT_TRUE(PayloadSigner::SignHash(hash, |
| 111 kUnittestPrivateKeyPath, | 112 private_key_path, |
| 112 &signature)); | 113 &signature)); |
| 113 return signature.size(); | 114 return signature.size(); |
| 114 } | 115 } |
| 115 | 116 |
| 116 void SignGeneratedPayload(const string& payload_path) { | 117 void SignGeneratedPayload(const string& payload_path) { |
| 117 int signature_size = GetSignatureSize(); | 118 int signature_size = GetSignatureSize(kUnittestPrivateKeyPath); |
| 118 vector<char> hash; | 119 vector<char> hash; |
| 119 ASSERT_TRUE(PayloadSigner::HashPayloadForSigning(payload_path, | 120 ASSERT_TRUE(PayloadSigner::HashPayloadForSigning(payload_path, |
| 120 signature_size, | 121 signature_size, |
| 121 &hash)); | 122 &hash)); |
| 122 vector<char> signature; | 123 vector<char> signature; |
| 123 ASSERT_TRUE(PayloadSigner::SignHash(hash, | 124 ASSERT_TRUE(PayloadSigner::SignHash(hash, |
| 124 kUnittestPrivateKeyPath, | 125 kUnittestPrivateKeyPath, |
| 125 &signature)); | 126 &signature)); |
| 126 ASSERT_TRUE(PayloadSigner::AddSignatureToPayload(payload_path, | 127 ASSERT_TRUE(PayloadSigner::AddSignatureToPayload(payload_path, |
| 127 signature, | 128 signature, |
| 128 payload_path)); | 129 payload_path)); |
| 129 EXPECT_TRUE(PayloadSigner::VerifySignedPayload(payload_path, | 130 EXPECT_TRUE(PayloadSigner::VerifySignedPayload(payload_path, |
| 130 kUnittestPublicKeyPath)); | 131 kUnittestPublicKeyPath)); |
| 131 } | 132 } |
| 132 | 133 |
| 133 void SignGeneratedShellPayload(const string& payload_path) { | 134 void SignGeneratedShellPayload(SignatureTest signature_test, |
| 134 int signature_size = GetSignatureSize(); | 135 const string& payload_path) { |
| 136 string private_key_path = kUnittestPrivateKeyPath; |
| 137 if (signature_test == kSignatureGeneratedShellBadKey) { |
| 138 ASSERT_TRUE(utils::MakeTempFile("/tmp/key.XXXXXX", |
| 139 &private_key_path, |
| 140 NULL)); |
| 141 } else { |
| 142 ASSERT_EQ(kSignatureGeneratedShell, signature_test); |
| 143 } |
| 144 ScopedPathUnlinker key_unlinker(private_key_path); |
| 145 key_unlinker.set_should_remove(signature_test == |
| 146 kSignatureGeneratedShellBadKey); |
| 147 // Generates a new private key that will not match the public key. |
| 148 if (signature_test == kSignatureGeneratedShellBadKey) { |
| 149 LOG(INFO) << "Generating a mismatched private key."; |
| 150 ASSERT_EQ(0, |
| 151 System(StringPrintf( |
| 152 "/usr/bin/openssl genrsa -out %s 1024", |
| 153 private_key_path.c_str()))); |
| 154 } |
| 155 int signature_size = GetSignatureSize(private_key_path); |
| 135 string hash_file; | 156 string hash_file; |
| 136 ASSERT_TRUE(utils::MakeTempFile("/tmp/hash.XXXXXX", &hash_file, NULL)); | 157 ASSERT_TRUE(utils::MakeTempFile("/tmp/hash.XXXXXX", &hash_file, NULL)); |
| 137 ScopedPathUnlinker hash_unlinker(hash_file); | 158 ScopedPathUnlinker hash_unlinker(hash_file); |
| 138 | |
| 139 ASSERT_EQ(0, | 159 ASSERT_EQ(0, |
| 140 System(StringPrintf( | 160 System(StringPrintf( |
| 141 "./delta_generator -in_file %s -signature_size %d " | 161 "./delta_generator -in_file %s -signature_size %d " |
| 142 "-out_hash_file %s", | 162 "-out_hash_file %s", |
| 143 payload_path.c_str(), | 163 payload_path.c_str(), |
| 144 signature_size, | 164 signature_size, |
| 145 hash_file.c_str()))); | 165 hash_file.c_str()))); |
| 146 | 166 |
| 147 string sig_file; | 167 string sig_file; |
| 148 ASSERT_TRUE(utils::MakeTempFile("/tmp/signature.XXXXXX", &sig_file, NULL)); | 168 ASSERT_TRUE(utils::MakeTempFile("/tmp/signature.XXXXXX", &sig_file, NULL)); |
| 149 ScopedPathUnlinker sig_unlinker(sig_file); | 169 ScopedPathUnlinker sig_unlinker(sig_file); |
| 150 ASSERT_EQ(0, | 170 ASSERT_EQ(0, |
| 151 System(StringPrintf( | 171 System(StringPrintf( |
| 152 "/usr/bin/openssl rsautl -pkcs -sign -inkey %s -in %s -out %s", | 172 "/usr/bin/openssl rsautl -pkcs -sign -inkey %s -in %s -out %s", |
| 153 kUnittestPrivateKeyPath, | 173 private_key_path.c_str(), |
| 154 hash_file.c_str(), | 174 hash_file.c_str(), |
| 155 sig_file.c_str()))); | 175 sig_file.c_str()))); |
| 156 ASSERT_EQ(0, | 176 ASSERT_EQ(0, |
| 157 System(StringPrintf( | 177 System(StringPrintf( |
| 158 "./delta_generator -in_file %s -signature_file %s " | 178 "./delta_generator -in_file %s -signature_file %s " |
| 159 "-out_file %s", | 179 "-out_file %s", |
| 160 payload_path.c_str(), | 180 payload_path.c_str(), |
| 161 sig_file.c_str(), | 181 sig_file.c_str(), |
| 162 payload_path.c_str()))); | 182 payload_path.c_str()))); |
| 163 ASSERT_EQ(0, | 183 int verify_result = |
| 164 System(StringPrintf( | 184 System(StringPrintf("./delta_generator -in_file %s -public_key %s", |
| 165 "./delta_generator -in_file %s -public_key %s", | 185 payload_path.c_str(), |
| 166 payload_path.c_str(), | 186 kUnittestPublicKeyPath)); |
| 167 kUnittestPublicKeyPath))); | 187 if (signature_test == kSignatureGeneratedShellBadKey) { |
| 188 ASSERT_NE(0, verify_result); |
| 189 } else { |
| 190 ASSERT_EQ(0, verify_result); |
| 191 } |
| 168 } | 192 } |
| 169 | 193 |
| 170 void DoSmallImageTest(bool full_kernel, bool full_rootfs, bool noop, | 194 void DoSmallImageTest(bool full_kernel, bool full_rootfs, bool noop, |
| 171 SignatureTest signature_test) { | 195 SignatureTest signature_test) { |
| 172 string a_img, b_img; | 196 string a_img, b_img; |
| 173 EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL)); | 197 EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL)); |
| 174 ScopedPathUnlinker a_img_unlinker(a_img); | 198 ScopedPathUnlinker a_img_unlinker(a_img); |
| 175 EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL)); | 199 EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL)); |
| 176 ScopedPathUnlinker b_img_unlinker(b_img); | 200 ScopedPathUnlinker b_img_unlinker(b_img); |
| 177 | 201 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 b_mnt, | 306 b_mnt, |
| 283 b_img, | 307 b_img, |
| 284 full_kernel ? "" : old_kernel, | 308 full_kernel ? "" : old_kernel, |
| 285 new_kernel, | 309 new_kernel, |
| 286 delta_path, | 310 delta_path, |
| 287 private_key)); | 311 private_key)); |
| 288 } | 312 } |
| 289 | 313 |
| 290 if (signature_test == kSignatureGenerated) { | 314 if (signature_test == kSignatureGenerated) { |
| 291 SignGeneratedPayload(delta_path); | 315 SignGeneratedPayload(delta_path); |
| 292 } else if (signature_test == kSignatureGeneratedShell) { | 316 } else if (signature_test == kSignatureGeneratedShell || |
| 293 SignGeneratedShellPayload(delta_path); | 317 signature_test == kSignatureGeneratedShellBadKey) { |
| 318 SignGeneratedShellPayload(signature_test, delta_path); |
| 294 } | 319 } |
| 295 | 320 |
| 296 // Read delta into memory. | 321 // Read delta into memory. |
| 297 vector<char> delta; | 322 vector<char> delta; |
| 298 EXPECT_TRUE(utils::ReadFile(delta_path, &delta)); | 323 EXPECT_TRUE(utils::ReadFile(delta_path, &delta)); |
| 299 | 324 |
| 300 uint64_t manifest_metadata_size; | 325 uint64_t manifest_metadata_size; |
| 301 | 326 |
| 302 // Check the metadata. | 327 // Check the metadata. |
| 303 { | 328 { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 | 430 |
| 406 CompareFilesByBlock(old_kernel, new_kernel); | 431 CompareFilesByBlock(old_kernel, new_kernel); |
| 407 CompareFilesByBlock(a_img, b_img); | 432 CompareFilesByBlock(a_img, b_img); |
| 408 | 433 |
| 409 vector<char> updated_kernel_partition; | 434 vector<char> updated_kernel_partition; |
| 410 EXPECT_TRUE(utils::ReadFile(old_kernel, &updated_kernel_partition)); | 435 EXPECT_TRUE(utils::ReadFile(old_kernel, &updated_kernel_partition)); |
| 411 EXPECT_EQ(0, strncmp(&updated_kernel_partition[0], new_data_string, | 436 EXPECT_EQ(0, strncmp(&updated_kernel_partition[0], new_data_string, |
| 412 strlen(new_data_string))); | 437 strlen(new_data_string))); |
| 413 | 438 |
| 414 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath)); | 439 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath)); |
| 415 EXPECT_EQ(signature_test != kSignatureNone, | 440 bool expect_verify_success = |
| 441 signature_test != kSignatureNone && |
| 442 signature_test != kSignatureGeneratedShellBadKey; |
| 443 EXPECT_EQ(expect_verify_success, |
| 416 performer.VerifyPayload( | 444 performer.VerifyPayload( |
| 417 kUnittestPublicKeyPath, | 445 kUnittestPublicKeyPath, |
| 418 OmahaHashCalculator::OmahaHashOfData(delta), | 446 OmahaHashCalculator::OmahaHashOfData(delta), |
| 419 delta.size())); | 447 delta.size())); |
| 448 EXPECT_TRUE(performer.VerifyPayload( |
| 449 "/public/key/does/not/exists", |
| 450 OmahaHashCalculator::OmahaHashOfData(delta), |
| 451 delta.size())); |
| 420 | 452 |
| 421 uint64_t new_kernel_size; | 453 uint64_t new_kernel_size; |
| 422 vector<char> new_kernel_hash; | 454 vector<char> new_kernel_hash; |
| 423 uint64_t new_rootfs_size; | 455 uint64_t new_rootfs_size; |
| 424 vector<char> new_rootfs_hash; | 456 vector<char> new_rootfs_hash; |
| 425 EXPECT_TRUE(performer.GetNewPartitionInfo(&new_kernel_size, | 457 EXPECT_TRUE(performer.GetNewPartitionInfo(&new_kernel_size, |
| 426 &new_kernel_hash, | 458 &new_kernel_hash, |
| 427 &new_rootfs_size, | 459 &new_rootfs_size, |
| 428 &new_rootfs_hash)); | 460 &new_rootfs_hash)); |
| 429 EXPECT_EQ(4096, new_kernel_size); | 461 EXPECT_EQ(4096, new_kernel_size); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 } | 494 } |
| 463 | 495 |
| 464 TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedTest) { | 496 TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedTest) { |
| 465 DoSmallImageTest(false, false, false, kSignatureGenerated); | 497 DoSmallImageTest(false, false, false, kSignatureGenerated); |
| 466 } | 498 } |
| 467 | 499 |
| 468 TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellTest) { | 500 TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellTest) { |
| 469 DoSmallImageTest(false, false, false, kSignatureGeneratedShell); | 501 DoSmallImageTest(false, false, false, kSignatureGeneratedShell); |
| 470 } | 502 } |
| 471 | 503 |
| 504 TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellBadKeyTest) { |
| 505 DoSmallImageTest(false, false, false, kSignatureGeneratedShellBadKey); |
| 506 } |
| 507 |
| 472 TEST(DeltaPerformerTest, BadDeltaMagicTest) { | 508 TEST(DeltaPerformerTest, BadDeltaMagicTest) { |
| 473 PrefsMock prefs; | 509 PrefsMock prefs; |
| 474 DeltaPerformer performer(&prefs); | 510 DeltaPerformer performer(&prefs); |
| 475 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0)); | 511 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0)); |
| 476 EXPECT_TRUE(performer.OpenKernel("/dev/null")); | 512 EXPECT_TRUE(performer.OpenKernel("/dev/null")); |
| 477 EXPECT_EQ(4, performer.Write("junk", 4)); | 513 EXPECT_EQ(4, performer.Write("junk", 4)); |
| 478 EXPECT_EQ(8, performer.Write("morejunk", 8)); | 514 EXPECT_EQ(8, performer.Write("morejunk", 8)); |
| 479 EXPECT_LT(performer.Write("morejunk", 8), 0); | 515 EXPECT_LT(performer.Write("morejunk", 8), 0); |
| 480 EXPECT_LT(performer.Close(), 0); | 516 EXPECT_LT(performer.Close(), 0); |
| 481 } | 517 } |
| 482 | 518 |
| 483 TEST(DeltaPerformerTest, IsIdempotentOperationTest) { | 519 TEST(DeltaPerformerTest, IsIdempotentOperationTest) { |
| 484 DeltaArchiveManifest_InstallOperation op; | 520 DeltaArchiveManifest_InstallOperation op; |
| 485 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); | 521 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); |
| 486 *(op.add_dst_extents()) = ExtentForRange(0, 5); | 522 *(op.add_dst_extents()) = ExtentForRange(0, 5); |
| 487 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); | 523 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); |
| 488 *(op.add_src_extents()) = ExtentForRange(4, 1); | 524 *(op.add_src_extents()) = ExtentForRange(4, 1); |
| 489 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op)); | 525 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op)); |
| 490 op.clear_src_extents(); | 526 op.clear_src_extents(); |
| 491 *(op.add_src_extents()) = ExtentForRange(5, 3); | 527 *(op.add_src_extents()) = ExtentForRange(5, 3); |
| 492 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); | 528 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); |
| 493 *(op.add_dst_extents()) = ExtentForRange(20, 6); | 529 *(op.add_dst_extents()) = ExtentForRange(20, 6); |
| 494 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); | 530 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); |
| 495 *(op.add_src_extents()) = ExtentForRange(19, 2); | 531 *(op.add_src_extents()) = ExtentForRange(19, 2); |
| 496 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op)); | 532 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op)); |
| 497 } | 533 } |
| 498 | 534 |
| 499 } // namespace chromeos_update_engine | 535 } // namespace chromeos_update_engine |
| OLD | NEW |