// Copyright (c) 2010 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 <string>
#include <vector>
#include <gtest/gtest.h>
#include "base/logging.h"
#include "update_engine/payload_signer.h"
#include "update_engine/update_metadata.pb.h"
#include "update_engine/utils.h"

using std::string;
using std::vector;

// Note: the test key was generated with the following command:
// openssl genrsa -out unittest_key.pem 2048
// The public-key version is created by the build system.

namespace chromeos_update_engine {

const char* kUnittestPrivateKeyPath = "unittest_key.pem";
const char* kUnittestPublicKeyPath = "unittest_key.pub.pem";
const char* kUnittestPrivateKey2Path = "unittest_key2.pem";
const char* kUnittestPublicKey2Path = "unittest_key2.pub.pem";

// Some data and its corresponding hash and signature:
const char kDataToSign[] = "This is some data to sign.";

// Generated by:
// echo -n 'This is some data to sign.' | openssl dgst -sha256 -binary |
//   hexdump -v -e '" " 8/1 "0x%02x, " "\n"'
const unsigned char kDataHash[] = {
  0x7a, 0x07, 0xa6, 0x44, 0x08, 0x86, 0x20, 0xa6,
  0xc1, 0xf8, 0xd9, 0x02, 0x05, 0x63, 0x0d, 0xb7,
  0xfc, 0x2b, 0xa0, 0xa9, 0x7c, 0x9d, 0x1d, 0x8c,
  0x01, 0xf5, 0x78, 0x6d, 0xc5, 0x11, 0xb4, 0x06
};

// Generated with openssl 1.0, which at the time of this writing, you need
// to download and install yourself. Here's my command:
// echo -n 'This is some data to sign.' | openssl dgst -sha256 -binary |
//    ~/local/bin/openssl pkeyutl -sign -inkey unittest_key.pem -pkeyopt
//    digest:sha256 | hexdump -v -e '" " 8/1 "0x%02x, " "\n"'
const unsigned char kDataSignature[] = {
  0x9f, 0x86, 0x25, 0x8b, 0xf3, 0xcc, 0xe3, 0x95,
  0x5f, 0x45, 0x83, 0xb2, 0x66, 0xf0, 0x2a, 0xcf,
  0xb7, 0xaa, 0x52, 0x25, 0x7a, 0xdd, 0x9d, 0x65,
  0xe5, 0xd6, 0x02, 0x4b, 0x37, 0x99, 0x53, 0x06,
  0xc2, 0xc9, 0x37, 0x36, 0x25, 0x62, 0x09, 0x4f,
  0x6b, 0x22, 0xf8, 0xb3, 0x89, 0x14, 0x98, 0x1a,
  0xbc, 0x30, 0x90, 0x4a, 0x43, 0xf5, 0xea, 0x2e,
  0xf0, 0xa4, 0xba, 0xc3, 0xa7, 0xa3, 0x44, 0x70,
  0xd6, 0xc4, 0x89, 0xd8, 0x45, 0x71, 0xbb, 0xee,
  0x59, 0x87, 0x3d, 0xd5, 0xe5, 0x40, 0x22, 0x3d,
  0x73, 0x7e, 0x2a, 0x58, 0x93, 0x8e, 0xcb, 0x9c,
  0xf2, 0xbb, 0x4a, 0xc9, 0xd2, 0x2c, 0x52, 0x42,
  0xb0, 0xd1, 0x13, 0x22, 0xa4, 0x78, 0xc7, 0xc6,
  0x3e, 0xf1, 0xdc, 0x4c, 0x7b, 0x2d, 0x40, 0xda,
  0x58, 0xac, 0x4a, 0x11, 0x96, 0x3d, 0xa0, 0x01,
  0xf6, 0x96, 0x74, 0xf6, 0x6c, 0x0c, 0x49, 0x69,
  0x4e, 0xc1, 0x7e, 0x9f, 0x2a, 0x42, 0xdd, 0x15,
  0x6b, 0x37, 0x2e, 0x3a, 0xa7, 0xa7, 0x6d, 0x91,
  0x13, 0xe8, 0x59, 0xde, 0xfe, 0x99, 0x07, 0xd9,
  0x34, 0x0f, 0x17, 0xb3, 0x05, 0x4c, 0xd2, 0xc6,
  0x82, 0xb7, 0x38, 0x36, 0x63, 0x1d, 0x9e, 0x21,
  0xa6, 0x32, 0xef, 0xf1, 0x65, 0xe6, 0xed, 0x95,
  0x25, 0x9b, 0x61, 0xe0, 0xba, 0x86, 0xa1, 0x7f,
  0xf8, 0xa5, 0x4a, 0x32, 0x1f, 0x15, 0x20, 0x8a,
  0x41, 0xc5, 0xb0, 0xd9, 0x4a, 0xda, 0x85, 0xf3,
  0xdc, 0xa0, 0x98, 0x5d, 0x1d, 0x18, 0x9d, 0x2e,
  0x42, 0xea, 0x69, 0x13, 0x74, 0x3c, 0x74, 0xf7,
  0x6d, 0x43, 0xb0, 0x63, 0x90, 0xdb, 0x04, 0xd5,
  0x05, 0xc9, 0x73, 0x1f, 0x6c, 0xd6, 0xfa, 0x46,
  0x4e, 0x0f, 0x33, 0x58, 0x5b, 0x0d, 0x1b, 0x55,
  0x39, 0xb9, 0x0f, 0x43, 0x37, 0xc0, 0x06, 0x0c,
  0x29, 0x93, 0x43, 0xc7, 0x43, 0xb9, 0xab, 0x7d
};

namespace {
void SignSampleData(vector<char>* out_signature_blob) {
  string data_path;
  ASSERT_TRUE(
      utils::MakeTempFile("data.XXXXXX", &data_path, NULL));
  ScopedPathUnlinker data_path_unlinker(data_path);
  ASSERT_TRUE(utils::WriteFile(data_path.c_str(),
                               kDataToSign,
                               strlen(kDataToSign)));
  uint64_t length = 0;
  EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
      vector<string> (1, kUnittestPrivateKeyPath),
      &length));
  EXPECT_GT(length, 0);
  EXPECT_TRUE(PayloadSigner::SignPayload(
      data_path,
      vector<string>(1, kUnittestPrivateKeyPath),
      out_signature_blob));
  EXPECT_EQ(length, out_signature_blob->size());
}
}  // namespace

TEST(PayloadSignerTest, SimpleTest) {
  vector<char> signature_blob;
  SignSampleData(&signature_blob);

  // Check the signature itself
  Signatures signatures;
  EXPECT_TRUE(signatures.ParseFromArray(&signature_blob[0],
                                        signature_blob.size()));
  EXPECT_EQ(1, signatures.signatures_size());
  const Signatures_Signature& signature = signatures.signatures(0);
  EXPECT_EQ(kSignatureMessageOriginalVersion, signature.version());
  const string sig_data = signature.data();
  ASSERT_EQ(arraysize(kDataSignature), sig_data.size());
  for (size_t i = 0; i < arraysize(kDataSignature); i++) {
    EXPECT_EQ(static_cast<char>(kDataSignature[i]), sig_data[i]);
  }
}

TEST(PayloadSignerTest, VerifySignatureTest) {
  vector<char> signature_blob;
  SignSampleData(&signature_blob);

  vector<char> hash_data;
  EXPECT_TRUE(PayloadSigner::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);
  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]);
  }
}

}  // namespace chromeos_update_engine
