update_engine: Split payload signing and verification.

Payloads are only signed on server-side code (delta_generator) and
verified on both sides and unittest. This removes the dependency of
payload_generator/ code from delta_performer.cc by spliting the
payload signing and verification in two files.

Currently, both files are still included on all the built files.

This patch also includes some minor linter fixes.

BUG=chromium:394184
TEST=FEATURES="test" emerge-link update_engine; sudo emerge update_engine

Change-Id: Ia4268257f4260902bc37612f429f44ba7e8f65fd
Reviewed-on: https://chromium-review.googlesource.com/208540
Tested-by: Alex Deymo <deymo@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/delta_performer.cc b/delta_performer.cc
index 2008536..a22adfb 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -25,8 +25,8 @@
 #include "update_engine/extent_writer.h"
 #include "update_engine/hardware_interface.h"
 #include "update_engine/payload_constants.h"
-#include "update_engine/payload_signer.h"
 #include "update_engine/payload_state_interface.h"
+#include "update_engine/payload_verifier.h"
 #include "update_engine/prefs_interface.h"
 #include "update_engine/subprocess.h"
 #include "update_engine/terminator.h"
@@ -890,9 +890,9 @@
             << path_to_public_key.value();
 
   vector<char> expected_metadata_hash;
-  if (!PayloadSigner::GetRawHashFromSignature(metadata_signature,
-                                              path_to_public_key.value(),
-                                              &expected_metadata_hash)) {
+  if (!PayloadVerifier::GetRawHashFromSignature(metadata_signature,
+                                                path_to_public_key.value(),
+                                                &expected_metadata_hash)) {
     LOG(ERROR) << "Unable to compute expected hash from metadata signature";
     return ErrorCode::kDownloadMetadataSignatureError;
   }
@@ -905,7 +905,7 @@
   }
 
   vector<char> calculated_metadata_hash = metadata_hasher.raw_hash();
-  PayloadSigner::PadRSA2048SHA256Hash(&calculated_metadata_hash);
+  PayloadVerifier::PadRSA2048SHA256Hash(&calculated_metadata_hash);
   if (calculated_metadata_hash.empty()) {
     LOG(ERROR) << "Computed actual hash of metadata is empty.";
     return ErrorCode::kDownloadMetadataSignatureVerificationError;
@@ -1078,7 +1078,7 @@
                       !signatures_message_data_.empty());
   vector<char> signed_hash_data;
   TEST_AND_RETURN_VAL(ErrorCode::kDownloadPayloadPubKeyVerificationError,
-                      PayloadSigner::VerifySignature(
+                      PayloadVerifier::VerifySignature(
                           signatures_message_data_,
                           path_to_public_key.value(),
                           &signed_hash_data));
@@ -1088,7 +1088,7 @@
   TEST_AND_RETURN_VAL(ErrorCode::kDownloadPayloadPubKeyVerificationError,
                       signed_hasher.Finalize());
   vector<char> hash_data = signed_hasher.raw_hash();
-  PayloadSigner::PadRSA2048SHA256Hash(&hash_data);
+  PayloadVerifier::PadRSA2048SHA256Hash(&hash_data);
   TEST_AND_RETURN_VAL(ErrorCode::kDownloadPayloadPubKeyVerificationError,
                       !hash_data.empty());
   if (hash_data != signed_hash_data) {
diff --git a/delta_performer_unittest.cc b/delta_performer_unittest.cc
index 226427f..c2e4667 100644
--- a/delta_performer_unittest.cc
+++ b/delta_performer_unittest.cc
@@ -23,7 +23,8 @@
 #include "update_engine/fake_system_state.h"
 #include "update_engine/payload_constants.h"
 #include "update_engine/payload_generator/delta_diff_generator.h"
-#include "update_engine/payload_signer.h"
+#include "update_engine/payload_generator/payload_signer.h"
+#include "update_engine/payload_verifier.h"
 #include "update_engine/prefs_mock.h"
 #include "update_engine/test_utils.h"
 #include "update_engine/update_metadata.pb.h"
@@ -172,7 +173,7 @@
       vector<vector<char> >(1, signature),
       payload_path,
       out_metadata_size));
