// Copyright 2016 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 "net/ssl/ssl_platform_key.h"

#include <keyhi.h>
#include <pk11pub.h>
#include <stdint.h>
#include <string.h>

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

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/ref_counted.h"
#include "crypto/ec_private_key.h"
#include "crypto/scoped_nss_types.h"
#include "crypto/scoped_test_nss_db.h"
#include "net/ssl/ssl_private_key.h"
#include "net/ssl/ssl_private_key_test_util.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/ec.h"
#include "third_party/boringssl/src/include/openssl/ec_key.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
#include "third_party/boringssl/src/include/openssl/mem.h"

namespace net {

namespace {

struct TestKey {
  const char* cert_file;
  const char* key_file;
  SSLPrivateKey::Type key_type;
};

const TestKey kTestKeys[] = {
    {"client_1.pem", "client_1.pk8", SSLPrivateKey::Type::RSA},
    {"client_4.pem", "client_4.pk8", SSLPrivateKey::Type::ECDSA_P256},
    {"client_5.pem", "client_5.pk8", SSLPrivateKey::Type::ECDSA_P384},
    {"client_6.pem", "client_6.pk8", SSLPrivateKey::Type::ECDSA_P521},
};

std::string TestKeyToString(const testing::TestParamInfo<TestKey>& params) {
  return SSLPrivateKeyTypeToString(params.param.key_type);
}

}  // namespace

class SSLPlatformKeyNSSTest : public testing::TestWithParam<TestKey> {};

TEST_P(SSLPlatformKeyNSSTest, KeyMatches) {
  const TestKey& test_key = GetParam();

  std::string pkcs8;
  base::FilePath pkcs8_path =
      GetTestCertsDirectory().AppendASCII(test_key.key_file);
  ASSERT_TRUE(base::ReadFileToString(pkcs8_path, &pkcs8));

  // Import the key into a test NSS database.
  crypto::ScopedTestNSSDB test_db;
  scoped_refptr<X509Certificate> cert;
  if (SSLPrivateKey::IsECDSAType(test_key.key_type)) {
    // NSS cannot import unencrypted ECDSA keys, so we encrypt it with an empty
    // password and import manually.
    std::vector<uint8_t> pkcs8_vector(pkcs8.begin(), pkcs8.end());
    std::unique_ptr<crypto::ECPrivateKey> ec_private_key =
        crypto::ECPrivateKey::CreateFromPrivateKeyInfo(pkcs8_vector);
    ASSERT_TRUE(ec_private_key);
    std::vector<uint8_t> encrypted;
    ASSERT_TRUE(ec_private_key->ExportEncryptedPrivateKey(&encrypted));

    SECItem encrypted_item = {siBuffer, encrypted.data(),
                              static_cast<unsigned>(encrypted.size())};
    SECKEYEncryptedPrivateKeyInfo epki;
    memset(&epki, 0, sizeof(epki));
    crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
    ASSERT_EQ(SECSuccess,
              SEC_QuickDERDecodeItem(
                  arena.get(), &epki,
                  SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate),
                  &encrypted_item));

    // NSS uses the serialized public key in X9.62 form as the "public value"
    // for key ID purposes.
    bssl::ScopedCBB cbb;
    ASSERT_TRUE(CBB_init(cbb.get(), 0));
    EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(ec_private_key->key());
    ASSERT_TRUE(EC_POINT_point2cbb(cbb.get(), EC_KEY_get0_group(ec_key),
                                   EC_KEY_get0_public_key(ec_key),
                                   POINT_CONVERSION_UNCOMPRESSED, nullptr));
    uint8_t* public_value;
    size_t public_value_len;
    ASSERT_TRUE(CBB_finish(cbb.get(), &public_value, &public_value_len));
    bssl::UniquePtr<uint8_t> scoped_public_value(public_value);
    SECItem public_item = {siBuffer, public_value,
                           static_cast<unsigned>(public_value_len)};

    SECItem password_item = {siBuffer, nullptr, 0};
    ASSERT_EQ(SECSuccess,
              PK11_ImportEncryptedPrivateKeyInfo(
                  test_db.slot(), &epki, &password_item, nullptr /* nickname */,
                  &public_item, PR_TRUE /* permanent */, PR_TRUE /* private */,
                  ecKey, KU_DIGITAL_SIGNATURE, nullptr /* wincx */));

    cert = ImportCertFromFile(GetTestCertsDirectory(), test_key.cert_file);
    ASSERT_TRUE(cert);
    ASSERT_TRUE(ImportClientCertToSlot(cert, test_db.slot()));
  } else {
    cert = ImportClientCertAndKeyFromFile(GetTestCertsDirectory(),
                                          test_key.cert_file, test_key.key_file,
                                          test_db.slot());
    ASSERT_TRUE(cert);
  }

  // Look up the key.
  scoped_refptr<SSLPrivateKey> key = FetchClientCertPrivateKey(cert.get());
  ASSERT_TRUE(key);

  // All NSS keys are expected to have the same hash preferences.
  std::vector<SSLPrivateKey::Hash> expected_hashes = {
      SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384,
      SSLPrivateKey::Hash::SHA256, SSLPrivateKey::Hash::SHA1,
  };
  EXPECT_EQ(expected_hashes, key->GetDigestPreferences());

  TestSSLPrivateKeyMatches(key.get(), pkcs8);
}

INSTANTIATE_TEST_CASE_P(,
                        SSLPlatformKeyNSSTest,
                        testing::ValuesIn(kTestKeys),
                        TestKeyToString);

}  // namespace net
