// 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 "net/http/transport_security_persister.h"

#include <map>
#include <string>
#include <vector>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "net/http/transport_security_state.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

class TransportSecurityPersisterTest : public testing::Test {
 public:
  TransportSecurityPersisterTest() {
  }

  ~TransportSecurityPersisterTest() override {
    base::MessageLoopForIO::current()->RunUntilIdle();
  }

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    persister_.reset(new TransportSecurityPersister(
        &state_, temp_dir_.path(),
        base::MessageLoopForIO::current()->task_runner(), false));
  }

 protected:
  base::ScopedTempDir temp_dir_;
  TransportSecurityState state_;
  scoped_ptr<TransportSecurityPersister> persister_;
};

TEST_F(TransportSecurityPersisterTest, SerializeData1) {
  std::string output;
  bool dirty;

  EXPECT_TRUE(persister_->SerializeData(&output));
  EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
  EXPECT_FALSE(dirty);
}

TEST_F(TransportSecurityPersisterTest, SerializeData2) {
  TransportSecurityState::DomainState domain_state;
  const base::Time current_time(base::Time::Now());
  const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
  static const char kYahooDomain[] = "yahoo.com";

  EXPECT_FALSE(state_.GetStaticDomainState(kYahooDomain, &domain_state));
  EXPECT_FALSE(state_.GetDynamicDomainState(kYahooDomain, &domain_state));

  bool include_subdomains = true;
  state_.AddHSTS(kYahooDomain, expiry, include_subdomains);

  std::string output;
  bool dirty;
  EXPECT_TRUE(persister_->SerializeData(&output));
  EXPECT_TRUE(persister_->LoadEntries(output, &dirty));

  EXPECT_TRUE(state_.GetDynamicDomainState(kYahooDomain, &domain_state));
  EXPECT_EQ(domain_state.sts.upgrade_mode,
            TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
  EXPECT_TRUE(state_.GetDynamicDomainState("foo.yahoo.com", &domain_state));
  EXPECT_EQ(domain_state.sts.upgrade_mode,
            TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
  EXPECT_TRUE(state_.GetDynamicDomainState("foo.bar.yahoo.com", &domain_state));
  EXPECT_EQ(domain_state.sts.upgrade_mode,
            TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
  EXPECT_TRUE(
      state_.GetDynamicDomainState("foo.bar.baz.yahoo.com", &domain_state));
  EXPECT_EQ(domain_state.sts.upgrade_mode,
            TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
  EXPECT_FALSE(state_.GetStaticDomainState("com", &domain_state));
}

TEST_F(TransportSecurityPersisterTest, SerializeData3) {
  // Add an entry.
  HashValue fp1(HASH_VALUE_SHA1);
  memset(fp1.data(), 0, fp1.size());
  HashValue fp2(HASH_VALUE_SHA1);
  memset(fp2.data(), 1, fp2.size());
  base::Time expiry =
      base::Time::Now() + base::TimeDelta::FromSeconds(1000);
  HashValueVector dynamic_spki_hashes;
  dynamic_spki_hashes.push_back(fp1);
  dynamic_spki_hashes.push_back(fp2);
  bool include_subdomains = false;
  state_.AddHSTS("www.example.com", expiry, include_subdomains);
  state_.AddHPKP("www.example.com", expiry, include_subdomains,
                 dynamic_spki_hashes);

  // Add another entry.
  memset(fp1.data(), 2, fp1.size());
  memset(fp2.data(), 3, fp2.size());
  expiry =
      base::Time::Now() + base::TimeDelta::FromSeconds(3000);
  dynamic_spki_hashes.push_back(fp1);
  dynamic_spki_hashes.push_back(fp2);
  state_.AddHSTS("www.example.net", expiry, include_subdomains);
  state_.AddHPKP("www.example.net", expiry, include_subdomains,
                 dynamic_spki_hashes);

  // Save a copy of everything.
  std::map<std::string, TransportSecurityState::DomainState> saved;
  TransportSecurityState::Iterator i(state_);
  while (i.HasNext()) {
    saved[i.hostname()] = i.domain_state();
    i.Advance();
  }

  std::string serialized;
  EXPECT_TRUE(persister_->SerializeData(&serialized));

  // Persist the data to the file. For the test to be fast and not flaky, we
  // just do it directly rather than call persister_->StateIsDirty. (That uses
  // ImportantFileWriter, which has an asynchronous commit interval rather
  // than block.) Use a different basename just for cleanliness.
  base::FilePath path =
      temp_dir_.path().AppendASCII("TransportSecurityPersisterTest");
  EXPECT_TRUE(base::WriteFile(path, serialized.c_str(), serialized.size()));

  // Read the data back.
  std::string persisted;
  EXPECT_TRUE(base::ReadFileToString(path, &persisted));
  EXPECT_EQ(persisted, serialized);
  bool dirty;
  EXPECT_TRUE(persister_->LoadEntries(persisted, &dirty));
  EXPECT_FALSE(dirty);

  // Check that states are the same as saved.
  size_t count = 0;
  TransportSecurityState::Iterator j(state_);
  while (j.HasNext()) {
    count++;
    j.Advance();
  }
  EXPECT_EQ(count, saved.size());
}

TEST_F(TransportSecurityPersisterTest, SerializeDataOld) {
  // This is an old-style piece of transport state JSON, which has no creation
  // date.
  std::string output =
      "{ "
      "\"NiyD+3J1r6z1wjl2n1ALBu94Zj9OsEAMo0kCN8js0Uk=\": {"
      "\"expiry\": 1266815027.983453, "
      "\"include_subdomains\": false, "
      "\"mode\": \"strict\" "
      "}"
      "}";
  bool dirty;
  EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
  EXPECT_TRUE(dirty);
}

TEST_F(TransportSecurityPersisterTest, PublicKeyHashes) {
  TransportSecurityState::DomainState domain_state;
  static const char kTestDomain[] = "example.com";
  EXPECT_FALSE(state_.GetDynamicDomainState(kTestDomain, &domain_state));
  HashValueVector hashes;
  std::string failure_log;
  EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));

  HashValue sha1(HASH_VALUE_SHA1);
  memset(sha1.data(), '1', sha1.size());
  domain_state.pkp.spki_hashes.push_back(sha1);

  EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));

  hashes.push_back(sha1);
  EXPECT_TRUE(domain_state.CheckPublicKeyPins(hashes, &failure_log));

  hashes[0].data()[0] = '2';
  EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));

  const base::Time current_time(base::Time::Now());
  const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
  bool include_subdomains = false;
  state_.AddHSTS(kTestDomain, expiry, include_subdomains);
  state_.AddHPKP(
      kTestDomain, expiry, include_subdomains, domain_state.pkp.spki_hashes);
  std::string serialized;
  EXPECT_TRUE(persister_->SerializeData(&serialized));
  bool dirty;
  EXPECT_TRUE(persister_->LoadEntries(serialized, &dirty));

  TransportSecurityState::DomainState new_domain_state;
  EXPECT_TRUE(state_.GetDynamicDomainState(kTestDomain, &new_domain_state));
  EXPECT_EQ(1u, new_domain_state.pkp.spki_hashes.size());
  EXPECT_EQ(sha1.tag, new_domain_state.pkp.spki_hashes[0].tag);
  EXPECT_EQ(0,
            memcmp(new_domain_state.pkp.spki_hashes[0].data(),
                   sha1.data(),
                   sha1.size()));
}

}  // namespace

}  // namespace net