-  EXPECT_TRUE(PayloadSigner::VerifySignedPayload(
+  EXPECT_TRUE(PayloadVerifier::VerifySignedPayload(
       payload_path,
       kUnittestPublicKeyPath,
       kSignatureMessageOriginalVersion));
@@ -222,7 +223,7 @@
   // Pad the hash
   vector<char> hash;
   ASSERT_TRUE(utils::ReadFile(hash_file, &hash));
-  ASSERT_TRUE(PayloadSigner::PadRSA2048SHA256Hash(&hash));
+  ASSERT_TRUE(PayloadVerifier::PadRSA2048SHA256Hash(&hash));
   ASSERT_TRUE(WriteFileVector(hash_file, hash));
 
   string sig_file;
@@ -521,10 +522,10 @@
   // Check the metadata.
   {
     DeltaArchiveManifest manifest;
-    EXPECT_TRUE(PayloadSigner::LoadPayload(state->delta_path,
-                                           &state->delta,
-                                           &manifest,
-                                           &state->metadata_size));
+    EXPECT_TRUE(PayloadVerifier::LoadPayload(state->delta_path,
+                                             &state->delta,
+                                             &manifest,
+                                             &state->metadata_size));
     LOG(INFO) << "Metadata size: " << state->metadata_size;
 
 
diff --git a/payload_generator/delta_diff_generator.cc b/payload_generator/delta_diff_generator.cc
index 587892c..1367b17 100644
--- a/payload_generator/delta_diff_generator.cc
+++ b/payload_generator/delta_diff_generator.cc
@@ -39,8 +39,9 @@
 #include "update_engine/payload_generator/graph_types.h"
 #include "update_engine/payload_generator/graph_utils.h"
 #include "update_engine/payload_generator/metadata.h"
+#include "update_engine/payload_generator/payload_signer.h"
 #include "update_engine/payload_generator/topological_sort.h"
-#include "update_engine/payload_signer.h"
+#include "update_engine/payload_verifier.h"
 #include "update_engine/subprocess.h"
 #include "update_engine/update_metadata.pb.h"
 #include "update_engine/utils.h"
@@ -60,7 +61,7 @@
 const uint64_t kFullUpdateChunkSize = 1024 * 1024;  // bytes
 
 const size_t kBlockSize = 4096;  // bytes
-const string kNonexistentPath = "";
+const char kEmptyPath[] = "";
 
 static const char* kInstallOperationTypes[] = {
   "REPLACE",
@@ -81,7 +82,7 @@
 const size_t kRootFSPartitionSize = static_cast<size_t>(2) * 1024 * 1024 * 1024;
 
 // Needed for testing purposes, in case we can't use actual filesystem objects.
-// TODO(garnold)(chromium:331965) Replace this hack with a properly injected
+// TODO(garnold) (chromium:331965) Replace this hack with a properly injected
 // parameter in form of a mockable abstract class.
 bool (*get_extents_with_chunk_func)(const std::string&, off_t, off_t,
                                     std::vector<Extent>*) =
@@ -122,7 +123,7 @@
   vector<char> data;
   DeltaArchiveManifest_InstallOperation operation;
 
-  string old_path = (old_root == kNonexistentPath) ? kNonexistentPath :
+  string old_path = (old_root == kEmptyPath) ? kEmptyPath :
       old_root + path;
 
   // If bsdiff breaks again, blacklist the problem file by using:
@@ -243,7 +244,7 @@
                                           blocks,
                                           (should_diff_from_source ?
                                            old_root :
-                                           kNonexistentPath),
+                                           kEmptyPath),
                                           new_root,
                                           fs_iter.GetPartialPath(),
                                           offset,
@@ -470,7 +471,7 @@
                                          new_kernel_part,
                                          0,  // chunk_offset
                                          -1,  // chunk_size
-                                         true, // bsdiff_allowed
+                                         true,  // bsdiff_allowed
                                          &data,
                                          &op,
                                          false));
@@ -1038,19 +1039,20 @@
 
 class SortCutsByTopoOrderLess {
  public:
-  SortCutsByTopoOrderLess(vector<vector<Vertex::Index>::size_type>& table)
+  explicit SortCutsByTopoOrderLess(
+      const vector<vector<Vertex::Index>::size_type>& table)
       : table_(table) {}
   bool operator()(const CutEdgeVertexes& a, const CutEdgeVertexes& b) {
     return table_[a.old_dst] < table_[b.old_dst];
   }
  private:
-  vector<vector<Vertex::Index>::size_type>& table_;
+  const vector<vector<Vertex::Index>::size_type>& table_;
 };
 
 }  // namespace
 
 void DeltaDiffGenerator::GenerateReverseTopoOrderMap(
-    vector<Vertex::Index>& op_indexes,
+    const vector<Vertex::Index>& op_indexes,
     vector<vector<Vertex::Index>::size_type>* reverse_op_indexes) {
   vector<vector<Vertex::Index>::size_type> table(op_indexes.size());
   for (vector<Vertex::Index>::size_type i = 0, e = op_indexes.size();
@@ -1064,8 +1066,9 @@
   reverse_op_indexes->swap(table);
 }
 
-void DeltaDiffGenerator::SortCutsByTopoOrder(vector<Vertex::Index>& op_indexes,
-                                             vector<CutEdgeVertexes>* cuts) {
+void DeltaDiffGenerator::SortCutsByTopoOrder(
+    const vector<Vertex::Index>& op_indexes,
+    vector<CutEdgeVertexes>* cuts) {
   // first, make a reverse lookup table.
   vector<vector<Vertex::Index>::size_type> table;
   GenerateReverseTopoOrderMap(op_indexes, &table);
@@ -1438,7 +1441,7 @@
     TEST_AND_RETURN_FALSE(DeltaReadFile(graph,
                                         cut.old_dst,
                                         NULL,
-                                        kNonexistentPath,
+                                        kEmptyPath,
                                         new_root,
                                         (*graph)[cut.old_dst].file_name,
                                         (*graph)[cut.old_dst].chunk_offset,
@@ -1563,7 +1566,7 @@
         << "Old and new images have different block counts.";
 
     // If new_image_info is present, old_image_info must be present.
-    TEST_AND_RETURN_FALSE((bool)old_image_info == (bool)new_image_info);
+    TEST_AND_RETURN_FALSE(!old_image_info == !new_image_info);
   } else {
     // old_image_info must not be present for a full update.
     TEST_AND_RETURN_FALSE(!old_image_info);
diff --git a/payload_generator/delta_diff_generator.h b/payload_generator/delta_diff_generator.h
index 596d9c0..3c4ad69 100644
--- a/payload_generator/delta_diff_generator.h
+++ b/payload_generator/delta_diff_generator.h
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_PAYLOAD_GENERATOR_DELTA_DIFF_GENERATOR_H_
-#define CHROMEOS_PLATFORM_UPDATE_ENGINE_PAYLOAD_GENERATOR_DELTA_DIFF_GENERATOR_H_
+#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_DELTA_DIFF_GENERATOR_H_
+#define UPDATE_ENGINE_PAYLOAD_GENERATOR_DELTA_DIFF_GENERATOR_H_
 
+#include <set>
 #include <string>
 #include <vector>
 
@@ -167,8 +168,9 @@
 
   // Sorts the vector |cuts| by its |cuts[].old_dest| member. Order is
   // determined by the order of elements in op_indexes.
-  static void SortCutsByTopoOrder(std::vector<Vertex::Index>& op_indexes,
-                                  std::vector<CutEdgeVertexes>* cuts);
+  static void SortCutsByTopoOrder(
+      const std::vector<Vertex::Index>& op_indexes,
+      std::vector<CutEdgeVertexes>* cuts);
 
   // Returns true iff there are no extents in the graph that refer to temp
   // blocks. Temp blocks are in the range [kTempBlockStart, kSparseHole).
@@ -211,7 +213,7 @@
   // which the op is performed -> graph vertex index, and produces the
   // reverse: a mapping from graph vertex index -> op_indexes index.
   static void GenerateReverseTopoOrderMap(
-      std::vector<Vertex::Index>& op_indexes,
+      const std::vector<Vertex::Index>& op_indexes,
       std::vector<std::vector<Vertex::Index>::size_type>* reverse_op_indexes);
 
   // Takes a |graph|, which has edges that must be cut, as listed in
@@ -264,7 +266,7 @@
                              DeltaArchiveManifest* manifest);
 
  private:
- // This should never be constructed
+  // This should never be constructed.
   DISALLOW_IMPLICIT_CONSTRUCTORS(DeltaDiffGenerator);
 };
 
@@ -273,4 +275,4 @@
 
 };  // namespace chromeos_update_engine
 
-#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_PAYLOAD_GENERATOR_DELTA_DIFF_GENERATOR_H_
+#endif  // UPDATE_ENGINE_PAYLOAD_GENERATOR_DELTA_DIFF_GENERATOR_H_
diff --git a/payload_generator/delta_diff_generator_unittest.cc b/payload_generator/delta_diff_generator_unittest.cc
index c9ac8cf..977b34d 100644
--- a/payload_generator/delta_diff_generator_unittest.cc
+++ b/payload_generator/delta_diff_generator_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "update_engine/payload_generator/delta_diff_generator.h"
+
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -22,7 +24,6 @@
 #include "update_engine/extent_ranges.h"
 #include "update_engine/payload_constants.h"
 #include "update_engine/payload_generator/cycle_breaker.h"
-#include "update_engine/payload_generator/delta_diff_generator.h"
 #include "update_engine/payload_generator/extent_mapper.h"
 #include "update_engine/payload_generator/graph_types.h"
 #include "update_engine/payload_generator/graph_utils.h"
@@ -91,7 +92,7 @@
                                                  new_path(),
                                                  0,  // chunk_offset
                                                  -1,  // chunk_size
-                                                 true, // bsdiff_allowed
+                                                 true,  // bsdiff_allowed
                                                  &data,
                                                  &op,
                                                  true));
