// 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 "remoting/host/token_validator_base.h"

#include <vector>

#include "base/atomic_sequence_num.h"
#include "base/memory/ptr_util.h"
#include "crypto/rsa_private_key.h"
#include "net/cert/x509_util.h"
#include "net/ssl/client_cert_identity_test_util.h"
#include "net/ssl/test_ssl_private_key.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

const char kTokenUrl[] = "https://example.com/token";
const char kTokenValidationUrl[] = "https://example.com/validate";
const char kTokenValidationCertIssuer[] = "*";

base::AtomicSequenceNumber g_serial_number;

std::unique_ptr<net::FakeClientCertIdentity> CreateFakeCert(
    base::Time valid_start,
    base::Time valid_expiry) {
  std::unique_ptr<crypto::RSAPrivateKey> rsa_private_key;
  std::string cert_der;
  net::x509_util::CreateKeyAndSelfSignedCert(
      "CN=subject", g_serial_number.GetNext(), valid_start, valid_expiry,
      &rsa_private_key, &cert_der);

  scoped_refptr<net::X509Certificate> cert =
      net::X509Certificate::CreateFromBytes(cert_der.data(), cert_der.size());
  if (!cert)
    return nullptr;

  scoped_refptr<net::SSLPrivateKey> ssl_private_key =
      net::WrapRSAPrivateKey(rsa_private_key.get());
  if (!ssl_private_key)
    return nullptr;

  return base::MakeUnique<net::FakeClientCertIdentity>(cert, ssl_private_key);
}

}  // namespace

namespace remoting {

class TestTokenValidator : TokenValidatorBase {
 public:
  explicit TestTokenValidator(const ThirdPartyAuthConfig& config);
  ~TestTokenValidator() override;

  void SelectCertificates(net::ClientCertIdentityList selected_certs);

  void ExpectContinueWithCertificate(
      const net::FakeClientCertIdentity* identity);

 protected:
  void ContinueWithCertificate(
      scoped_refptr<net::X509Certificate> client_cert,
      scoped_refptr<net::SSLPrivateKey> client_private_key) override;

 private:
  void StartValidateRequest(const std::string& token) override {}

