AU: Add support for signing of update payloads after they're generated.
The change adds 2 methods -- one that takes an unsigned payload and a raw
signature size and returns the hash that needs to be signed, and another one
that takes an unsigned payload and a raw signature and generates the signed
payload.
BUG=chromium-os:10872
TEST=unit tests
Change-Id: I65bbe72a1ec67e603e78508c33893695b7de0e6a
Review URL: http://codereview.chromium.org/6265001
diff --git a/delta_performer.cc b/delta_performer.cc
index 6eb8aea..117e8f5 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -194,6 +194,43 @@
} // namespace {}
+DeltaPerformer::MetadataParseResult DeltaPerformer::ParsePayloadMetadata(
+ const std::vector<char>& payload,
+ DeltaArchiveManifest* manifest,
+ uint64_t* metadata_size) {
+ if (payload.size() < strlen(kDeltaMagic) +
+ kDeltaVersionLength + kDeltaProtobufLengthLength) {
+ // Don't have enough bytes to know the protobuf length.
+ return kMetadataParseInsufficientData;
+ }
+ if (memcmp(payload.data(), kDeltaMagic, strlen(kDeltaMagic)) != 0) {
+ LOG(ERROR) << "Bad payload format -- invalid delta magic.";
+ return kMetadataParseError;
+ }
+ uint64_t protobuf_length;
+ COMPILE_ASSERT(sizeof(protobuf_length) == kDeltaProtobufLengthLength,
+ protobuf_length_size_mismatch);
+ memcpy(&protobuf_length,
+ &payload[strlen(kDeltaMagic) + kDeltaVersionLength],
+ kDeltaProtobufLengthLength);
+ protobuf_length = be64toh(protobuf_length); // switch big endian to host
+ if (payload.size() < strlen(kDeltaMagic) + kDeltaVersionLength +
+ kDeltaProtobufLengthLength + protobuf_length) {
+ return kMetadataParseInsufficientData;
+ }
+ // We have the full proto buffer in |payload|. Parse it.
+ const int offset = strlen(kDeltaMagic) + kDeltaVersionLength +
+ kDeltaProtobufLengthLength;
+ if (!manifest->ParseFromArray(&payload[offset], protobuf_length)) {
+ LOG(ERROR) << "Unable to parse manifest in update file.";
+ return kMetadataParseError;
+ }
+ *metadata_size = strlen(kDeltaMagic) + kDeltaVersionLength +
+ kDeltaProtobufLengthLength + protobuf_length;
+ return kMetadataParseSuccess;
+}
+
+
// Wrapper around write. Returns bytes written on success or
// -errno on error.
// This function performs as many actions as it can, given the amount of
@@ -203,37 +240,17 @@
buffer_.insert(buffer_.end(), c_bytes, c_bytes + count);
if (!manifest_valid_) {
- if (buffer_.size() < strlen(kDeltaMagic) +
- kDeltaVersionLength + kDeltaProtobufLengthLength) {
- // Don't have enough bytes to know the protobuf length.
- return count;
- }
- if (memcmp(buffer_.data(), kDeltaMagic, strlen(kDeltaMagic)) != 0) {
- LOG(ERROR) << "Bad payload format -- invalid delta magic.";
+ MetadataParseResult result = ParsePayloadMetadata(buffer_,
+ &manifest_,
+ &manifest_metadata_size_);
+ if (result == kMetadataParseError) {
return -EINVAL;
}
- uint64_t protobuf_length;
- COMPILE_ASSERT(sizeof(protobuf_length) == kDeltaProtobufLengthLength,
- protobuf_length_size_mismatch);
- memcpy(&protobuf_length,
- &buffer_[strlen(kDeltaMagic) + kDeltaVersionLength],
- kDeltaProtobufLengthLength);
- protobuf_length = be64toh(protobuf_length); // switch big endian to host
- if (buffer_.size() < strlen(kDeltaMagic) + kDeltaVersionLength +
- kDeltaProtobufLengthLength + protobuf_length) {
+ if (result == kMetadataParseInsufficientData) {
return count;
}
- // We have the full proto buffer in buffer_. Parse it.
- const int offset = strlen(kDeltaMagic) + kDeltaVersionLength +
- kDeltaProtobufLengthLength;
- if (!manifest_.ParseFromArray(&buffer_[offset], protobuf_length)) {
- LOG(ERROR) << "Unable to parse manifest in update file.";
- return -EINVAL;
- }
// Remove protobuf and header info from buffer_, so buffer_ contains
// just data blobs
- manifest_metadata_size_ = strlen(kDeltaMagic) + kDeltaVersionLength +
- kDeltaProtobufLengthLength + protobuf_length;
DiscardBufferHeadBytes(manifest_metadata_size_);
LOG_IF(WARNING, !prefs_->SetInt64(kPrefsManifestMetadataSize,
manifest_metadata_size_))