// 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("/tmp/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