  net::X509Certificate* expected_client_cert_ = nullptr;
  net::SSLPrivateKey* expected_private_key_ = nullptr;
};

TestTokenValidator::TestTokenValidator(const ThirdPartyAuthConfig& config) :
    TokenValidatorBase(config, "", nullptr) {
}

TestTokenValidator::~TestTokenValidator() {}

void TestTokenValidator::SelectCertificates(
    net::ClientCertIdentityList selected_certs) {
  OnCertificatesSelected(nullptr, std::move(selected_certs));
}

void TestTokenValidator::ExpectContinueWithCertificate(
    const net::FakeClientCertIdentity* identity) {
  if (identity) {
    expected_client_cert_ = identity->certificate();
    expected_private_key_ = identity->ssl_private_key();
  } else {
    expected_client_cert_ = nullptr;
    expected_private_key_ = nullptr;
  }
}

void TestTokenValidator::ContinueWithCertificate(
    scoped_refptr<net::X509Certificate> client_cert,
    scoped_refptr<net::SSLPrivateKey> client_private_key) {
  EXPECT_EQ(expected_client_cert_, client_cert.get());
  EXPECT_EQ(expected_private_key_, client_private_key.get());
}

class TokenValidatorBaseTest : public testing::Test {
 public:
  void SetUp() override;
 protected:
  std::unique_ptr<TestTokenValidator> token_validator_;
};

void TokenValidatorBaseTest::SetUp() {
  ThirdPartyAuthConfig config;
  config.token_url = GURL(kTokenUrl);
  config.token_validation_url = GURL(kTokenValidationUrl);
  config.token_validation_cert_issuer = kTokenValidationCertIssuer;
  token_validator_.reset(new TestTokenValidator(config));
}

TEST_F(TokenValidatorBaseTest, TestSelectCertificate) {
  base::Time now = base::Time::Now();

  std::unique_ptr<net::FakeClientCertIdentity> cert_expired_5_minutes_ago =
      CreateFakeCert(now - base::TimeDelta::FromMinutes(10),
                     now - base::TimeDelta::FromMinutes(5));
  ASSERT_TRUE(cert_expired_5_minutes_ago);

  std::unique_ptr<net::FakeClientCertIdentity> cert_start_5min_expire_5min =
      CreateFakeCert(now - base::TimeDelta::FromMinutes(5),
                     now + base::TimeDelta::FromMinutes(5));
  ASSERT_TRUE(cert_start_5min_expire_5min);

  std::unique_ptr<net::FakeClientCertIdentity> cert_start_10min_expire_5min =
      CreateFakeCert(now - base::TimeDelta::FromMinutes(10),
                     now + base::TimeDelta::FromMinutes(5));
  ASSERT_TRUE(cert_start_10min_expire_5min);

  std::unique_ptr<net::FakeClientCertIdentity> cert_start_5min_expire_10min =
      CreateFakeCert(now - base::TimeDelta::FromMinutes(5),
                     now + base::TimeDelta::FromMinutes(10));
  ASSERT_TRUE(cert_start_5min_expire_10min);

  // No certificate.
  token_validator_->ExpectContinueWithCertificate(nullptr);
  token_validator_->SelectCertificates(net::ClientCertIdentityList());
  {
    // One invalid certificate.
    net::ClientCertIdentityList client_certs;
    client_certs.push_back(cert_expired_5_minutes_ago->Copy());
    token_validator_->ExpectContinueWithCertificate(nullptr);
    token_validator_->SelectCertificates(std::move(client_certs));
  }
  {
    // One valid certificate.
    net::ClientCertIdentityList client_certs;
    client_certs.push_back(cert_start_5min_expire_5min->Copy());
    token_validator_->ExpectContinueWithCertificate(
        cert_start_5min_expire_5min.get());
    token_validator_->SelectCertificates(std::move(client_certs));
  }
  {
    // One valid one invalid.
    net::ClientCertIdentityList client_certs;
    client_certs.push_back(cert_expired_5_minutes_ago->Copy());
    client_certs.push_back(cert_start_5min_expire_5min->Copy());
    token_validator_->ExpectContinueWithCertificate(
        cert_start_5min_expire_5min.get());
    token_validator_->SelectCertificates(std::move(client_certs));
  }
  {
    // Two valid certs. Choose latest created.
    net::ClientCertIdentityList client_certs;
    client_certs.push_back(cert_start_10min_expire_5min->Copy());
    client_certs.push_back(cert_start_5min_expire_5min->Copy());
    token_validator_->ExpectContinueWithCertificate(
        cert_start_5min_expire_5min.get());
    token_validator_->SelectCertificates(std::move(client_certs));
  }
  {
    // Two valid certs. Choose latest expires.
    net::ClientCertIdentityList client_certs;
    client_certs.push_back(cert_start_5min_expire_5min->Copy());
    client_certs.push_back(cert_start_5min_expire_10min->Copy());
    token_validator_->ExpectContinueWithCertificate(
        cert_start_5min_expire_10min.get());
    token_validator_->SelectCertificates(std::move(client_certs));
  }
  {
    // Pick the best given all certificates.
    net::ClientCertIdentityList client_certs;
    client_certs.push_back(cert_expired_5_minutes_ago->Copy());
    client_certs.push_back(cert_start_5min_expire_5min->Copy());
    client_certs.push_back(cert_start_5min_expire_10min->Copy());
    client_certs.push_back(cert_start_10min_expire_5min->Copy());
    token_validator_->ExpectContinueWithCertificate(
        cert_start_5min_expire_10min.get());
    token_validator_->SelectCertificates(std::move(client_certs));
  }
}

}  // namespace remoting
