// Copyright 2013 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/client_cert_store_nss.h"

#include <cert.h>
#include <certt.h>
#include <pk11pub.h>

#include <memory>
#include <string>

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "crypto/scoped_test_nss_db.h"
#include "net/cert/pem_tokenizer.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util_nss.h"
#include "net/ssl/client_cert_identity_test_util.h"
#include "net/ssl/client_cert_store_unittest-inl.h"
#include "net/ssl/ssl_cert_request_info.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 "testing/gtest/include/gtest/gtest.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"

namespace net {

namespace {

void SaveIdentitiesAndQuitCallback(ClientCertIdentityList* out_identities,
                                   base::Closure quit_closure,
                                   ClientCertIdentityList in_identities) {
  *out_identities = std::move(in_identities);
  quit_closure.Run();
}

void SavePrivateKeyAndQuitCallback(scoped_refptr<net::SSLPrivateKey>* out_key,
                                   base::Closure quit_closure,
                                   scoped_refptr<net::SSLPrivateKey> in_key) {
  *out_key = std::move(in_key);
  quit_closure.Run();
}

}  // namespace

class ClientCertStoreNSSTestDelegate {
 public:
  ClientCertStoreNSSTestDelegate() = default;

  bool SelectClientCerts(const CertificateList& input_certs,
                         const SSLCertRequestInfo& cert_request_info,
                         ClientCertIdentityList* selected_identities) {
    *selected_identities =
        FakeClientCertIdentityListFromCertificateList(input_certs);

    // Filters |selected_identities| using the logic being used to filter the
    // system store when GetClientCerts() is called.
    ClientCertStoreNSS::FilterCertsOnWorkerThread(selected_identities,
                                                  cert_request_info);
    return true;
  }
};

INSTANTIATE_TYPED_TEST_CASE_P(NSS,
                              ClientCertStoreTest,
                              ClientCertStoreNSSTestDelegate);

// Tests that ClientCertStoreNSS attempts to build a certificate chain by
// querying NSS before return a certificate.
TEST(ClientCertStoreNSSTest, BuildsCertificateChain) {
  base::test::ScopedTaskEnvironment scoped_task_environment;

  // Set up a test DB and import client_1.pem and client_1_ca.pem.
  crypto::ScopedTestNSSDB test_db;
  scoped_refptr<X509Certificate> client_1(ImportClientCertAndKeyFromFile(
      GetTestCertsDirectory(), "client_1.pem", "client_1.pk8", test_db.slot()));
  ASSERT_TRUE(client_1.get());
  scoped_refptr<X509Certificate> client_1_ca(
      ImportCertFromFile(GetTestCertsDirectory(), "client_1_ca.pem"));
  ASSERT_TRUE(client_1_ca.get());
  ASSERT_TRUE(ImportClientCertToSlot(client_1_ca, test_db.slot()));
  std::string pkcs8_key;
  ASSERT_TRUE(base::ReadFileToString(
      GetTestCertsDirectory().AppendASCII("client_1.pk8"), &pkcs8_key));

  std::unique_ptr<ClientCertStoreNSS> store(
      new ClientCertStoreNSS(ClientCertStoreNSS::PasswordDelegateFactory()));

  // These test keys are RSA keys.
  std::vector<uint16_t> expected = SSLPrivateKey::DefaultAlgorithmPreferences(
      EVP_PKEY_RSA, true /* supports PSS */);

  {
    // Request certificates matching B CA, |client_1|'s issuer.
    scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo);
    request->cert_authorities.push_back(std::string(
        reinterpret_cast<const char*>(kAuthority1DN), sizeof(kAuthority1DN)));

    ClientCertIdentityList selected_identities;
    base::RunLoop loop;
    store->GetClientCerts(*request.get(),
                          base::Bind(SaveIdentitiesAndQuitCallback,
                                     &selected_identities, loop.QuitClosure()));
    loop.Run();

    // The result be |client_1| with no intermediates.
    ASSERT_EQ(1u, selected_identities.size());
    scoped_refptr<X509Certificate> selected_cert =
        selected_identities[0]->certificate();
    EXPECT_TRUE(x509_util::CryptoBufferEqual(client_1->cert_buffer(),
                                             selected_cert->cert_buffer()));
    ASSERT_EQ(0u, selected_cert->intermediate_buffers().size());

    scoped_refptr<SSLPrivateKey> ssl_private_key;
    base::RunLoop key_loop;
    selected_identities[0]->AcquirePrivateKey(
        base::Bind(SavePrivateKeyAndQuitCallback, &ssl_private_key,
                   key_loop.QuitClosure()));
    key_loop.Run();

    ASSERT_TRUE(ssl_private_key);
    EXPECT_EQ(expected, ssl_private_key->GetAlgorithmPreferences());
    TestSSLPrivateKeyMatches(ssl_private_key.get(), pkcs8_key);
  }