@@ -181,7 +182,7 @@
                                                  new_path(),
                                                  0,  // chunk_offset
                                                  -1,  // chunk_size
-                                                 true, // bsdiff_allowed
+                                                 true,  // bsdiff_allowed
                                                  &data,
                                                  &op,
                                                  true));
@@ -245,7 +246,7 @@
                                                  new_path(),
                                                  0,  // chunk_offset
                                                  -1,  // chunk_size
-                                                 true, // bsdiff_allowed
+                                                 true,  // bsdiff_allowed
                                                  &data,
                                                  &op,
                                                  true));
@@ -278,7 +279,7 @@
                                                  new_path(),
                                                  0,  // chunk_offset
                                                  -1,  // chunk_size
-                                                 false, // bsdiff_allowed
+                                                 false,  // bsdiff_allowed
                                                  &data,
                                                  &op,
                                                  true));
@@ -304,7 +305,7 @@
                                                  new_path(),
                                                  0,  // chunk_offset
                                                  -1,  // chunk_size
-                                                 false, // bsdiff_allowed
+                                                 false,  // bsdiff_allowed
                                                  &data,
                                                  &op,
                                                  true));
@@ -331,7 +332,7 @@
                                                    new_path(),
                                                    0,  // chunk_offset
                                                    -1,  // chunk_size
-                                                   true, // bsdiff_allowed
+                                                   true,  // bsdiff_allowed
                                                    &data,
                                                    &op,
                                                    true));
@@ -365,7 +366,7 @@
                                                  new_path(),
                                                  0,  // chunk_offset
                                                  -1,  // chunk_size
-                                                 true, // bsdiff_allowed
+                                                 true,  // bsdiff_allowed
                                                  &data,
                                                  &op,
                                                  false));
@@ -398,7 +399,7 @@
   extent->set_start_block(start);
   extent->set_num_blocks(length);
 }
-}
+}  // namespace
 
 TEST_F(DeltaDiffGeneratorTest, SubstituteBlocksTest) {
   vector<Extent> remove_blocks;
@@ -498,8 +499,8 @@
   cycle_breaker.BreakCycles(graph, &cut_edges);
 
   EXPECT_EQ(1, cut_edges.size());
-  EXPECT_TRUE(cut_edges.end() != cut_edges.find(make_pair<Vertex::Index>(1,
-                                                                         0)));
+  EXPECT_TRUE(cut_edges.end() != cut_edges.find(
+      std::pair<Vertex::Index, Vertex::Index>(1, 0)));
 
   vector<CutEdgeVertexes> cuts;
   EXPECT_TRUE(DeltaDiffGenerator::CutEdges(&graph, cut_edges, &cuts));
diff --git a/payload_generator/generate_delta_main.cc b/payload_generator/generate_delta_main.cc
index 89bb2b9..a2b6b3c 100644
--- a/payload_generator/generate_delta_main.cc
+++ b/payload_generator/generate_delta_main.cc
@@ -21,7 +21,8 @@
 
 #include "update_engine/delta_performer.h"
 #include "update_engine/payload_generator/delta_diff_generator.h"
-#include "update_engine/payload_signer.h"
+#include "update_engine/payload_generator/payload_signer.h"
+#include "update_engine/payload_verifier.h"
 #include "update_engine/prefs.h"
 #include "update_engine/subprocess.h"
 #include "update_engine/terminator.h"
@@ -142,7 +143,6 @@
                     const string& build_channel,
                     const string& build_version,
                     ImageInfo* image_info) {
-
   // All of these arguments should be present or missing.
   bool empty = channel.empty();
 
@@ -237,8 +237,8 @@
       << "Must pass --in_file to verify signed payload.";
   LOG_IF(FATAL, FLAGS_public_key.empty())
       << "Must pass --public_key to verify signed payload.";
-  CHECK(PayloadSigner::VerifySignedPayload(FLAGS_in_file, FLAGS_public_key,
-                                           FLAGS_public_key_version));
+  CHECK(PayloadVerifier::VerifySignedPayload(FLAGS_in_file, FLAGS_public_key,
+                                             FLAGS_public_key_version));
   LOG(INFO) << "Done verifying signed payload.";
 }
 
