OLD | NEW |
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "update_engine/payload_signer.h" | 5 #include "update_engine/payload_signer.h" |
6 | 6 |
7 #include <base/logging.h> | 7 #include <base/logging.h> |
8 #include <base/string_util.h> | 8 #include <base/string_util.h> |
9 #include <openssl/pem.h> | 9 #include <openssl/pem.h> |
10 | 10 |
(...skipping 25 matching lines...) Expand all Loading... |
36 // Serialize protobuf | 36 // Serialize protobuf |
37 string serialized; | 37 string serialized; |
38 TEST_AND_RETURN_FALSE(out_message.AppendToString(&serialized)); | 38 TEST_AND_RETURN_FALSE(out_message.AppendToString(&serialized)); |
39 out_signature_blob->insert(out_signature_blob->end(), | 39 out_signature_blob->insert(out_signature_blob->end(), |
40 serialized.begin(), | 40 serialized.begin(), |
41 serialized.end()); | 41 serialized.end()); |
42 LOG(INFO) << "Signature blob size: " << out_signature_blob->size(); | 42 LOG(INFO) << "Signature blob size: " << out_signature_blob->size(); |
43 return true; | 43 return true; |
44 } | 44 } |
45 | 45 |
| 46 bool LoadPayload(const string& payload_path, |
| 47 vector<char>* out_payload, |
| 48 DeltaArchiveManifest* out_manifest, |
| 49 uint64_t* out_metadata_size) { |
| 50 vector<char> payload; |
| 51 // Loads the payload and parses the manifest. |
| 52 TEST_AND_RETURN_FALSE(utils::ReadFile(payload_path, &payload)); |
| 53 LOG(INFO) << "Payload size: " << payload.size(); |
| 54 TEST_AND_RETURN_FALSE(DeltaPerformer::ParsePayloadMetadata( |
| 55 payload, out_manifest, out_metadata_size) == |
| 56 DeltaPerformer::kMetadataParseSuccess); |
| 57 LOG(INFO) << "Metadata size: " << *out_metadata_size; |
| 58 out_payload->swap(payload); |
| 59 return true; |
| 60 } |
| 61 |
46 // Given an unsigned payload under |payload_path| and the |signature_blob_size| | 62 // Given an unsigned payload under |payload_path| and the |signature_blob_size| |
47 // generates an updated payload that includes a dummy signature op in its | 63 // generates an updated payload that includes a dummy signature op in its |
48 // manifest. Returns true on success, false otherwise. | 64 // manifest. Returns true on success, false otherwise. |
49 bool AddSignatureOpToPayload(const std::string& payload_path, | 65 bool AddSignatureOpToPayload(const string& payload_path, |
50 int signature_blob_size, | 66 int signature_blob_size, |
51 vector<char>* out_payload) { | 67 vector<char>* out_payload) { |
52 const int kProtobufOffset = 20; | 68 const int kProtobufOffset = 20; |
53 const int kProtobufSizeOffset = 12; | 69 const int kProtobufSizeOffset = 12; |
54 | 70 |
| 71 // Loads the payload. |
55 vector<char> payload; | 72 vector<char> payload; |
56 // Loads the payload and parses the manifest. | 73 DeltaArchiveManifest manifest; |
57 TEST_AND_RETURN_FALSE(utils::ReadFile(payload_path, &payload)); | |
58 LOG(INFO) << "Original payload size: " << payload.size(); | |
59 uint64_t metadata_size; | 74 uint64_t metadata_size; |
60 DeltaArchiveManifest manifest; | 75 TEST_AND_RETURN_FALSE(LoadPayload( |
61 TEST_AND_RETURN_FALSE(DeltaPerformer::ParsePayloadMetadata( | 76 payload_path, &payload, &manifest, &metadata_size)); |
62 payload, &manifest, &metadata_size) == | |
63 DeltaPerformer::kMetadataParseSuccess); | |
64 LOG(INFO) << "Metadata size: " << metadata_size; | |
65 TEST_AND_RETURN_FALSE(!manifest.has_signatures_offset() && | 77 TEST_AND_RETURN_FALSE(!manifest.has_signatures_offset() && |
66 !manifest.has_signatures_size()); | 78 !manifest.has_signatures_size()); |
67 | 79 |
68 // Updates the manifest to include the signature operation. | 80 // Updates the manifest to include the signature operation. |
69 DeltaDiffGenerator::AddSignatureOp(payload.size() - metadata_size, | 81 DeltaDiffGenerator::AddSignatureOp(payload.size() - metadata_size, |
70 signature_blob_size, | 82 signature_blob_size, |
71 &manifest); | 83 &manifest); |
72 | 84 |
73 // Updates the payload to include the new manifest. | 85 // Updates the payload to include the new manifest. |
74 string serialized_manifest; | 86 string serialized_manifest; |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 rsa, | 222 rsa, |
211 RSA_PKCS1_PADDING); | 223 RSA_PKCS1_PADDING); |
212 RSA_free(rsa); | 224 RSA_free(rsa); |
213 TEST_AND_RETURN_FALSE(decrypt_size > 0 && | 225 TEST_AND_RETURN_FALSE(decrypt_size > 0 && |
214 decrypt_size <= static_cast<int>(hash_data.size())); | 226 decrypt_size <= static_cast<int>(hash_data.size())); |
215 hash_data.resize(decrypt_size); | 227 hash_data.resize(decrypt_size); |
216 out_hash_data->swap(hash_data); | 228 out_hash_data->swap(hash_data); |
217 return true; | 229 return true; |
218 } | 230 } |
219 | 231 |
| 232 bool PayloadSigner::VerifySignedPayload(const std::string& payload_path, |
| 233 const std::string& public_key_path) { |
| 234 vector<char> payload; |
| 235 DeltaArchiveManifest manifest; |
| 236 uint64_t metadata_size; |
| 237 TEST_AND_RETURN_FALSE(LoadPayload( |
| 238 payload_path, &payload, &manifest, &metadata_size)); |
| 239 TEST_AND_RETURN_FALSE(manifest.has_signatures_offset() && |
| 240 manifest.has_signatures_size()); |
| 241 CHECK_EQ(payload.size(), |
| 242 metadata_size + manifest.signatures_offset() + |
| 243 manifest.signatures_size()); |
| 244 vector<char> signature_blob( |
| 245 payload.begin() + metadata_size + manifest.signatures_offset(), |
| 246 payload.end()); |
| 247 vector<char> signed_hash; |
| 248 TEST_AND_RETURN_FALSE(VerifySignature( |
| 249 signature_blob, public_key_path, &signed_hash)); |
| 250 TEST_AND_RETURN_FALSE(!signed_hash.empty()); |
| 251 vector<char> hash; |
| 252 TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes( |
| 253 payload.data(), metadata_size + manifest.signatures_offset(), &hash)); |
| 254 TEST_AND_RETURN_FALSE(hash == signed_hash); |
| 255 return true; |
| 256 } |
| 257 |
220 bool PayloadSigner::HashPayloadForSigning(const std::string& payload_path, | 258 bool PayloadSigner::HashPayloadForSigning(const std::string& payload_path, |
221 int signature_size, | 259 int signature_size, |
222 vector<char>* out_hash_data) { | 260 vector<char>* out_hash_data) { |
223 // TODO(petkov): Reduce memory usage -- the payload is manipulated in memory. | 261 // TODO(petkov): Reduce memory usage -- the payload is manipulated in memory. |
224 | 262 |
225 // Loads the payload and adds the signature op to it. | 263 // Loads the payload and adds the signature op to it. |
226 vector<char> signature(signature_size, 0); | 264 vector<char> signature(signature_size, 0); |
227 vector<char> signature_blob; | 265 vector<char> signature_blob; |
228 TEST_AND_RETURN_FALSE(ConvertSignatureToProtobufBlob(signature, | 266 TEST_AND_RETURN_FALSE(ConvertSignatureToProtobufBlob(signature, |
229 &signature_blob)); | 267 &signature_blob)); |
(...skipping 25 matching lines...) Expand all Loading... |
255 // payload. | 293 // payload. |
256 payload.insert(payload.end(), signature_blob.begin(), signature_blob.end()); | 294 payload.insert(payload.end(), signature_blob.begin(), signature_blob.end()); |
257 LOG(INFO) << "Signed payload size: " << payload.size(); | 295 LOG(INFO) << "Signed payload size: " << payload.size(); |
258 TEST_AND_RETURN_FALSE(utils::WriteFile(signed_payload_path.c_str(), | 296 TEST_AND_RETURN_FALSE(utils::WriteFile(signed_payload_path.c_str(), |
259 payload.data(), | 297 payload.data(), |
260 payload.size())); | 298 payload.size())); |
261 return true; | 299 return true; |
262 } | 300 } |
263 | 301 |
264 } // namespace chromeos_update_engine | 302 } // namespace chromeos_update_engine |
OLD | NEW |