// Copyright (c) 2009 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_client_auth_cache.h"

#include "base/callback.h"
#include "base/macros.h"
#include "base/time/time.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_private_key.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

class MockSSLPrivateKey : public SSLPrivateKey {
 public:
  MockSSLPrivateKey() = default;

  std::vector<uint16_t> GetAlgorithmPreferences() override {
    NOTIMPLEMENTED();
    return {};
  }

  void Sign(uint16_t algorithm,
            base::span<const uint8_t> input,
            SignCallback callback) override {
    NOTIMPLEMENTED();
  }

 private:
  ~MockSSLPrivateKey() override = default;

  DISALLOW_COPY_AND_ASSIGN(MockSSLPrivateKey);
};

TEST(SSLClientAuthCacheTest, LookupAddRemove) {
  SSLClientAuthCache cache;

  HostPortPair server1("foo1", 443);
  scoped_refptr<X509Certificate> cert1(
      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
  ASSERT_TRUE(cert1);

  HostPortPair server2("foo2", 443);
  scoped_refptr<X509Certificate> cert2(
      ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem"));
  ASSERT_TRUE(cert2);

  HostPortPair server3("foo3", 443);
  scoped_refptr<X509Certificate> cert3(
      ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem"));
  ASSERT_TRUE(cert3);

  scoped_refptr<X509Certificate> cached_cert;
  scoped_refptr<SSLPrivateKey> cached_pkey;
  // Lookup non-existent client certificate.
  cached_cert = nullptr;
  EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));

  // Add client certificate for server1.
  cache.Add(server1, cert1.get(), new MockSSLPrivateKey);
  cached_cert = nullptr;
  EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
  EXPECT_EQ(cert1, cached_cert);

  // Add client certificate for server2.
  cache.Add(server2, cert2.get(), new MockSSLPrivateKey);
  cached_cert = nullptr;
  EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
  EXPECT_EQ(cert1.get(), cached_cert.get());
  cached_cert = nullptr;
  EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
  EXPECT_EQ(cert2, cached_cert);

  // Overwrite the client certificate for server1.
  cache.Add(server1, cert3.get(), new MockSSLPrivateKey);
  cached_cert = nullptr;
  EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
  EXPECT_EQ(cert3, cached_cert);
  cached_cert = nullptr;
  EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
  EXPECT_EQ(cert2, cached_cert);

  // Remove client certificate of server1.
  cache.Remove(server1);
  cached_cert = nullptr;
  EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
  cached_cert = nullptr;
  EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
  EXPECT_EQ(cert2, cached_cert);

  // Remove non-existent client certificate.
  cache.Remove(server1);
  cached_cert = nullptr;
  EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
  cached_cert = nullptr;
  EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
  EXPECT_EQ(cert2, cached_cert);
}

// Check that if the server differs only by port number, it is considered
// a separate server.
TEST(SSLClientAuthCacheTest, LookupWithPort) {
  SSLClientAuthCache cache;

  HostPortPair server1("foo", 443);
  scoped_refptr<X509Certificate> cert1(
      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
  ASSERT_TRUE(cert1);

  HostPortPair server2("foo", 8443);
  scoped_refptr<X509Certificate> cert2(
      ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem"));
  ASSERT_TRUE(cert2);

  cache.Add(server1, cert1.get(), new MockSSLPrivateKey);
  cache.Add(server2, cert2.get(), new MockSSLPrivateKey);

  scoped_refptr<X509Certificate> cached_cert;
  scoped_refptr<SSLPrivateKey> cached_pkey;
  EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
  EXPECT_EQ(cert1.get(), cached_cert.get());
  EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
  EXPECT_EQ(cert2.get(), cached_cert.get());
}

// Check that the a nullptr certificate, indicating the user has declined to
// send a certificate, is properly cached.
TEST(SSLClientAuthCacheTest, LookupNullPreference) {
  SSLClientAuthCache cache;

  HostPortPair server1("foo", 443);
  scoped_refptr<X509Certificate> cert1(
      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
  ASSERT_TRUE(cert1);

  cache.Add(server1, nullptr, new MockSSLPrivateKey);

  scoped_refptr<X509Certificate> cached_cert(cert1);
  scoped_refptr<SSLPrivateKey> cached_pkey;
  // Make sure that |cached_cert| is updated to nullptr, indicating the user
  // declined to send a certificate to |server1|.
  EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
  EXPECT_EQ(nullptr, cached_cert.get());

  // Remove the existing cached certificate.
  cache.Remove(server1);
  cached_cert = nullptr;
  EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));

  // Add a new preference for a specific certificate.
  cache.Add(server1, cert1.get(), new MockSSLPrivateKey);
  cached_cert = nullptr;
  EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
  EXPECT_EQ(cert1, cached_cert);

  // Replace the specific preference with a nullptr certificate.
  cache.Add(server1, nullptr, new MockSSLPrivateKey);
  cached_cert = nullptr;
  EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
  EXPECT_EQ(nullptr, cached_cert.get());
}

// Check that the OnCertDBChanged() method removes all cache entries.
TEST(SSLClientAuthCacheTest, OnCertDBChanged) {
  SSLClientAuthCache cache;

  HostPortPair server1("foo", 443);
  scoped_refptr<X509Certificate> cert1(
      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
  ASSERT_TRUE(cert1);

  cache.Add(server1, cert1.get(), new MockSSLPrivateKey);

  HostPortPair server2("foo2", 443);
  cache.Add(server2, nullptr, new MockSSLPrivateKey);

  scoped_refptr<X509Certificate> cached_cert;
  scoped_refptr<SSLPrivateKey> cached_pkey;

  // Demonstrate the set up is correct.
  EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
  EXPECT_EQ(cert1, cached_cert);

  EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
  EXPECT_EQ(nullptr, cached_cert.get());

  cache.OnCertDBChanged();

  // Check that we no longer have entries for either server.
  EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
  EXPECT_FALSE(cache.Lookup(server2, &cached_cert, &cached_pkey));
}

}  // namespace net
