diff options
author | Scott Lobdell <slobdell@google.com> | 2019-03-05 11:56:41 -0800 |
---|---|---|
committer | Scott Lobdell <slobdell@google.com> | 2019-03-05 16:53:31 -0800 |
commit | 838bccb515036433be3a55bec702336f170df38a (patch) | |
tree | eb94a5e0cbab6fa3e8f5539fed44dd081f48fc04 | |
parent | 2af3457b7362c163b1896f7a4b6eee69f8439296 (diff) | |
parent | 4eee53f5949d5e4cb43894b3d190daf635e31338 (diff) |
Merge QP1A.190228.005
Change-Id: I546552fe26b74b96c18d929cdda1a527bbcdf4dc
26 files changed, 139 insertions, 150 deletions
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc index f405bd93..489c821d 100644 --- a/payload_consumer/delta_performer.cc +++ b/payload_consumer/delta_performer.cc @@ -1586,8 +1586,7 @@ bool DeltaPerformer::ExtractSignatureMessage() { // blob and the signed sha-256 context. LOG_IF(WARNING, !prefs_->SetString(kPrefsUpdateStateSignatureBlob, - string(signatures_message_data_.begin(), - signatures_message_data_.end()))) + signatures_message_data_)) << "Unable to store the signature blob."; LOG(INFO) << "Extracted signature data of size " @@ -1970,11 +1969,7 @@ bool DeltaPerformer::PrimeUpdateState() { signed_hash_calculator_.SetContext(signed_hash_context)); } - string signature_blob; - if (prefs_->GetString(kPrefsUpdateStateSignatureBlob, &signature_blob)) { - signatures_message_data_.assign(signature_blob.begin(), - signature_blob.end()); - } + prefs_->GetString(kPrefsUpdateStateSignatureBlob, &signatures_message_data_); string hash_context; TEST_AND_RETURN_FALSE( diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h index 55cb2a46..17cb5995 100644 --- a/payload_consumer/delta_performer.h +++ b/payload_consumer/delta_performer.h @@ -377,7 +377,7 @@ class DeltaPerformer : public FileWriter { HashCalculator signed_hash_calculator_; // Signatures message blob extracted directly from the payload. - brillo::Blob signatures_message_data_; + std::string signatures_message_data_; // The public key to be used. Provided as a member so that tests can // override with test keys. diff --git a/payload_consumer/delta_performer_integration_test.cc b/payload_consumer/delta_performer_integration_test.cc index e064077f..6b4771d6 100644 --- a/payload_consumer/delta_performer_integration_test.cc +++ b/payload_consumer/delta_performer_integration_test.cc @@ -596,7 +596,7 @@ static void ApplyDeltaFile(bool full_kernel, EXPECT_EQ(2, sigs_message.signatures_size()); else EXPECT_EQ(1, sigs_message.signatures_size()); - const Signatures_Signature& signature = sigs_message.signatures(0); + const Signatures::Signature& signature = sigs_message.signatures(0); EXPECT_EQ(1U, signature.version()); uint64_t expected_sig_data_length = 0; diff --git a/payload_consumer/payload_constants.cc b/payload_consumer/payload_constants.cc index 213d798f..a2368a43 100644 --- a/payload_consumer/payload_constants.cc +++ b/payload_consumer/payload_constants.cc @@ -42,7 +42,7 @@ const char kPartitionNameRoot[] = "root"; const char kDeltaMagic[4] = {'C', 'r', 'A', 'U'}; -const char* InstallOperationTypeName(InstallOperation_Type op_type) { +const char* InstallOperationTypeName(InstallOperation::Type op_type) { switch (op_type) { case InstallOperation::BSDIFF: return "BSDIFF"; diff --git a/payload_consumer/payload_constants.h b/payload_consumer/payload_constants.h index 7f768984..16424887 100644 --- a/payload_consumer/payload_constants.h +++ b/payload_consumer/payload_constants.h @@ -77,7 +77,7 @@ extern const char kDeltaMagic[4]; const uint64_t kSparseHole = std::numeric_limits<uint64_t>::max(); // Return the name of the operation type. -const char* InstallOperationTypeName(InstallOperation_Type op_type); +const char* InstallOperationTypeName(InstallOperation::Type op_type); } // namespace chromeos_update_engine diff --git a/payload_consumer/payload_metadata.cc b/payload_consumer/payload_metadata.cc index b631c87c..8b3eb4e1 100644 --- a/payload_consumer/payload_metadata.cc +++ b/payload_consumer/payload_metadata.cc @@ -25,6 +25,8 @@ #include "update_engine/payload_consumer/payload_constants.h" #include "update_engine/payload_consumer/payload_verifier.h" +using std::string; + namespace chromeos_update_engine { const uint64_t PayloadMetadata::kDeltaVersionOffset = sizeof(kDeltaMagic); @@ -155,12 +157,16 @@ bool PayloadMetadata::GetManifest(const brillo::Blob& payload, ErrorCode PayloadMetadata::ValidateMetadataSignature( const brillo::Blob& payload, - const std::string& metadata_signature, - const std::string& pem_public_key) const { + const string& metadata_signature, + const string& pem_public_key) const { if (payload.size() < metadata_size_ + metadata_signature_size_) return ErrorCode::kDownloadMetadataSignatureError; - brillo::Blob metadata_signature_blob, metadata_signature_protobuf_blob; + // A single signature in raw bytes. + brillo::Blob metadata_signature_blob; + // The serialized Signatures protobuf message stored in major version >=2 + // payload, it may contain multiple signatures. + string metadata_signature_protobuf; if (!metadata_signature.empty()) { // Convert base64-encoded signature to raw bytes. if (!brillo::data_encoding::Base64Decode(metadata_signature, @@ -170,13 +176,12 @@ ErrorCode PayloadMetadata::ValidateMetadataSignature( return ErrorCode::kDownloadMetadataSignatureError; } } else if (major_payload_version_ == kBrilloMajorPayloadVersion) { - metadata_signature_protobuf_blob.assign( + metadata_signature_protobuf.assign( payload.begin() + metadata_size_, payload.begin() + metadata_size_ + metadata_signature_size_); } - if (metadata_signature_blob.empty() && - metadata_signature_protobuf_blob.empty()) { + if (metadata_signature_blob.empty() && metadata_signature_protobuf.empty()) { LOG(ERROR) << "Missing mandatory metadata signature in both Omaha " << "response and payload."; return ErrorCode::kDownloadMetadataSignatureMissingError; @@ -210,7 +215,7 @@ ErrorCode PayloadMetadata::ValidateMetadataSignature( return ErrorCode::kDownloadMetadataSignatureMismatch; } } else { - if (!PayloadVerifier::VerifySignature(metadata_signature_protobuf_blob, + if (!PayloadVerifier::VerifySignature(metadata_signature_protobuf, pem_public_key, calculated_metadata_hash)) { LOG(ERROR) << "Manifest hash verification failed."; diff --git a/payload_consumer/payload_verifier.cc b/payload_consumer/payload_verifier.cc index 2f7c133a..3eb1da8b 100644 --- a/payload_consumer/payload_verifier.cc +++ b/payload_consumer/payload_verifier.cc @@ -79,13 +79,12 @@ const uint8_t kRSA2048SHA256Padding[] = { } // namespace -bool PayloadVerifier::VerifySignature(const brillo::Blob& signature_blob, +bool PayloadVerifier::VerifySignature(const string& signature_proto, const string& pem_public_key, const brillo::Blob& hash_data) { Signatures signatures; - LOG(INFO) << "signature blob size = " << signature_blob.size(); - TEST_AND_RETURN_FALSE( - signatures.ParseFromArray(signature_blob.data(), signature_blob.size())); + LOG(INFO) << "signature blob size = " << signature_proto.size(); + TEST_AND_RETURN_FALSE(signatures.ParseFromString(signature_proto)); if (!signatures.signatures_size()) { LOG(ERROR) << "No signatures stored in the blob."; @@ -95,7 +94,7 @@ bool PayloadVerifier::VerifySignature(const brillo::Blob& signature_blob, std::vector<brillo::Blob> tested_hashes; // Tries every signature in the signature blob. for (int i = 0; i < signatures.signatures_size(); i++) { - const Signatures_Signature& signature = signatures.signatures(i); + const Signatures::Signature& signature = signatures.signatures(i); brillo::Blob sig_data(signature.data().begin(), signature.data().end()); brillo::Blob sig_hash_data; if (!GetRawHashFromSignature(sig_data, pem_public_key, &sig_hash_data)) diff --git a/payload_consumer/payload_verifier.h b/payload_consumer/payload_verifier.h index ec23ef21..09bdbf95 100644 --- a/payload_consumer/payload_verifier.h +++ b/payload_consumer/payload_verifier.h @@ -31,13 +31,13 @@ namespace chromeos_update_engine { class PayloadVerifier { public: - // Interprets |signature_blob| as a protocol buffer containing the Signatures + // Interprets |signature_proto| as a protocol buffer containing the Signatures // message and decrypts each signature data using the |pem_public_key|. // |pem_public_key| should be a PEM format RSA public key data. // Returns whether *any* of the decrypted hashes matches the |hash_data|. // In case of any error parsing the signatures or the public key, returns // false. - static bool VerifySignature(const brillo::Blob& signature_blob, + static bool VerifySignature(const std::string& signature_proto, const std::string& pem_public_key, const brillo::Blob& hash_data); diff --git a/payload_generator/ab_generator.cc b/payload_generator/ab_generator.cc index f4cc9fba..d9b9d885 100644 --- a/payload_generator/ab_generator.cc +++ b/payload_generator/ab_generator.cc @@ -276,7 +276,7 @@ bool ABGenerator::AddDataAndSetType(AnnotatedOperation* aop, target_part_path, dst_extents, &data, data.size(), kBlockSize)); brillo::Blob blob; - InstallOperation_Type op_type; + InstallOperation::Type op_type; TEST_AND_RETURN_FALSE( diff_utils::GenerateBestFullOperation(data, version, &blob, &op_type)); diff --git a/payload_generator/ab_generator_unittest.cc b/payload_generator/ab_generator_unittest.cc index 2f8c0c60..270657ab 100644 --- a/payload_generator/ab_generator_unittest.cc +++ b/payload_generator/ab_generator_unittest.cc @@ -49,7 +49,7 @@ bool ExtentEquals(const Extent& ext, } // Tests splitting of a REPLACE/REPLACE_BZ operation. -void TestSplitReplaceOrReplaceBzOperation(InstallOperation_Type orig_type, +void TestSplitReplaceOrReplaceBzOperation(InstallOperation::Type orig_type, bool compressible) { const size_t op_ex1_start_block = 2; const size_t op_ex1_num_blocks = 2; @@ -124,7 +124,7 @@ void TestSplitReplaceOrReplaceBzOperation(InstallOperation_Type orig_type, version, aop, part_file.path(), &result_ops, &blob_file)); // Check the result. - InstallOperation_Type expected_type = + InstallOperation::Type expected_type = compressible ? InstallOperation::REPLACE_BZ : InstallOperation::REPLACE; ASSERT_EQ(2U, result_ops.size()); @@ -200,7 +200,7 @@ void TestSplitReplaceOrReplaceBzOperation(InstallOperation_Type orig_type, } // Tests merging of REPLACE/REPLACE_BZ operations. -void TestMergeReplaceOrReplaceBzOperations(InstallOperation_Type orig_type, +void TestMergeReplaceOrReplaceBzOperations(InstallOperation::Type orig_type, bool compressible) { const size_t first_op_num_blocks = 1; const size_t second_op_num_blocks = 2; @@ -287,7 +287,7 @@ void TestMergeReplaceOrReplaceBzOperations(InstallOperation_Type orig_type, &aops, version, 5, part_file.path(), &blob_file)); // Check the result. - InstallOperation_Type expected_op_type = + InstallOperation::Type expected_op_type = compressible ? InstallOperation::REPLACE_BZ : InstallOperation::REPLACE; EXPECT_EQ(1U, aops.size()); InstallOperation new_op = aops[0].op; diff --git a/payload_generator/cycle_breaker.cc b/payload_generator/cycle_breaker.cc index d76f679f..d6eeed2b 100644 --- a/payload_generator/cycle_breaker.cc +++ b/payload_generator/cycle_breaker.cc @@ -56,7 +56,7 @@ void CycleBreaker::BreakCycles(const Graph& graph, set<Edge>* out_cut_edges) { skipped_ops_ = 0; for (Graph::size_type i = 0; i < subgraph_.size(); i++) { - InstallOperation_Type op_type = graph[i].aop.op.type(); + InstallOperation::Type op_type = graph[i].aop.op.type(); if (op_type == InstallOperation::REPLACE || op_type == InstallOperation::REPLACE_BZ) { skipped_ops_++; diff --git a/payload_generator/delta_diff_utils.cc b/payload_generator/delta_diff_utils.cc index 1bad4d75..4ba6e24f 100644 --- a/payload_generator/delta_diff_utils.cc +++ b/payload_generator/delta_diff_utils.cc @@ -760,7 +760,7 @@ bool DeltaReadFile(vector<AnnotatedOperation>* aops, bool GenerateBestFullOperation(const brillo::Blob& new_data, const PayloadVersion& version, brillo::Blob* out_blob, - InstallOperation_Type* out_type) { + InstallOperation::Type* out_type) { if (new_data.empty()) return false; @@ -863,7 +863,7 @@ bool ReadExtentsToDiff(const string& old_part, // Try generating a full operation for the given new data, regardless of the // old_data. - InstallOperation_Type op_type; + InstallOperation::Type op_type; TEST_AND_RETURN_FALSE( GenerateBestFullOperation(new_data, version, &data_blob, &op_type)); operation.set_type(op_type); @@ -892,7 +892,7 @@ bool ReadExtentsToDiff(const string& old_part, ScopedPathUnlinker unlinker(patch.value()); std::unique_ptr<bsdiff::PatchWriterInterface> bsdiff_patch_writer; - InstallOperation_Type operation_type = InstallOperation::BSDIFF; + InstallOperation::Type operation_type = InstallOperation::BSDIFF; if (version.OperationAllowed(InstallOperation::BROTLI_BSDIFF)) { bsdiff_patch_writer = bsdiff::CreateBSDF2PatchWriter(patch.value(), @@ -1010,13 +1010,13 @@ bool ReadExtentsToDiff(const string& old_part, return true; } -bool IsAReplaceOperation(InstallOperation_Type op_type) { +bool IsAReplaceOperation(InstallOperation::Type op_type) { return (op_type == InstallOperation::REPLACE || op_type == InstallOperation::REPLACE_BZ || op_type == InstallOperation::REPLACE_XZ); } -bool IsNoSourceOperation(InstallOperation_Type op_type) { +bool IsNoSourceOperation(InstallOperation::Type op_type) { return (IsAReplaceOperation(op_type) || op_type == InstallOperation::ZERO || op_type == InstallOperation::DISCARD); } diff --git a/payload_generator/delta_diff_utils.h b/payload_generator/delta_diff_utils.h index 2306572c..2211b307 100644 --- a/payload_generator/delta_diff_utils.h +++ b/payload_generator/delta_diff_utils.h @@ -119,13 +119,13 @@ bool ReadExtentsToDiff(const std::string& old_part, bool GenerateBestFullOperation(const brillo::Blob& new_data, const PayloadVersion& version, brillo::Blob* out_blob, - InstallOperation_Type* out_type); + InstallOperation::Type* out_type); // Returns whether |op_type| is one of the REPLACE full operations. -bool IsAReplaceOperation(InstallOperation_Type op_type); +bool IsAReplaceOperation(InstallOperation::Type op_type); // Returns true if an operation with type |op_type| has no |src_extents|. -bool IsNoSourceOperation(InstallOperation_Type op_type); +bool IsNoSourceOperation(InstallOperation::Type op_type); // Returns true if |op| is a no-op operation that doesn't do any useful work // (e.g., a move operation that copies blocks onto themselves). diff --git a/payload_generator/delta_diff_utils_unittest.cc b/payload_generator/delta_diff_utils_unittest.cc index f730cc93..b2950e8b 100644 --- a/payload_generator/delta_diff_utils_unittest.cc +++ b/payload_generator/delta_diff_utils_unittest.cc @@ -390,7 +390,7 @@ TEST_F(DeltaDiffUtilsTest, ReplaceSmallTest) { EXPECT_FALSE(data.empty()); EXPECT_TRUE(op.has_type()); - const InstallOperation_Type expected_type = + const InstallOperation::Type expected_type = (i == 0 ? InstallOperation::REPLACE : InstallOperation::REPLACE_BZ); EXPECT_EQ(expected_type, op.type()); EXPECT_FALSE(op.has_data_offset()); diff --git a/payload_generator/full_update_generator.cc b/payload_generator/full_update_generator.cc index 4d8b2f99..94a43ab7 100644 --- a/payload_generator/full_update_generator.cc +++ b/payload_generator/full_update_generator.cc @@ -99,7 +99,7 @@ bool ChunkProcessor::ProcessChunk() { fd_, buffer_in_.data(), buffer_in_.size(), offset_, &bytes_read)); TEST_AND_RETURN_FALSE(bytes_read == static_cast<ssize_t>(size_)); - InstallOperation_Type op_type; + InstallOperation::Type op_type; TEST_AND_RETURN_FALSE(diff_utils::GenerateBestFullOperation( buffer_in_, version_, &op_blob, &op_type)); diff --git a/payload_generator/inplace_generator.cc b/payload_generator/inplace_generator.cc index ee19b620..d553cc41 100644 --- a/payload_generator/inplace_generator.cc +++ b/payload_generator/inplace_generator.cc @@ -273,7 +273,7 @@ void InplaceGenerator::MoveAndSortFullOpsToBack( vector<Vertex::Index> full_ops; ret.reserve(op_indexes->size()); for (auto op_index : *op_indexes) { - InstallOperation_Type type = (*graph)[op_index].aop.op.type(); + InstallOperation::Type type = (*graph)[op_index].aop.op.type(); if (type == InstallOperation::REPLACE || type == InstallOperation::REPLACE_BZ) { full_ops.push_back(op_index); diff --git a/payload_generator/inplace_generator_unittest.cc b/payload_generator/inplace_generator_unittest.cc index ab3b8671..8028f366 100644 --- a/payload_generator/inplace_generator_unittest.cc +++ b/payload_generator/inplace_generator_unittest.cc @@ -55,7 +55,7 @@ void GenVertex(Vertex* out, const vector<Extent>& src_extents, const vector<Extent>& dst_extents, const string& path, - InstallOperation_Type type) { + InstallOperation::Type type) { out->aop.op.set_type(type); out->aop.name = path; StoreExtents(src_extents, out->aop.op.mutable_src_extents()); diff --git a/payload_generator/payload_file.cc b/payload_generator/payload_file.cc index 775a509d..a111fd63 100644 --- a/payload_generator/payload_file.cc +++ b/payload_generator/payload_file.cc @@ -197,7 +197,7 @@ bool PayloadFile::WritePayload(const string& payload_file, uint64_t signature_blob_length = 0; if (!private_key_path.empty()) { TEST_AND_RETURN_FALSE(PayloadSigner::SignatureBlobLength( - vector<string>(1, private_key_path), &signature_blob_length)); + {private_key_path}, &signature_blob_length)); PayloadSigner::AddSignatureToManifest( next_blob_offset, signature_blob_length, @@ -207,7 +207,7 @@ bool PayloadFile::WritePayload(const string& payload_file, // Serialize protobuf string serialized_manifest; - TEST_AND_RETURN_FALSE(manifest_.AppendToString(&serialized_manifest)); + TEST_AND_RETURN_FALSE(manifest_.SerializeToString(&serialized_manifest)); uint64_t metadata_size = sizeof(kDeltaMagic) + 2 * sizeof(uint64_t) + serialized_manifest.size(); @@ -251,13 +251,12 @@ bool PayloadFile::WritePayload(const string& payload_file, // Write metadata signature blob. if (major_version_ == kBrilloMajorPayloadVersion && !private_key_path.empty()) { - brillo::Blob metadata_hash, metadata_signature; + brillo::Blob metadata_hash; TEST_AND_RETURN_FALSE(HashCalculator::RawHashOfFile( payload_file, metadata_size, &metadata_hash)); - TEST_AND_RETURN_FALSE( - PayloadSigner::SignHashWithKeys(metadata_hash, - vector<string>(1, private_key_path), - &metadata_signature)); + string metadata_signature; + TEST_AND_RETURN_FALSE(PayloadSigner::SignHashWithKeys( + metadata_hash, {private_key_path}, &metadata_signature)); TEST_AND_RETURN_FALSE_ERRNO( writer.Write(metadata_signature.data(), metadata_signature.size())); } @@ -281,16 +280,16 @@ bool PayloadFile::WritePayload(const string& payload_file, // Write payload signature blob. if (!private_key_path.empty()) { LOG(INFO) << "Signing the update..."; - brillo::Blob signature_blob; + string signature; TEST_AND_RETURN_FALSE(PayloadSigner::SignPayload( payload_file, - vector<string>(1, private_key_path), + {private_key_path}, metadata_size, metadata_signature_size, metadata_size + metadata_signature_size + manifest_.signatures_offset(), - &signature_blob)); + &signature)); TEST_AND_RETURN_FALSE_ERRNO( - writer.Write(signature_blob.data(), signature_blob.size())); + writer.Write(signature.data(), signature.size())); } ReportPayloadUsage(metadata_size); @@ -366,15 +365,15 @@ void PayloadFile::ReportPayloadUsage(uint64_t metadata_size) const { const DeltaObject& object = object_count.first; // Use printf() instead of LOG(INFO) because timestamp makes it difficult to // compare two reports. - printf( - kFormatString, - object.size * 100.0 / total_size, - object.size, - (object.type >= 0 ? InstallOperationTypeName( - static_cast<InstallOperation_Type>(object.type)) - : "-"), - object.name.c_str(), - object_count.second); + printf(kFormatString, + object.size * 100.0 / total_size, + object.size, + (object.type >= 0 + ? InstallOperationTypeName( + static_cast<InstallOperation::Type>(object.type)) + : "-"), + object.name.c_str(), + object_count.second); } printf(kFormatString, 100.0, total_size, "", "<total>", total_op); fflush(stdout); diff --git a/payload_generator/payload_generation_config.cc b/payload_generator/payload_generation_config.cc index 694c71fa..648fe8b9 100644 --- a/payload_generator/payload_generation_config.cc +++ b/payload_generator/payload_generation_config.cc @@ -222,7 +222,7 @@ bool PayloadVersion::Validate() const { return true; } -bool PayloadVersion::OperationAllowed(InstallOperation_Type operation) const { +bool PayloadVersion::OperationAllowed(InstallOperation::Type operation) const { switch (operation) { // Full operations: case InstallOperation::REPLACE: diff --git a/payload_generator/payload_generation_config.h b/payload_generator/payload_generation_config.h index 2153ab07..584ac7b6 100644 --- a/payload_generator/payload_generation_config.h +++ b/payload_generator/payload_generation_config.h @@ -165,7 +165,7 @@ struct PayloadVersion { bool Validate() const; // Return whether the passed |operation| is allowed by this payload. - bool OperationAllowed(InstallOperation_Type operation) const; + bool OperationAllowed(InstallOperation::Type operation) const; // Whether this payload version is a delta payload. bool IsDelta() const; diff --git a/payload_generator/payload_signer.cc b/payload_generator/payload_signer.cc index 2d0489a2..cbca7fe3 100644 --- a/payload_generator/payload_signer.cc +++ b/payload_generator/payload_signer.cc @@ -52,38 +52,36 @@ namespace { const uint32_t kSignatureMessageLegacyVersion = 1; // Given raw |signatures|, packs them into a protobuf and serializes it into a -// binary blob. Returns true on success, false otherwise. -bool ConvertSignatureToProtobufBlob(const vector<brillo::Blob>& signatures, - brillo::Blob* out_signature_blob) { +// string. Returns true on success, false otherwise. +bool ConvertSignaturesToProtobuf(const vector<brillo::Blob>& signatures, + string* out_serialized_signature) { // Pack it into a protobuf Signatures out_message; for (const brillo::Blob& signature : signatures) { - Signatures_Signature* sig_message = out_message.add_signatures(); + Signatures::Signature* sig_message = out_message.add_signatures(); // Set all the signatures with the same version number. sig_message->set_version(kSignatureMessageLegacyVersion); sig_message->set_data(signature.data(), signature.size()); } // Serialize protobuf - string serialized; - TEST_AND_RETURN_FALSE(out_message.AppendToString(&serialized)); - out_signature_blob->insert( - out_signature_blob->end(), serialized.begin(), serialized.end()); - LOG(INFO) << "Signature blob size: " << out_signature_blob->size(); + TEST_AND_RETURN_FALSE( + out_message.SerializeToString(out_serialized_signature)); + LOG(INFO) << "Signature blob size: " << out_serialized_signature->size(); return true; } -// Given an unsigned payload under |payload_path| and the |signature_blob| and -// |metadata_signature_blob| generates an updated payload that includes the +// Given an unsigned payload under |payload_path| and the |payload_signature| +// and |metadata_signature| generates an updated payload that includes the // signatures. It populates |out_metadata_size| with the size of the final // manifest after adding the dummy signature operation, and // |out_signatures_offset| with the expected offset for the new blob, and -// |out_metadata_signature_size| which will be size of |metadata_signature_blob| +// |out_metadata_signature_size| which will be size of |metadata_signature| // if the payload major version supports metadata signature, 0 otherwise. // Returns true on success, false otherwise. bool AddSignatureBlobToPayload(const string& payload_path, - const brillo::Blob& signature_blob, - const brillo::Blob& metadata_signature_blob, + const string& payload_signature, + const string& metadata_signature, brillo::Blob* out_payload, uint64_t* out_metadata_size, uint32_t* out_metadata_signature_size, @@ -100,8 +98,7 @@ bool AddSignatureBlobToPayload(const string& payload_path, payload_metadata.GetMetadataSignatureSize(); if (payload_metadata.GetMajorVersion() == kBrilloMajorPayloadVersion) { // Write metadata signature size in header. - uint32_t metadata_signature_size_be = - htobe32(metadata_signature_blob.size()); + uint32_t metadata_signature_size_be = htobe32(metadata_signature.size()); memcpy(payload.data() + manifest_offset, &metadata_signature_size_be, sizeof(metadata_signature_size_be)); @@ -110,9 +107,9 @@ bool AddSignatureBlobToPayload(const string& payload_path, payload.erase(payload.begin() + metadata_size, payload.begin() + metadata_size + metadata_signature_size); payload.insert(payload.begin() + metadata_size, - metadata_signature_blob.begin(), - metadata_signature_blob.end()); - metadata_signature_size = metadata_signature_blob.size(); + metadata_signature.begin(), + metadata_signature.end()); + metadata_signature_size = metadata_signature.size(); LOG(INFO) << "Metadata signature size: " << metadata_signature_size; } @@ -125,10 +122,10 @@ bool AddSignatureBlobToPayload(const string& payload_path, // contents. We don't allow the manifest to change if there is already an op // present, because that might invalidate previously generated // hashes/signatures. - if (manifest.signatures_size() != signature_blob.size()) { + if (manifest.signatures_size() != payload_signature.size()) { LOG(ERROR) << "Attempt to insert different signature sized blob. " << "(current:" << manifest.signatures_size() - << "new:" << signature_blob.size() << ")"; + << "new:" << payload_signature.size() << ")"; return false; } @@ -137,7 +134,7 @@ bool AddSignatureBlobToPayload(const string& payload_path, // Updates the manifest to include the signature operation. PayloadSigner::AddSignatureToManifest( payload.size() - metadata_size - metadata_signature_size, - signature_blob.size(), + payload_signature.size(), payload_metadata.GetMajorVersion() == kChromeOSMajorPayloadVersion, &manifest); @@ -164,8 +161,8 @@ bool AddSignatureBlobToPayload(const string& payload_path, LOG(INFO) << "Signature Blob Offset: " << signatures_offset; payload.resize(signatures_offset); payload.insert(payload.begin() + signatures_offset, - signature_blob.begin(), - signature_blob.end()); + payload_signature.begin(), + payload_signature.end()); *out_payload = std::move(payload); *out_metadata_size = metadata_size; @@ -253,21 +250,19 @@ bool PayloadSigner::VerifySignedPayload(const string& payload_path, signatures_offset, &payload_hash, &metadata_hash)); - brillo::Blob signature_blob(payload.begin() + signatures_offset, - payload.end()); + string signature(payload.begin() + signatures_offset, payload.end()); string public_key; TEST_AND_RETURN_FALSE(utils::ReadFile(public_key_path, &public_key)); TEST_AND_RETURN_FALSE(PayloadVerifier::PadRSA2048SHA256Hash(&payload_hash)); - TEST_AND_RETURN_FALSE(PayloadVerifier::VerifySignature( - signature_blob, public_key, payload_hash)); + TEST_AND_RETURN_FALSE( + PayloadVerifier::VerifySignature(signature, public_key, payload_hash)); if (metadata_signature_size) { - signature_blob.assign( - payload.begin() + metadata_size, - payload.begin() + metadata_size + metadata_signature_size); + signature.assign(payload.begin() + metadata_size, + payload.begin() + metadata_size + metadata_signature_size); TEST_AND_RETURN_FALSE( PayloadVerifier::PadRSA2048SHA256Hash(&metadata_hash)); - TEST_AND_RETURN_FALSE(PayloadVerifier::VerifySignature( - signature_blob, public_key, metadata_hash)); + TEST_AND_RETURN_FALSE( + PayloadVerifier::VerifySignature(signature, public_key, metadata_hash)); } return true; } @@ -311,7 +306,7 @@ bool PayloadSigner::SignHash(const brillo::Blob& hash, bool PayloadSigner::SignHashWithKeys(const brillo::Blob& hash_data, const vector<string>& private_key_paths, - brillo::Blob* out_signature_blob) { + string* out_serialized_signature) { vector<brillo::Blob> signatures; for (const string& path : private_key_paths) { brillo::Blob signature; @@ -319,7 +314,7 @@ bool PayloadSigner::SignHashWithKeys(const brillo::Blob& hash_data, signatures.push_back(signature); } TEST_AND_RETURN_FALSE( - ConvertSignatureToProtobufBlob(signatures, out_signature_blob)); + ConvertSignaturesToProtobuf(signatures, out_serialized_signature)); return true; } @@ -328,7 +323,7 @@ bool PayloadSigner::SignPayload(const string& unsigned_payload_path, const uint64_t metadata_size, const uint32_t metadata_signature_size, const uint64_t signatures_offset, - brillo::Blob* out_signature_blob) { + string* out_serialized_signature) { brillo::Blob payload; TEST_AND_RETURN_FALSE(utils::ReadFile(unsigned_payload_path, &payload)); brillo::Blob hash_data; @@ -339,16 +334,16 @@ bool PayloadSigner::SignPayload(const string& unsigned_payload_path, &hash_data, nullptr)); TEST_AND_RETURN_FALSE( - SignHashWithKeys(hash_data, private_key_paths, out_signature_blob)); + SignHashWithKeys(hash_data, private_key_paths, out_serialized_signature)); return true; } bool PayloadSigner::SignatureBlobLength(const vector<string>& private_key_paths, uint64_t* out_length) { DCHECK(out_length); - brillo::Blob x_blob(1, 'x'), hash_blob, sig_blob; - TEST_AND_RETURN_FALSE( - HashCalculator::RawHashOfBytes(x_blob.data(), x_blob.size(), &hash_blob)); + brillo::Blob hash_blob; + TEST_AND_RETURN_FALSE(HashCalculator::RawHashOfData({'x'}, &hash_blob)); + string sig_blob; TEST_AND_RETURN_FALSE( SignHashWithKeys(hash_blob, private_key_paths, &sig_blob)); *out_length = sig_blob.size(); @@ -365,17 +360,16 @@ bool PayloadSigner::HashPayloadForSigning(const string& payload_path, for (int signature_size : signature_sizes) { signatures.emplace_back(signature_size, 0); } - brillo::Blob signature_blob; - TEST_AND_RETURN_FALSE( - ConvertSignatureToProtobufBlob(signatures, &signature_blob)); + string signature; + TEST_AND_RETURN_FALSE(ConvertSignaturesToProtobuf(signatures, &signature)); brillo::Blob payload; uint64_t metadata_size, signatures_offset; uint32_t metadata_signature_size; // Prepare payload for hashing. TEST_AND_RETURN_FALSE(AddSignatureBlobToPayload(payload_path, - signature_blob, - signature_blob, + signature, + signature, &payload, &metadata_size, &metadata_signature_size, @@ -398,19 +392,19 @@ bool PayloadSigner::AddSignatureToPayload( // TODO(petkov): Reduce memory usage -- the payload is manipulated in memory. // Loads the payload and adds the signature op to it. - brillo::Blob signature_blob, metadata_signature_blob; + string payload_signature, metadata_signature; TEST_AND_RETURN_FALSE( - ConvertSignatureToProtobufBlob(payload_signatures, &signature_blob)); + ConvertSignaturesToProtobuf(payload_signatures, &payload_signature)); if (!metadata_signatures.empty()) { - TEST_AND_RETURN_FALSE(ConvertSignatureToProtobufBlob( - metadata_signatures, &metadata_signature_blob)); + TEST_AND_RETURN_FALSE( + ConvertSignaturesToProtobuf(metadata_signatures, &metadata_signature)); } brillo::Blob payload; uint64_t signatures_offset; uint32_t metadata_signature_size; TEST_AND_RETURN_FALSE(AddSignatureBlobToPayload(payload_path, - signature_blob, - metadata_signature_blob, + payload_signature, + metadata_signature, &payload, out_metadata_size, &metadata_signature_size, diff --git a/payload_generator/payload_signer.h b/payload_generator/payload_signer.h index b2d6606c..7854e126 100644 --- a/payload_generator/payload_signer.h +++ b/payload_generator/payload_signer.h @@ -54,17 +54,17 @@ class PayloadSigner { brillo::Blob* out_signature); // Sign |hash_data| blob with all private keys in |private_key_paths|, then - // convert the signatures to protobuf blob. + // convert the signatures to serialized protobuf. static bool SignHashWithKeys( const brillo::Blob& hash_data, const std::vector<std::string>& private_key_paths, - brillo::Blob* out_signature_blob); + std::string* out_serialized_signature); // Given an unsigned payload in |unsigned_payload_path|, private keys in // |private_key_path|, metadata size in |metadata_size|, metadata signature // size in |metadata_signature_size| and signatures offset in // |signatures_offset|, calculates the payload signature blob into - // |out_signature_blob|. Note that the payload must already have an + // |out_serialized_signature|. Note that the payload must already have an // updated manifest that includes the dummy signature op and correct metadata // signature size in header. Returns true on success, false otherwise. static bool SignPayload(const std::string& unsigned_payload_path, @@ -72,9 +72,9 @@ class PayloadSigner { const uint64_t metadata_size, const uint32_t metadata_signature_size, const uint64_t signatures_offset, - brillo::Blob* out_signature_blob); + std::string* out_serialized_signature); - // Returns the length of out_signature_blob that will result in a call + // Returns the length of out_serialized_signature that will result in a call // to SignPayload with the given private keys. Returns true on success. static bool SignatureBlobLength( const std::vector<std::string>& private_key_paths, uint64_t* out_length); diff --git a/payload_generator/payload_signer_unittest.cc b/payload_generator/payload_signer_unittest.cc index 52d51bc4..0b863b1e 100644 --- a/payload_generator/payload_signer_unittest.cc +++ b/payload_generator/payload_signer_unittest.cc @@ -86,19 +86,16 @@ const uint8_t kDataSignature[] = { 0x43, 0xb9, 0xab, 0x7d}; namespace { -void SignSampleData(brillo::Blob* out_signature_blob, - const vector<string>& private_keys) { - brillo::Blob data_blob(std::begin(kDataToSign), - std::begin(kDataToSign) + strlen(kDataToSign)); +void SignSampleData(string* out_signature, const vector<string>& private_keys) { uint64_t length = 0; EXPECT_TRUE(PayloadSigner::SignatureBlobLength(private_keys, &length)); EXPECT_GT(length, 0U); brillo::Blob hash_blob; EXPECT_TRUE(HashCalculator::RawHashOfBytes( - data_blob.data(), data_blob.size(), &hash_blob)); - EXPECT_TRUE(PayloadSigner::SignHashWithKeys( - hash_blob, private_keys, out_signature_blob)); - EXPECT_EQ(length, out_signature_blob->size()); + kDataToSign, strlen(kDataToSign), &hash_blob)); + EXPECT_TRUE( + PayloadSigner::SignHashWithKeys(hash_blob, private_keys, out_signature)); + EXPECT_EQ(length, out_signature->size()); } } // namespace @@ -112,18 +109,16 @@ class PayloadSignerTest : public ::testing::Test { }; TEST_F(PayloadSignerTest, SignSimpleTextTest) { - brillo::Blob signature_blob; - SignSampleData(&signature_blob, - {GetBuildArtifactsPath(kUnittestPrivateKeyPath)}); + string signature; + SignSampleData(&signature, {GetBuildArtifactsPath(kUnittestPrivateKeyPath)}); // Check the signature itself Signatures signatures; - EXPECT_TRUE( - signatures.ParseFromArray(signature_blob.data(), signature_blob.size())); + EXPECT_TRUE(signatures.ParseFromString(signature)); EXPECT_EQ(1, signatures.signatures_size()); - const Signatures_Signature& signature = signatures.signatures(0); - EXPECT_EQ(1U, signature.version()); - const string& sig_data = signature.data(); + const Signatures::Signature& sig = signatures.signatures(0); + EXPECT_EQ(1U, sig.version()); + const string& sig_data = sig.data(); ASSERT_EQ(arraysize(kDataSignature), sig_data.size()); for (size_t i = 0; i < arraysize(kDataSignature); i++) { EXPECT_EQ(kDataSignature[i], static_cast<uint8_t>(sig_data[i])); @@ -131,8 +126,8 @@ TEST_F(PayloadSignerTest, SignSimpleTextTest) { } TEST_F(PayloadSignerTest, VerifyAllSignatureTest) { - brillo::Blob signature_blob; - SignSampleData(&signature_blob, + string signature; + SignSampleData(&signature, {GetBuildArtifactsPath(kUnittestPrivateKeyPath), GetBuildArtifactsPath(kUnittestPrivateKey2Path)}); @@ -141,28 +136,27 @@ TEST_F(PayloadSignerTest, VerifyAllSignatureTest) { EXPECT_TRUE(utils::ReadFile(GetBuildArtifactsPath(kUnittestPublicKeyPath), &public_key)); EXPECT_TRUE(PayloadVerifier::VerifySignature( - signature_blob, public_key, padded_hash_data_)); + signature, public_key, padded_hash_data_)); EXPECT_TRUE(utils::ReadFile(GetBuildArtifactsPath(kUnittestPublicKey2Path), &public_key)); EXPECT_TRUE(PayloadVerifier::VerifySignature( - signature_blob, public_key, padded_hash_data_)); + signature, public_key, padded_hash_data_)); } TEST_F(PayloadSignerTest, VerifySignatureTest) { - brillo::Blob signature_blob; - SignSampleData(&signature_blob, - {GetBuildArtifactsPath(kUnittestPrivateKeyPath)}); + string signature; + SignSampleData(&signature, {GetBuildArtifactsPath(kUnittestPrivateKeyPath)}); string public_key; EXPECT_TRUE(utils::ReadFile(GetBuildArtifactsPath(kUnittestPublicKeyPath), &public_key)); EXPECT_TRUE(PayloadVerifier::VerifySignature( - signature_blob, public_key, padded_hash_data_)); + signature, public_key, padded_hash_data_)); // Passing the invalid key should fail the verification. EXPECT_TRUE(utils::ReadFile(GetBuildArtifactsPath(kUnittestPublicKey2Path), &public_key)); EXPECT_TRUE(PayloadVerifier::VerifySignature( - signature_blob, public_key, padded_hash_data_)); + signature, public_key, padded_hash_data_)); } TEST_F(PayloadSignerTest, SkipMetadataSignatureTest) { diff --git a/update_attempter_android.cc b/update_attempter_android.cc index c738e4ef..1cc85058 100644 --- a/update_attempter_android.cc +++ b/update_attempter_android.cc @@ -596,6 +596,9 @@ void UpdateAttempterAndroid::TerminateUpdateAndNotify(ErrorCode error_code) { CollectAndReportUpdateMetricsOnUpdateFinished(error_code); ClearMetricsPrefs(); if (error_code == ErrorCode::kSuccess) { + // We should only reset the PayloadAttemptNumber if the update succeeds, or + // we switch to a different payload. + prefs_->Delete(kPrefsPayloadAttemptNumber); metrics_utils::SetSystemUpdatedMarker(clock_.get(), prefs_); // Clear the total bytes downloaded if and only if the update succeeds. prefs_->SetInt64(kPrefsTotalBytesDownloaded, 0); @@ -826,7 +829,6 @@ void UpdateAttempterAndroid::ClearMetricsPrefs() { CHECK(prefs_); prefs_->Delete(kPrefsCurrentBytesDownloaded); prefs_->Delete(kPrefsNumReboots); - prefs_->Delete(kPrefsPayloadAttemptNumber); prefs_->Delete(kPrefsSystemUpdatedMarker); prefs_->Delete(kPrefsUpdateTimestampStart); prefs_->Delete(kPrefsUpdateBootTimestampStart); diff --git a/update_attempter_android.h b/update_attempter_android.h index e4b40ded..c4710ad5 100644 --- a/update_attempter_android.h +++ b/update_attempter_android.h @@ -151,9 +151,9 @@ class UpdateAttempterAndroid void UpdatePrefsOnUpdateStart(bool is_resume); // Prefs to delete: - // |kPrefsNumReboots|, |kPrefsPayloadAttemptNumber|, + // |kPrefsNumReboots|, |kPrefsCurrentBytesDownloaded| // |kPrefsSystemUpdatedMarker|, |kPrefsUpdateTimestampStart|, - // |kPrefsUpdateBootTimestampStart|, |kPrefsCurrentBytesDownloaded| + // |kPrefsUpdateBootTimestampStart| void ClearMetricsPrefs(); DaemonStateInterface* daemon_state_; diff --git a/update_attempter_android_unittest.cc b/update_attempter_android_unittest.cc index 2593d44a..3be0b7ea 100644 --- a/update_attempter_android_unittest.cc +++ b/update_attempter_android_unittest.cc @@ -111,9 +111,10 @@ TEST_F(UpdateAttempterAndroidTest, UpdatePrefsBuildVersionChangeOnInit) { update_attempter_android_.Init(); // Check that we reset the metric prefs. EXPECT_FALSE(prefs_.Exists(kPrefsNumReboots)); - EXPECT_FALSE(prefs_.Exists(kPrefsPayloadAttemptNumber)); EXPECT_FALSE(prefs_.Exists(kPrefsUpdateTimestampStart)); EXPECT_FALSE(prefs_.Exists(kPrefsSystemUpdatedMarker)); + // PayloadAttemptNumber should persist across reboots. + EXPECT_TRUE(prefs_.Exists(kPrefsPayloadAttemptNumber)); } TEST_F(UpdateAttempterAndroidTest, ReportMetricsOnUpdateTerminated) { |