  {
    // Request certificates matching C Root CA, |client_1_ca|'s issuer.
    scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo);
    request->cert_authorities.push_back(
        std::string(reinterpret_cast<const char*>(kAuthorityRootDN),
                    sizeof(kAuthorityRootDN)));

    ClientCertIdentityList selected_identities;
    base::RunLoop loop;
    store->GetClientCerts(*request.get(),
                          base::Bind(SaveIdentitiesAndQuitCallback,
                                     &selected_identities, loop.QuitClosure()));
    loop.Run();

    // The result be |client_1| with |client_1_ca| as an intermediate.
    ASSERT_EQ(1u, selected_identities.size());
    scoped_refptr<X509Certificate> selected_cert =
        selected_identities[0]->certificate();
    EXPECT_TRUE(x509_util::CryptoBufferEqual(client_1->cert_buffer(),
                                             selected_cert->cert_buffer()));
    ASSERT_EQ(1u, selected_cert->intermediate_buffers().size());
    EXPECT_TRUE(x509_util::CryptoBufferEqual(
        client_1_ca->cert_buffer(),
        selected_cert->intermediate_buffers()[0].get()));

    scoped_refptr<SSLPrivateKey> ssl_private_key;
    base::RunLoop key_loop;
    selected_identities[0]->AcquirePrivateKey(
        base::Bind(SavePrivateKeyAndQuitCallback, &ssl_private_key,
                   key_loop.QuitClosure()));
    key_loop.Run();
    ASSERT_TRUE(ssl_private_key);
    EXPECT_EQ(expected, ssl_private_key->GetAlgorithmPreferences());
    TestSSLPrivateKeyMatches(ssl_private_key.get(), pkcs8_key);
  }
}

TEST(ClientCertStoreNSSTest, SubjectPrintableStringContainingUTF8) {
  base::test::ScopedTaskEnvironment scoped_task_environment;

  crypto::ScopedTestNSSDB test_db;
  base::FilePath certs_dir =
      GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");

  ASSERT_TRUE(ImportSensitiveKeyFromFile(
      certs_dir, "v3_certificate_template.pk8", test_db.slot()));
  std::string pkcs8_key;
  ASSERT_TRUE(base::ReadFileToString(
      certs_dir.AppendASCII("v3_certificate_template.pk8"), &pkcs8_key));

  std::string file_data;
  ASSERT_TRUE(base::ReadFileToString(
      certs_dir.AppendASCII(
          "subject_printable_string_containing_utf8_client_cert.pem"),
      &file_data));

  net::PEMTokenizer pem_tokenizer(file_data, {"CERTIFICATE"});
  ASSERT_TRUE(pem_tokenizer.GetNext());
  std::string cert_der(pem_tokenizer.data());
  ASSERT_FALSE(pem_tokenizer.GetNext());

  ScopedCERTCertificate cert(x509_util::CreateCERTCertificateFromBytes(
      reinterpret_cast<const uint8_t*>(cert_der.data()), cert_der.size()));
  ASSERT_TRUE(cert);

  ASSERT_TRUE(ImportClientCertToSlot(cert.get(), test_db.slot()));

  std::unique_ptr<ClientCertStoreNSS> store(
      new ClientCertStoreNSS(ClientCertStoreNSS::PasswordDelegateFactory()));

  // These test keys are RSA keys.
  std::vector<uint16_t> expected = SSLPrivateKey::DefaultAlgorithmPreferences(
      EVP_PKEY_RSA, true /* supports PSS */);

  constexpr uint8_t kAuthorityDN[] = {
      0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
      0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
      0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
      0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
      0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
      0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64};
  scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo);
  request->cert_authorities.push_back(std::string(
      reinterpret_cast<const char*>(kAuthorityDN), sizeof(kAuthorityDN)));

  ClientCertIdentityList selected_identities;
  base::RunLoop loop;
  store->GetClientCerts(*request.get(),
                        base::Bind(SaveIdentitiesAndQuitCallback,
                                   &selected_identities, loop.QuitClosure()));
  loop.Run();

  // The result be |cert| with no intermediates.
  ASSERT_EQ(1u, selected_identities.size());
  scoped_refptr<X509Certificate> selected_cert =
      selected_identities[0]->certificate();
  EXPECT_TRUE(x509_util::IsSameCertificate(cert.get(), selected_cert.get()));
  EXPECT_EQ(0u, selected_cert->intermediate_buffers().size());

  scoped_refptr<SSLPrivateKey> ssl_private_key;
  base::RunLoop key_loop;
  selected_identities[0]->AcquirePrivateKey(base::Bind(
      SavePrivateKeyAndQuitCallback, &ssl_private_key, key_loop.QuitClosure()));
  key_loop.Run();

  ASSERT_TRUE(ssl_private_key);
  EXPECT_EQ(expected, ssl_private_key->GetAlgorithmPreferences());
  TestSSLPrivateKeyMatches(ssl_private_key.get(), pkcs8_key);
}

// TODO(mattm): is it possible to unittest slot unlocking?

}  // namespace net
