// 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
};

//class PayloadSignerTest : public ::testing::Test {};

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());
}
}

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
