Support needed for generating metadata signature in paygen
The metadata is the first portion of a payload that contains the following:
1. magic string ("CrOS")
2. version number
3. length of the manifest protobuf
4. manifest protobuf itself
<payload blobs begin here>
<payload signature as the last blob>
Currently we have a manifest signature which protects only #4 above. In
this CL we're extending the scope of manifest signature to include the rest
of the metadata (1-4). The reason we need to do this is to protect the
version value in HTTP as we're going to use it in future to have the
flexibility to change the protobuf format of the manifest.
Besides this change, this CL also contains:
1. Renaming of manifest_size and manifest_signature to metadata_size and
metadata_signature respectively to reflect the above change and keep
consistent terminology throughout. Also it renames protobuf_offset and
protobuf_length to manifest_offset and manifest_size to increase the
contextual semantics of the protobuf.
2. Addition of a new command-line option --out_metadata_hash_file in
delta_generator so that au_generate can use it in a subsequent CL to get
the SHA256 hash of the payload metadata in order to get it signed with
the signer.
3. Reusing LoadPayload in unit tests to get rid of some hardcoding. Also
updated delta_performer to localize such hardcoded constants within that
class and not have callers worry about those values.
BUG=chromium-os:33603
TEST=Tested on ZGB. Reran existing unit tests.
Change-Id: Iace5aebe8f7d054a0fa3a224a588ef52d85f510b
Reviewed-on: https://gerrit.chromium.org/gerrit/33726
Commit-Ready: Jay Srinivasan <jaysri@chromium.org>
Reviewed-by: Jay Srinivasan <jaysri@chromium.org>
Tested-by: Jay Srinivasan <jaysri@chromium.org>
diff --git a/payload_signer.h b/payload_signer.h
index 1c4a3eb..08135d2 100644
--- a/payload_signer.h
+++ b/payload_signer.h
@@ -9,6 +9,7 @@
#include <vector>
#include <base/basictypes.h>
+#include "update_engine/update_metadata.pb.h"
// This class encapsulates methods used for payload signing and signature
// verification. See update_metadata.proto for more info.
@@ -41,13 +42,35 @@
const std::vector<std::string>& private_key_paths,
uint64_t* out_length);
- // Given an unsigned payload in |payload_path| (with no dummy signature op)
- // and the raw |signature_sizes| calculates the raw hash that needs to be
- // signed in |out_hash_data|. Returns true on success, false otherwise.
+ // Given an unsigned payload in |payload_path| (with no dummy signature op),
+ // this method does two things:
+ // 1. It calculates the raw SHA256 hash of the entire payload in
+ // |payload_path| and returns the result in |out_hash_data|.
+ // 2. But before calculating the hash, it also inserts a dummy signature
+ // operation at the end of the manifest. This signature operation points to a
+ // blob offset and length that'll be later filled in by paygen with the
+ // actual signature from signer. But since the hash includes the signature
+ // operation, the signature operation has to be inserted before we compute
+ // the hash. Note, the hash doesn't cover the signature itself - it covers
+ // only the signature operation in manifest. Since paygen may add multiple
+ // signatures of different sizes (1024, 2048, etc.) it specifies a list
+ // of those |signature_sizes| so that the signature blob length is
+ // calculated to be of the correct size before the hash is computed.
+ // Returns true on success, false otherwise.
static bool HashPayloadForSigning(const std::string& payload_path,
const std::vector<int>& signature_sizes,
std::vector<char>* out_hash_data);
+ // Given an unsigned payload in |payload_path|, calculates the raw hash of
+ // just the metadata (not the entire payload) that needs to be signed in
+ // |out_hash_data|. Note: This method should be called only after calling the
+ // HashPayloadForSigning method so that the metadata hash is computed on the
+ // final metadata that will be in the payload (because HashPayloadForSigning
+ // adds a dummy signature operation to the manifest).
+ // Returns true on success, false otherwise.
+ static bool HashMetadataForSigning(const std::string& payload_path,
+ std::vector<char>* out_metadata_hash);
+
// Given an unsigned payload in |payload_path| (with no dummy signature op)
// and the raw |signatures| updates the payload to include the signature thus
// turning it into a signed payload. The new payload is stored in
@@ -95,11 +118,24 @@
// 2048 bits. Returns true on success, false otherwise.
static bool PadRSA2048SHA256Hash(std::vector<char>* hash);
- static bool GetManifestSignature(const char* manifest,
- size_t manifest_size,
+ // Computes the SHA256 hash of the first metadata_size bytes of |metadata|
+ // and signs the hash with the given private_key_path and writes the signed
+ // hash in |out_signature|. Returns true if successful or false if there was
+ // any error in the computations.
+ static bool GetMetadataSignature(const char* const metadata,
+ size_t metadata_size,
const std::string& private_key_path,
std::string* out_signature);
+ // Reads the payload from the given |payload_path| into the |out_payload|
+ // vector. It also parses the manifest protobuf in the payload and returns it
+ // in |out_manifest| along with the size of the entire metadata in
+ // |out_metadata_size|.
+ static bool LoadPayload(const std::string& payload_path,
+ std::vector<char>* out_payload,
+ DeltaArchiveManifest* out_manifest,
+ uint64_t* out_metadata_size);
+
private:
// This should never be constructed
DISALLOW_IMPLICIT_CONSTRUCTORS(PayloadSigner);