AU: Switch to 2048 bit RSA keys; Pad SHA256 hashes appropriately.

Manually pad hashes according to how SHA256 hashes should be padded
for use in RSA 2048 bit encryption.

Also, remove the public key from the repository, as it's generated by
scons.

In an upcoming CL, I will test via an actual update.

BUG=chromium-os:13341
TEST=unittests

Review URL: http://codereview.chromium.org/6771024

Change-Id: I8aa93ed54e4d32b46f4d817a5ae5c36d9f0885f6
diff --git a/payload_signer.cc b/payload_signer.cc
index 60a80d1..ef9791d 100644
--- a/payload_signer.cc
+++ b/payload_signer.cc
@@ -23,6 +23,28 @@
 const uint32_t kSignatureMessageVersion = 1;
 
 namespace {
+
+const char kRSA2048SHA256Padding[] = {
+  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, 0x30, 0x31, 0x30,
+  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+  0x00, 0x04, 0x20
+};
+
 // Given a raw |signature|, packs it into a protobuf and serializes it into a
 // binary blob. Returns true on success, false otherwise.
 bool ConvertSignatureToProtobufBlob(const vector<char> signature,
@@ -113,14 +135,18 @@
   TEST_AND_RETURN_FALSE(
       utils::MakeTempFile("/tmp/hash.XXXXXX", &hash_path, NULL));
   ScopedPathUnlinker hash_path_unlinker(hash_path);
+  // We expect unpadded SHA256 hash coming in
+  TEST_AND_RETURN_FALSE(hash.size() == 32);
+  vector<char> padded_hash(hash);
+  PadRSA2048SHA256Hash(&padded_hash);
   TEST_AND_RETURN_FALSE(utils::WriteFile(hash_path.c_str(),
-                                         hash.data(),
-                                         hash.size()));
+                                         padded_hash.data(),
+                                         padded_hash.size()));
 
   // This runs on the server, so it's okay to cop out and call openssl
   // executable rather than properly use the library
   vector<string> cmd;
-  SplitString("/usr/bin/openssl rsautl -pkcs -sign -inkey x -in x -out x",
+  SplitString("/usr/bin/openssl rsautl -raw -sign -inkey x -in x -out x",
               ' ',
               &cmd);
   cmd[cmd.size() - 5] = private_key_path;
@@ -220,7 +246,7 @@
       reinterpret_cast<const unsigned char*>(sig_data.data()),
       reinterpret_cast<unsigned char*>(hash_data.data()),
       rsa,
-      RSA_PKCS1_PADDING);
+      RSA_NO_PADDING);
   RSA_free(rsa);
   TEST_AND_RETURN_FALSE(decrypt_size > 0 &&
                         decrypt_size <= static_cast<int>(hash_data.size()));
@@ -251,6 +277,7 @@
   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;
 }
@@ -299,4 +326,13 @@
   return true;
 }
 
+bool PayloadSigner::PadRSA2048SHA256Hash(std::vector<char>* hash) {
+  TEST_AND_RETURN_FALSE(hash->size() == 32);
+  hash->insert(hash->begin(),
+               kRSA2048SHA256Padding,
+               kRSA2048SHA256Padding + sizeof(kRSA2048SHA256Padding));
+  TEST_AND_RETURN_FALSE(hash->size() == 256);
+  return true;
+}
+
 }  // namespace chromeos_update_engine