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 |