// Copyright (c) 2012 The Chromium 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 "crypto/signature_creator.h"

#include <memory>
#include <string>
#include <vector>

#include "base/sha1.h"
#include "crypto/rsa_private_key.h"
#include "crypto/sha2.h"
#include "crypto/signature_verifier.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"

TEST(SignatureCreatorTest, BasicTest) {
  // Do a verify round trip.
  std::unique_ptr<crypto::RSAPrivateKey> key_original(
      crypto::RSAPrivateKey::Create(1024));
  ASSERT_TRUE(key_original.get());

  std::vector<uint8_t> key_info;
  key_original->ExportPrivateKey(&key_info);
  std::unique_ptr<crypto::RSAPrivateKey> key(
      crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_info));
  ASSERT_TRUE(key.get());

  std::unique_ptr<crypto::SignatureCreator> signer(
      crypto::SignatureCreator::Create(key.get(),
                                       crypto::SignatureCreator::SHA1));
  ASSERT_TRUE(signer.get());

  std::string data("Hello, World!");
  ASSERT_TRUE(signer->Update(reinterpret_cast<const uint8_t*>(data.c_str()),
                             data.size()));

  std::vector<uint8_t> signature;
  ASSERT_TRUE(signer->Final(&signature));

  std::vector<uint8_t> public_key_info;
  ASSERT_TRUE(key_original->ExportPublicKey(&public_key_info));

  crypto::SignatureVerifier verifier;
  ASSERT_TRUE(verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1,
                                  signature, public_key_info));

  verifier.VerifyUpdate(base::as_bytes(base::make_span(data)));
  ASSERT_TRUE(verifier.VerifyFinal());
}

TEST(SignatureCreatorTest, SignDigestTest) {
  // Do a verify round trip.
  std::unique_ptr<crypto::RSAPrivateKey> key_original(
      crypto::RSAPrivateKey::Create(1024));
  ASSERT_TRUE(key_original.get());

  std::vector<uint8_t> key_info;
  key_original->ExportPrivateKey(&key_info);
  std::unique_ptr<crypto::RSAPrivateKey> key(
      crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_info));
  ASSERT_TRUE(key.get());

  std::string data("Hello, World!");
  std::string sha1 = base::SHA1HashString(data);
  // Sign sha1 of the input data.
  std::vector<uint8_t> signature;
  ASSERT_TRUE(crypto::SignatureCreator::Sign(
      key.get(), crypto::SignatureCreator::SHA1,
      reinterpret_cast<const uint8_t*>(sha1.c_str()), sha1.size(), &signature));

  std::vector<uint8_t> public_key_info;
  ASSERT_TRUE(key_original->ExportPublicKey(&public_key_info));

  // Verify the input data.
  crypto::SignatureVerifier verifier;
  ASSERT_TRUE(verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1,
                                  signature, public_key_info));

  verifier.VerifyUpdate(base::as_bytes(base::make_span(data)));
  ASSERT_TRUE(verifier.VerifyFinal());
}

TEST(SignatureCreatorTest, SignSHA256DigestTest) {
  // Do a verify round trip.
  std::unique_ptr<crypto::RSAPrivateKey> key_original(
      crypto::RSAPrivateKey::Create(1024));
  ASSERT_TRUE(key_original.get());

  std::vector<uint8_t> key_info;
  key_original->ExportPrivateKey(&key_info);
  std::unique_ptr<crypto::RSAPrivateKey> key(
      crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_info));
  ASSERT_TRUE(key.get());

  std::string data("Hello, World!");
  std::string sha256 = crypto::SHA256HashString(data);
  // Sign sha256 of the input data.
  std::vector<uint8_t> signature;
  ASSERT_TRUE(crypto::SignatureCreator::Sign(
      key.get(), crypto::SignatureCreator::HashAlgorithm::SHA256,
      reinterpret_cast<const uint8_t*>(sha256.c_str()), sha256.size(),
      &signature));

  std::vector<uint8_t> public_key_info;
  ASSERT_TRUE(key_original->ExportPublicKey(&public_key_info));

  // Verify the input data.
  crypto::SignatureVerifier verifier;
  ASSERT_TRUE(verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA256,
                                  signature, public_key_info));

  verifier.VerifyUpdate(base::as_bytes(base::make_span(data)));
  ASSERT_TRUE(verifier.VerifyFinal());
}