diff --git a/payload_signer.cc b/payload_generator/payload_signer.cc
similarity index 63%
rename from payload_signer.cc
rename to payload_generator/payload_signer.cc
index 3d09737..4bbb155 100644
--- a/payload_signer.cc
+++ b/payload_generator/payload_signer.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "update_engine/payload_signer.h"
+#include "update_engine/payload_generator/payload_signer.h"
 
 #include <base/logging.h>
 #include <base/strings/string_split.h>
 #include <base/strings/string_util.h>
 #include <openssl/pem.h>
 
-#include "update_engine/delta_performer.h"
 #include "update_engine/omaha_hash_calculator.h"
 #include "update_engine/payload_generator/delta_diff_generator.h"
+#include "update_engine/payload_verifier.h"
 #include "update_engine/subprocess.h"
 #include "update_engine/update_metadata.pb.h"
 #include "update_engine/utils.h"
@@ -21,64 +21,8 @@
 
 namespace chromeos_update_engine {
 
-const uint32_t kSignatureMessageOriginalVersion = 1;
-const uint32_t kSignatureMessageCurrentVersion = 1;
-
 namespace {
 
-// The following is a standard PKCS1-v1_5 padding for SHA256 signatures, as
-// defined in RFC3447. It is prepended to the actual signature (32 bytes) to
-// form a sequence of 256 bytes (2048 bits) that is amenable to RSA signing. The
-// padded hash will look as follows:
-//
-//    0x00 0x01 0xff ... 0xff 0x00  ASN1HEADER  SHA256HASH
-//   |--------------205-----------||----19----||----32----|
-//
-// where ASN1HEADER is the ASN.1 description of the signed data. The complete 51
-// bytes of actual data (i.e. the ASN.1 header complete with the hash) are
-// packed as follows:
-//
-//  SEQUENCE(2+49) {
-//   SEQUENCE(2+13) {
-//    OBJECT(2+9) id-sha256
-//    NULL(2+0)
-//   }
-//   OCTET STRING(2+32) <actual signature bytes...>
-//  }
-const unsigned char kRSA2048SHA256Padding[] = {
-  // PKCS1-v1_5 padding
-  0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0x00,
-  // ASN.1 header
-  0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-  0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
-  0x00, 0x04, 0x20,
-};
-
 // 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<vector<char> >& signatures,
@@ -128,7 +72,7 @@
   vector<char> payload;
   DeltaArchiveManifest manifest;
   uint64_t metadata_size;
-  TEST_AND_RETURN_FALSE(PayloadSigner::LoadPayload(
+  TEST_AND_RETURN_FALSE(PayloadVerifier::LoadPayload(
       payload_path, &payload, &manifest, &metadata_size));
 
   // Is there already a signature op in place?
@@ -178,27 +122,6 @@
 }
 }  // namespace
 
-bool PayloadSigner::LoadPayload(const string& payload_path,
-                 vector<char>* out_payload,
-                 DeltaArchiveManifest* out_manifest,
-                 uint64_t* out_metadata_size) {
-  vector<char> payload;
-  // Loads the payload and parses the manifest.
-  TEST_AND_RETURN_FALSE(utils::ReadFile(payload_path, &payload));
-  LOG(INFO) << "Payload size: " << payload.size();
-  ErrorCode error = ErrorCode::kSuccess;
-  InstallPlan install_plan;
-  DeltaPerformer delta_performer(NULL, NULL, &install_plan);
-  TEST_AND_RETURN_FALSE(
-      delta_performer.ParsePayloadMetadata(payload, &error) ==
-      DeltaPerformer::kMetadataParseSuccess);
-  TEST_AND_RETURN_FALSE(delta_performer.GetManifest(out_manifest));
-  *out_metadata_size = delta_performer.GetMetadataSize();
-  LOG(INFO) << "Metadata size: " << *out_metadata_size;
-  out_payload->swap(payload);
-  return true;
-}
-
 bool PayloadSigner::SignHash(const vector<char>& hash,
                              const string& private_key_path,
                              vector<char>* out_signature) {
@@ -215,7 +138,7 @@
   // We expect unpadded SHA256 hash coming in
   TEST_AND_RETURN_FALSE(hash.size() == 32);
   vector<char> padded_hash(hash);
-  PadRSA2048SHA256Hash(&padded_hash);
+  PayloadVerifier::PadRSA2048SHA256Hash(&padded_hash);
   TEST_AND_RETURN_FALSE(utils::WriteFile(hash_path.c_str(),
                                          padded_hash.data(),
                                          padded_hash.size()));
@@ -282,116 +205,6 @@
   return true;
 }
 
-bool PayloadSigner::VerifySignature(const std::vector<char>& signature_blob,
-                                    const std::string& public_key_path,
-                                    std::vector<char>* out_hash_data) {
-  return VerifySignatureBlob(signature_blob, public_key_path,
-                                kSignatureMessageCurrentVersion, out_hash_data);
-}
-
-bool PayloadSigner::VerifySignatureBlob(
-    const std::vector<char>& signature_blob,
-    const std::string& public_key_path,
-    uint32_t client_version,
-    std::vector<char>* out_hash_data) {
-  TEST_AND_RETURN_FALSE(!public_key_path.empty());
-
-  Signatures signatures;
-  LOG(INFO) << "signature size = " <<  signature_blob.size();
-  TEST_AND_RETURN_FALSE(signatures.ParseFromArray(&signature_blob[0],
-                                                  signature_blob.size()));
-
-  // Finds a signature that matches the current version.
-  int sig_index = 0;
-  for (; sig_index < signatures.signatures_size(); sig_index++) {
-    const Signatures_Signature& signature = signatures.signatures(sig_index);
-    if (signature.has_version() &&
-        signature.version() == client_version) {
-      break;
-    }
-  }
-  TEST_AND_RETURN_FALSE(sig_index < signatures.signatures_size());
-
-  const Signatures_Signature& signature = signatures.signatures(sig_index);
-  vector<char> sig_data(signature.data().begin(), signature.data().end());
-
-  return GetRawHashFromSignature(sig_data, public_key_path, out_hash_data);
-}
-
-
-bool PayloadSigner::GetRawHashFromSignature(
-    const std::vector<char>& sig_data,
-    const std::string& public_key_path,
-    std::vector<char>* out_hash_data) {
-  TEST_AND_RETURN_FALSE(!public_key_path.empty());
-
-  // The code below executes the equivalent of:
-  //
-  // openssl rsautl -verify -pubin -inkey |public_key_path|
-  //   -in |sig_data| -out |out_hash_data|
-
-  // Loads the public key.
-  FILE* fpubkey = fopen(public_key_path.c_str(), "rb");
-  if (!fpubkey) {
-    LOG(ERROR) << "Unable to open public key file: " << public_key_path;
-    return false;
-  }
-
-  char dummy_password[] = { ' ', 0 };  // Ensure no password is read from stdin.
-  RSA* rsa = PEM_read_RSA_PUBKEY(fpubkey, NULL, NULL, dummy_password);
-  fclose(fpubkey);
-  TEST_AND_RETURN_FALSE(rsa != NULL);
-  unsigned int keysize = RSA_size(rsa);
-  if (sig_data.size() > 2 * keysize) {
-    LOG(ERROR) << "Signature size is too big for public key size.";
-    RSA_free(rsa);
-    return false;
-  }
-
-  // Decrypts the signature.
-  vector<char> hash_data(keysize);
-  int decrypt_size = RSA_public_decrypt(
-      sig_data.size(),
-      reinterpret_cast<const unsigned char*>(sig_data.data()),
-      reinterpret_cast<unsigned char*>(hash_data.data()),
-      rsa,
-      RSA_NO_PADDING);
-  RSA_free(rsa);
-  TEST_AND_RETURN_FALSE(decrypt_size > 0 &&
-                        decrypt_size <= static_cast<int>(hash_data.size()));
-  hash_data.resize(decrypt_size);
-  out_hash_data->swap(hash_data);
-  return true;
-}
-
-bool PayloadSigner::VerifySignedPayload(const std::string& payload_path,
-                                        const std::string& public_key_path,
-                                        uint32_t client_key_check_version) {
-  vector<char> payload;
-  DeltaArchiveManifest manifest;
-  uint64_t metadata_size;
-  TEST_AND_RETURN_FALSE(LoadPayload(
-      payload_path, &payload, &manifest, &metadata_size));
-  TEST_AND_RETURN_FALSE(manifest.has_signatures_offset() &&
-                        manifest.has_signatures_size());
-  CHECK_EQ(payload.size(),
-           metadata_size + manifest.signatures_offset() +
-           manifest.signatures_size());
-  vector<char> signature_blob(
-      payload.begin() + metadata_size + manifest.signatures_offset(),
-      payload.end());
-  vector<char> signed_hash;
-  TEST_AND_RETURN_FALSE(VerifySignatureBlob(
-      signature_blob, public_key_path, client_key_check_version, &signed_hash));
-  TEST_AND_RETURN_FALSE(!signed_hash.empty());
-  vector<char> hash;
-  TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes(
-      payload.data(), metadata_size + manifest.signatures_offset(), &hash));
-  PadRSA2048SHA256Hash(&hash);
-  TEST_AND_RETURN_FALSE(hash == signed_hash);
-  return true;
-}
-
 bool PayloadSigner::PrepPayloadForHashing(
         const string& payload_path,
         const vector<int>& signature_sizes,
@@ -492,16 +305,6 @@
   return true;
 }
 
-bool PayloadSigner::PadRSA2048SHA256Hash(std::vector<char>* hash) {
-  TEST_AND_RETURN_FALSE(hash->size() == 32);
-  hash->insert(hash->begin(),
-               reinterpret_cast<const char*>(kRSA2048SHA256Padding),
-               reinterpret_cast<const char*>(kRSA2048SHA256Padding +
-                                             sizeof(kRSA2048SHA256Padding)));
-  TEST_AND_RETURN_FALSE(hash->size() == 256);
-  return true;
-}
-
 bool PayloadSigner::GetMetadataSignature(const char* const metadata,
                                          size_t metadata_size,
                                          const string& private_key_path,
diff --git a/payload_signer.h b/payload_generator/payload_signer.h
similarity index 61%
rename from payload_signer.h
rename to payload_generator/payload_signer.h
index d4215f5..0c540e6 100644
--- a/payload_signer.h
+++ b/payload_generator/payload_signer.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef UPDATE_ENGINE_PAYLOAD_SIGNER_H_
-#define UPDATE_ENGINE_PAYLOAD_SIGNER_H_
+#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_PAYLOAD_SIGNER_H_
+#define UPDATE_ENGINE_PAYLOAD_GENERATOR_PAYLOAD_SIGNER_H_
 
 #include <string>
 #include <vector>
@@ -11,14 +11,11 @@
 #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.
+// This class encapsulates methods used for payload signing.
+// See update_metadata.proto for more info.
 
 namespace chromeos_update_engine {
 
-extern const uint32_t kSignatureMessageOriginalVersion;
-extern const uint32_t kSignatureMessageCurrentVersion;
-
 class PayloadSigner {
  public:
   // Given a raw |hash| and a private key in |private_key_path| calculates the
@@ -92,43 +89,6 @@
       const std::string& signed_payload_path,
       uint64_t* out_metadata_size);
 
-  // Returns false if the payload signature can't be verified. Returns true
-  // otherwise and sets |out_hash| to the signed payload hash.
-  static bool VerifySignature(const std::vector<char>& signature_blob,
-                              const std::string& public_key_path,
-                              std::vector<char>* out_hash_data);
-
-  // Interprets signature_blob as a protocol buffer containing the Signatures
-  // message and decrypts the signature data using the public_key_path and
-  // stores the resultant raw hash data in out_hash_data. Returns true if
-  // everything is successful. False otherwise. It also takes the client_version
-  // and interprets the signature blob according to that version.
-  static bool VerifySignatureBlob(const std::vector<char>& signature_blob,
-                                  const std::string& public_key_path,
-                                  uint32_t client_version,
-                                  std::vector<char>* out_hash_data);
-
-  // Decrypts sig_data with the given public_key_path and populates
-  // out_hash_data with the decoded raw hash. Returns true if successful,
-  // false otherwise.
-  static bool GetRawHashFromSignature(const std::vector<char>& sig_data,
-                                      const std::string& public_key_path,
-                                      std::vector<char>* out_hash_data);
-
-  // Returns true if the payload in |payload_path| is signed and its hash can be
-  // verified using the public key in |public_key_path| with the signature
-  // of a given version in the signature blob. Returns false otherwise.
-  static bool VerifySignedPayload(const std::string& payload_path,
-                                  const std::string& public_key_path,
-                                  uint32_t client_key_check_version);
-
-  // Pads a SHA256 hash so that it may be encrypted/signed with RSA2048
-  // using the PKCS#1 v1.5 scheme.
-  // hash should be a pointer to vector of exactly 256 bits. The vector
-  // will be modified in place and will result in having a length of
-  // 2048 bits. Returns true on success, false otherwise.
-  static bool PadRSA2048SHA256Hash(std::vector<char>* hash);
-
   // 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
@@ -138,15 +98,6 @@
                                    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);
@@ -154,4 +105,4 @@
 
 }  // namespace chromeos_update_engine
 
-#endif  // UPDATE_ENGINE_PAYLOAD_SIGNER_H_
+#endif  // UPDATE_ENGINE_PAYLOAD_GENERATOR_PAYLOAD_SIGNER_H_
diff --git a/payload_signer_unittest.cc b/payload_generator/payload_signer_unittest.cc
similarity index 95%
rename from payload_signer_unittest.cc
rename to payload_generator/payload_signer_unittest.cc
index 829fdd8..00df88c 100644
--- a/payload_signer_unittest.cc
+++ b/payload_generator/payload_signer_unittest.cc
@@ -2,11 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "update_engine/payload_generator/payload_signer.h"
+
 #include <string>
 #include <vector>
+
+#include <base/logging.h>
 #include <gtest/gtest.h>
-#include "base/logging.h"
-#include "update_engine/payload_signer.h"
+
+#include "update_engine/payload_verifier.h"
 #include "update_engine/update_metadata.pb.h"
 #include "update_engine/utils.h"
 
@@ -122,13 +126,13 @@
   SignSampleData(&signature_blob);
 
   vector<char> hash_data;
-  EXPECT_TRUE(PayloadSigner::VerifySignature(signature_blob,
+  EXPECT_TRUE(PayloadVerifier::VerifySignature(signature_blob,
                                              kUnittestPublicKeyPath,
                                              &hash_data));
   vector<char> padded_hash_data(reinterpret_cast<const char *>(kDataHash),
                                 reinterpret_cast<const char *>(kDataHash +
                                                          sizeof(kDataHash)));
-  PayloadSigner::PadRSA2048SHA256Hash(&padded_hash_data);
+  PayloadVerifier::PadRSA2048SHA256Hash(&padded_hash_data);
   ASSERT_EQ(padded_hash_data.size(), hash_data.size());
   for (size_t i = 0; i < padded_hash_data.size(); i++) {
     EXPECT_EQ(padded_hash_data[i], hash_data[i]);
diff --git a/payload_verifier.cc b/payload_verifier.cc
new file mode 100644
index 0000000..fa23d4f
--- /dev/null
+++ b/payload_verifier.cc
@@ -0,0 +1,222 @@
+// Copyright 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "update_engine/payload_verifier.h"
+
+#include <base/logging.h>
+#include <openssl/pem.h>
+
+#include "update_engine/delta_performer.h"
+#include "update_engine/omaha_hash_calculator.h"
+#include "update_engine/payload_generator/delta_diff_generator.h"
+#include "update_engine/update_metadata.pb.h"
+#include "update_engine/utils.h"
+
+using std::string;
+using std::vector;
+
+namespace chromeos_update_engine {
+
+const uint32_t kSignatureMessageOriginalVersion = 1;
+const uint32_t kSignatureMessageCurrentVersion = 1;
+
+namespace {
+
+// The following is a standard PKCS1-v1_5 padding for SHA256 signatures, as
+// defined in RFC3447. It is prepended to the actual signature (32 bytes) to
+// form a sequence of 256 bytes (2048 bits) that is amenable to RSA signing. The
+// padded hash will look as follows:
+//
+//    0x00 0x01 0xff ... 0xff 0x00  ASN1HEADER  SHA256HASH
+//   |--------------205-----------||----19----||----32----|
+//
+// where ASN1HEADER is the ASN.1 description of the signed data. The complete 51
+// bytes of actual data (i.e. the ASN.1 header complete with the hash) are
+// packed as follows:
+//
+//  SEQUENCE(2+49) {
+//   SEQUENCE(2+13) {
+//    OBJECT(2+9) id-sha256
+//    NULL(2+0)
+//   }
+//   OCTET STRING(2+32) <actual signature bytes...>
+//  }
+const unsigned char kRSA2048SHA256Padding[] = {
+  // PKCS1-v1_5 padding
+  0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00,
+  // ASN.1 header
+  0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+  0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+  0x00, 0x04, 0x20,
+};
+
+}  // namespace
+
+bool PayloadVerifier::LoadPayload(const string& payload_path,
+                                  vector<char>* out_payload,
+                                  DeltaArchiveManifest* out_manifest,
+                                  uint64_t* out_metadata_size) {
+  vector<char> payload;
+  // Loads the payload and parses the manifest.
+  TEST_AND_RETURN_FALSE(utils::ReadFile(payload_path, &payload));
+  LOG(INFO) << "Payload size: " << payload.size();
+  ErrorCode error = ErrorCode::kSuccess;
+  InstallPlan install_plan;
+  DeltaPerformer delta_performer(NULL, NULL, &install_plan);
+  TEST_AND_RETURN_FALSE(
+      delta_performer.ParsePayloadMetadata(payload, &error) ==
+      DeltaPerformer::kMetadataParseSuccess);
+  TEST_AND_RETURN_FALSE(delta_performer.GetManifest(out_manifest));
+  *out_metadata_size = delta_performer.GetMetadataSize();
+  LOG(INFO) << "Metadata size: " << *out_metadata_size;
+  out_payload->swap(payload);
+  return true;
+}
+
+bool PayloadVerifier::VerifySignature(const std::vector<char>& signature_blob,
+                                      const std::string& public_key_path,
+                                      std::vector<char>* out_hash_data) {
+  return VerifySignatureBlob(signature_blob, public_key_path,
+                             kSignatureMessageCurrentVersion, out_hash_data);
+}
+
+bool PayloadVerifier::VerifySignatureBlob(
+    const std::vector<char>& signature_blob,
+    const std::string& public_key_path,
+    uint32_t client_version,
+    std::vector<char>* out_hash_data) {
+  TEST_AND_RETURN_FALSE(!public_key_path.empty());
+
+  Signatures signatures;
+  LOG(INFO) << "signature size = " <<  signature_blob.size();
+  TEST_AND_RETURN_FALSE(signatures.ParseFromArray(&signature_blob[0],
+                                                  signature_blob.size()));
+
+  // Finds a signature that matches the current version.
+  int sig_index = 0;
+  for (; sig_index < signatures.signatures_size(); sig_index++) {
+    const Signatures_Signature& signature = signatures.signatures(sig_index);
+    if (signature.has_version() &&
+        signature.version() == client_version) {
+      break;
+    }
+  }
+  TEST_AND_RETURN_FALSE(sig_index < signatures.signatures_size());
+
+  const Signatures_Signature& signature = signatures.signatures(sig_index);
+  vector<char> sig_data(signature.data().begin(), signature.data().end());
+
+  return GetRawHashFromSignature(sig_data, public_key_path, out_hash_data);
+}
+
+
+bool PayloadVerifier::GetRawHashFromSignature(
+    const std::vector<char>& sig_data,
+    const std::string& public_key_path,
+    std::vector<char>* out_hash_data) {
+  TEST_AND_RETURN_FALSE(!public_key_path.empty());
+
+  // The code below executes the equivalent of:
+  //
+  // openssl rsautl -verify -pubin -inkey |public_key_path|
+  //   -in |sig_data| -out |out_hash_data|
+
+  // Loads the public key.
+  FILE* fpubkey = fopen(public_key_path.c_str(), "rb");
+  if (!fpubkey) {
+    LOG(ERROR) << "Unable to open public key file: " << public_key_path;
+    return false;
+  }
+
+  char dummy_password[] = { ' ', 0 };  // Ensure no password is read from stdin.
+  RSA* rsa = PEM_read_RSA_PUBKEY(fpubkey, NULL, NULL, dummy_password);
+  fclose(fpubkey);
+  TEST_AND_RETURN_FALSE(rsa != NULL);
+  unsigned int keysize = RSA_size(rsa);
+  if (sig_data.size() > 2 * keysize) {
+    LOG(ERROR) << "Signature size is too big for public key size.";
+    RSA_free(rsa);
+    return false;
+  }
+
+  // Decrypts the signature.
+  vector<char> hash_data(keysize);
+  int decrypt_size = RSA_public_decrypt(
+      sig_data.size(),
+      reinterpret_cast<const unsigned char*>(sig_data.data()),
+      reinterpret_cast<unsigned char*>(hash_data.data()),
+      rsa,
+      RSA_NO_PADDING);
+  RSA_free(rsa);
+  TEST_AND_RETURN_FALSE(decrypt_size > 0 &&
+                        decrypt_size <= static_cast<int>(hash_data.size()));
+  hash_data.resize(decrypt_size);
+  out_hash_data->swap(hash_data);
+  return true;
+}
+
+bool PayloadVerifier::VerifySignedPayload(const std::string& payload_path,
+                                          const std::string& public_key_path,
+                                          uint32_t client_key_check_version) {
+  vector<char> payload;
+  DeltaArchiveManifest manifest;
+  uint64_t metadata_size;
+  TEST_AND_RETURN_FALSE(LoadPayload(
+      payload_path, &payload, &manifest, &metadata_size));
+  TEST_AND_RETURN_FALSE(manifest.has_signatures_offset() &&
+                        manifest.has_signatures_size());
+  CHECK_EQ(payload.size(),
+           metadata_size + manifest.signatures_offset() +
+           manifest.signatures_size());
+  vector<char> signature_blob(
+      payload.begin() + metadata_size + manifest.signatures_offset(),
+      payload.end());
+  vector<char> signed_hash;
+  TEST_AND_RETURN_FALSE(VerifySignatureBlob(
+      signature_blob, public_key_path, client_key_check_version, &signed_hash));
+  TEST_AND_RETURN_FALSE(!signed_hash.empty());
+  vector<char> hash;
+  TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes(
+      payload.data(), metadata_size + manifest.signatures_offset(), &hash));
+  PadRSA2048SHA256Hash(&hash);
+  TEST_AND_RETURN_FALSE(hash == signed_hash);
+  return true;
+}
+
+bool PayloadVerifier::PadRSA2048SHA256Hash(std::vector<char>* hash) {
+  TEST_AND_RETURN_FALSE(hash->size() == 32);
+  hash->insert(hash->begin(),
+               reinterpret_cast<const char*>(kRSA2048SHA256Padding),
+               reinterpret_cast<const char*>(kRSA2048SHA256Padding +
+                                             sizeof(kRSA2048SHA256Padding)));
+  TEST_AND_RETURN_FALSE(hash->size() == 256);
+  return true;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_verifier.h b/payload_verifier.h
new file mode 100644
index 0000000..ba392c9
--- /dev/null
+++ b/payload_verifier.h
@@ -0,0 +1,77 @@
+// Copyright 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UPDATE_ENGINE_PAYLOAD_VERIFIER_H_
+#define UPDATE_ENGINE_PAYLOAD_VERIFIER_H_
+
+#include <string>
+#include <vector>
+
+#include <base/basictypes.h>
+#include "update_engine/update_metadata.pb.h"
+
+// This class encapsulates methods used for payload signature verification.
+// See payload_generator/payload_signer.h for payload signing.
+
+namespace chromeos_update_engine {
+
+extern const uint32_t kSignatureMessageOriginalVersion;
+extern const uint32_t kSignatureMessageCurrentVersion;
+
+class PayloadVerifier {
+ public:
+  // Returns false if the payload signature can't be verified. Returns true
+  // otherwise and sets |out_hash| to the signed payload hash.
+  static bool VerifySignature(const std::vector<char>& signature_blob,
+                              const std::string& public_key_path,
+                              std::vector<char>* out_hash_data);
+
+  // Interprets signature_blob as a protocol buffer containing the Signatures
+  // message and decrypts the signature data using the public_key_path and
+  // stores the resultant raw hash data in out_hash_data. Returns true if
+  // everything is successful. False otherwise. It also takes the client_version
+  // and interprets the signature blob according to that version.
+  static bool VerifySignatureBlob(const std::vector<char>& signature_blob,
+                                  const std::string& public_key_path,
+                                  uint32_t client_version,
+                                  std::vector<char>* out_hash_data);
+
+  // Decrypts sig_data with the given public_key_path and populates
+  // out_hash_data with the decoded raw hash. Returns true if successful,
+  // false otherwise.
+  static bool GetRawHashFromSignature(const std::vector<char>& sig_data,
+                                      const std::string& public_key_path,
+                                      std::vector<char>* out_hash_data);
+
+  // Returns true if the payload in |payload_path| is signed and its hash can be
+  // verified using the public key in |public_key_path| with the signature
+  // of a given version in the signature blob. Returns false otherwise.
+  static bool VerifySignedPayload(const std::string& payload_path,
+                                  const std::string& public_key_path,
+                                  uint32_t client_key_check_version);
+
+  // Pads a SHA256 hash so that it may be encrypted/signed with RSA2048
+  // using the PKCS#1 v1.5 scheme.
+  // hash should be a pointer to vector of exactly 256 bits. The vector
+  // will be modified in place and will result in having a length of
+  // 2048 bits. Returns true on success, false otherwise.
+  static bool PadRSA2048SHA256Hash(std::vector<char>* hash);
+
+  // 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(PayloadVerifier);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_VERIFIER_H_
diff --git a/update_engine.gyp b/update_engine.gyp
index 24a9a98..c201b65 100644
--- a/update_engine.gyp
+++ b/update_engine.gyp
@@ -164,10 +164,11 @@
         'payload_generator/full_update_generator.cc',
         'payload_generator/graph_utils.cc',
         'payload_generator/metadata.cc',
+        'payload_generator/payload_signer.cc',
         'payload_generator/tarjan.cc',
         'payload_generator/topological_sort.cc',
-        'payload_signer.cc',
         'payload_state.cc',
+        'payload_verifier.cc',
         'postinstall_runner_action.cc',
         'prefs.cc',
         'proxy_resolver.cc',
@@ -293,9 +294,9 @@
             'payload_generator/full_update_generator_unittest.cc',
             'payload_generator/graph_utils_unittest.cc',
             'payload_generator/metadata_unittest.cc',
+            'payload_generator/payload_signer_unittest.cc',
             'payload_generator/tarjan_unittest.cc',
             'payload_generator/topological_sort_unittest.cc',
-            'payload_signer_unittest.cc',
             'payload_state_unittest.cc',
             'postinstall_runner_action_unittest.cc',
             'prefs_unittest.cc',