// 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_state.h"

#if defined(USE_OPENSSL)
#include <openssl/ecdsa.h>
#include <openssl/ssl.h>
#else  // !defined(USE_OPENSSL)
#include <cryptohi.h>
#include <hasht.h>
#include <keyhi.h>
#include <nspr.h>
#include <pk11pub.h>
#endif

#include <algorithm>

#include "base/base64.h"
#include "base/build_time.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "crypto/sha2.h"
#include "net/base/dns_util.h"
#include "net/cert/x509_cert_types.h"
#include "net/cert/x509_certificate.h"
#include "net/http/http_security_headers.h"
#include "net/ssl/ssl_info.h"
#include "url/gurl.h"

#if defined(USE_OPENSSL)
#include "crypto/openssl_util.h"
#endif

namespace net {

namespace {

std::string HashesToBase64String(const HashValueVector& hashes) {
  std::string str;
  for (size_t i = 0; i != hashes.size(); ++i) {
    if (i != 0)
      str += ",";
    str += hashes[i].ToString();
  }
  return str;
}

std::string HashHost(const std::string& canonicalized_host) {
  char hashed[crypto::kSHA256Length];
  crypto::SHA256HashString(canonicalized_host, hashed, sizeof(hashed));
  return std::string(hashed, sizeof(hashed));
}

// Returns true if the intersection of |a| and |b| is not empty. If either
// |a| or |b| is empty, returns false.
bool HashesIntersect(const HashValueVector& a,
                     const HashValueVector& b) {
  for (HashValueVector::const_iterator i = a.begin(); i != a.end(); ++i) {
    HashValueVector::const_iterator j =
        std::find_if(b.begin(), b.end(), HashValuesEqual(*i));
    if (j != b.end())
      return true;
  }
  return false;
}

bool AddHash(const char* sha1_hash,
             HashValueVector* out) {
  HashValue hash(HASH_VALUE_SHA1);
  memcpy(hash.data(), sha1_hash, hash.size());
  out->push_back(hash);
  return true;
}

}  // namespace

TransportSecurityState::TransportSecurityState()
    : delegate_(NULL), enable_static_pins_(true) {
// Static pinning is only enabled for official builds to make sure that
// others don't end up with pins that cannot be easily updated.
#if !defined(OFFICIAL_BUILD) || defined(OS_ANDROID) || defined(OS_IOS)
  enable_static_pins_ = false;
#endif
  DCHECK(CalledOnValidThread());
}

TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state)
    : iterator_(state.enabled_hosts_.begin()),
      end_(state.enabled_hosts_.end()) {
}

TransportSecurityState::Iterator::~Iterator() {}

bool TransportSecurityState::ShouldSSLErrorsBeFatal(const std::string& host) {
  DomainState state;
  if (GetStaticDomainState(host, &state))
    return true;
  return GetDynamicDomainState(host, &state);
}

bool TransportSecurityState::ShouldUpgradeToSSL(const std::string& host) {
  DomainState dynamic_state;
  if (GetDynamicDomainState(host, &dynamic_state))
    return dynamic_state.ShouldUpgradeToSSL();

  DomainState static_state;
  if (GetStaticDomainState(host, &static_state) &&
      static_state.ShouldUpgradeToSSL()) {
      return true;
  }

  return false;
}

bool TransportSecurityState::CheckPublicKeyPins(
    const std::string& host,
    bool is_issued_by_known_root,
    const HashValueVector& public_key_hashes,
    std::string* pinning_failure_log) {
  // Perform pin validation if, and only if, all these conditions obtain:
  //
  // * the server's certificate chain chains up to a known root (i.e. not a
  //   user-installed trust anchor); and
  // * the server actually has public key pins.
  if (!is_issued_by_known_root || !HasPublicKeyPins(host)) {
    return true;
  }

  bool pins_are_valid = CheckPublicKeyPinsImpl(
      host, public_key_hashes, pinning_failure_log);
  if (!pins_are_valid) {
    LOG(ERROR) << *pinning_failure_log;
    ReportUMAOnPinFailure(host);
  }

  UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid);
  return pins_are_valid;
}

bool TransportSecurityState::HasPublicKeyPins(const std::string& host) {
  DomainState dynamic_state;
  if (GetDynamicDomainState(host, &dynamic_state))
    return dynamic_state.HasPublicKeyPins();

  DomainState static_state;
  if (GetStaticDomainState(host, &static_state)) {
    if (static_state.HasPublicKeyPins())
      return true;
  }

  return false;
}

void TransportSecurityState::SetDelegate(
    TransportSecurityState::Delegate* delegate) {
  DCHECK(CalledOnValidThread());
  delegate_ = delegate;
}

void TransportSecurityState::EnableHost(const std::string& host,
                                        const DomainState& state) {
  DCHECK(CalledOnValidThread());

  const std::string canonicalized_host = CanonicalizeHost(host);
  if (canonicalized_host.empty())
    return;

  DomainState state_copy(state);
  // No need to store this value since it is redundant. (|canonicalized_host|
  // is the map key.)
  state_copy.domain.clear();

  enabled_hosts_[HashHost(canonicalized_host)] = state_copy;
  DirtyNotify();
}

bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
  DCHECK(CalledOnValidThread());

  const std::string canonicalized_host = CanonicalizeHost(host);
  if (canonicalized_host.empty())
    return false;

  DomainStateMap::iterator i = enabled_hosts_.find(
      HashHost(canonicalized_host));
  if (i != enabled_hosts_.end()) {
    enabled_hosts_.erase(i);
    DirtyNotify();
    return true;
  }
  return false;
}

void TransportSecurityState::ClearDynamicData() {
  DCHECK(CalledOnValidThread());
  enabled_hosts_.clear();
}

void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) {
  DCHECK(CalledOnValidThread());

  bool dirtied = false;
  DomainStateMap::iterator i = enabled_hosts_.begin();
  while (i != enabled_hosts_.end()) {
    if (i->second.sts.last_observed >= time &&
        i->second.pkp.last_observed >= time) {
      dirtied = true;
      enabled_hosts_.erase(i++);
      continue;
    }

    if (i->second.sts.last_observed >= time) {
      dirtied = true;
      i->second.sts.upgrade_mode = DomainState::MODE_DEFAULT;
    } else if (i->second.pkp.last_observed >= time) {
      dirtied = true;
      i->second.pkp.spki_hashes.clear();
      i->second.pkp.expiry = base::Time();
    }
    ++i;
  }

  if (dirtied)
    DirtyNotify();
}

TransportSecurityState::~TransportSecurityState() {
  DCHECK(CalledOnValidThread());
}

void TransportSecurityState::DirtyNotify() {
  DCHECK(CalledOnValidThread());

  if (delegate_)
    delegate_->StateIsDirty(this);
}

// static
std::string TransportSecurityState::CanonicalizeHost(const std::string& host) {
  // We cannot perform the operations as detailed in the spec here as |host|
  // has already undergone IDN processing before it reached us. Thus, we check
  // that there are no invalid characters in the host and lowercase the result.

  std::string new_host;
  if (!DNSDomainFromDot(host, &new_host)) {
    // DNSDomainFromDot can fail if any label is > 63 bytes or if the whole
    // name is >255 bytes. However, search terms can have those properties.
    return std::string();
  }

  for (size_t i = 0; new_host[i]; i += new_host[i] + 1) {
    const unsigned label_length = static_cast<unsigned>(new_host[i]);
    if (!label_length)
      break;

    for (size_t j = 0; j < label_length; ++j) {
      new_host[i + 1 + j] = tolower(new_host[i + 1 + j]);
    }
  }

  return new_host;
}

// BitReader is a class that allows a bytestring to be read bit-by-bit.
class BitReader {
 public:
  BitReader(const uint8* bytes, size_t num_bits)
      : bytes_(bytes),
        num_bits_(num_bits),
        num_bytes_((num_bits + 7) / 8),
        current_byte_index_(0),
        num_bits_used_(8) {}

  // Next sets |*out| to the next bit from the input. It returns false if no
  // more bits are available or true otherwise.
  bool Next(bool* out) {
    if (num_bits_used_ == 8) {
      if (current_byte_index_ >= num_bytes_) {
        return false;
      }
      current_byte_ = bytes_[current_byte_index_++];
      num_bits_used_ = 0;
    }

    *out = 1 & (current_byte_ >> (7 - num_bits_used_));
    num_bits_used_++;
    return true;
  }

  // Read sets the |num_bits| least-significant bits of |*out| to the value of
  // the next |num_bits| bits from the input. It returns false if there are
  // insufficient bits in the input or true otherwise.
  bool Read(unsigned num_bits, uint32* out) {
    DCHECK_LE(num_bits, 32u);

    uint32 ret = 0;
    for (unsigned i = 0; i < num_bits; ++i) {
      bool bit;
      if (!Next(&bit)) {
        return false;
      }
      ret |= static_cast<uint32>(bit) << (num_bits - 1 - i);
    }

    *out = ret;
    return true;
  }

  // Unary sets |*out| to the result of decoding a unary value from the input.
  // It returns false if there were insufficient bits in the input and true
  // otherwise.
  bool Unary(size_t* out) {
    size_t ret = 0;

    for (;;) {
      bool bit;
      if (!Next(&bit)) {
        return false;
      }
      if (!bit) {
        break;
      }
      ret++;
    }

    *out = ret;
    return true;
  }

  // Seek sets the current offest in the input to bit number |offset|. It
  // returns true if |offset| is within the range of the input and false
  // otherwise.
  bool Seek(size_t offset) {
    if (offset >= num_bits_) {
      return false;
    }
    current_byte_index_ = offset / 8;
    current_byte_ = bytes_[current_byte_index_++];
    num_bits_used_ = offset % 8;
    return true;
  }

 private:
  const uint8* const bytes_;
  const size_t num_bits_;
  const size_t num_bytes_;
  // current_byte_index_ contains the current byte offset in |bytes_|.
  size_t current_byte_index_;
  // current_byte_ contains the current byte of the input.
  uint8 current_byte_;
  // num_bits_used_ contains the number of bits of |current_byte_| that have
  // been read.
  unsigned num_bits_used_;
};

// HuffmanDecoder is a very simple Huffman reader. The input Huffman tree is
// simply encoded as a series of two-byte structures. The first byte determines
// the "0" pointer for that node and the second the "1" pointer. Each byte
// either has the MSB set, in which case the bottom 7 bits are the value for
// that position, or else the bottom seven bits contain the index of a node.
//
// The tree is decoded by walking rather than a table-driven approach.
class HuffmanDecoder {
 public:
  HuffmanDecoder(const uint8* tree, size_t tree_bytes)
      : tree_(tree),
        tree_bytes_(tree_bytes) {}

  bool Decode(BitReader* reader, char* out) {
    const uint8* current = &tree_[tree_bytes_-2];

    for (;;) {
      bool bit;
      if (!reader->Next(&bit)) {
        return false;
      }

      uint8 b = current[bit];
      if (b & 0x80) {
        *out = static_cast<char>(b & 0x7f);
        return true;
      }

      unsigned offset = static_cast<unsigned>(b) * 2;
      DCHECK_LT(offset, tree_bytes_);
      if (offset >= tree_bytes_) {
        return false;
      }

      current = &tree_[offset];
    }
  }

 private:
  const uint8* const tree_;
  const size_t tree_bytes_;
};

#include "net/http/transport_security_state_static.h"

// PreloadResult is the result of resolving a specific name in the preloaded
// data.
struct PreloadResult {
  uint32 pinset_id;
  uint32 domain_id;
  // hostname_offset contains the number of bytes from the start of the given
  // hostname where the name of the matching entry starts.
  size_t hostname_offset;
  bool include_subdomains;
  bool force_https;
  bool has_pins;
};

// DecodeHSTSPreloadRaw resolves |hostname| in the preloaded data. It returns
// false on internal error and true otherwise. After a successful return,
// |*out_found| is true iff a relevant entry has been found. If so, |*out|
// contains the details.
//
// Don't call this function, call DecodeHSTSPreload, below.
//
// Although this code should be robust, it never processes attacker-controlled
// data -- it only operates on the preloaded data built into the binary.
//
// The preloaded data is represented as a trie and matches the hostname
// backwards. Each node in the trie starts with a number of characters, which
// must match exactly. After that is a dispatch table which maps the next
// character in the hostname to another node in the trie.
//
// In the dispatch table, the zero character represents the "end of string"
// (which is the *beginning* of a hostname since we process it backwards). The
// value in that case is special -- rather than an offset to another trie node,
// it contains the HSTS information: whether subdomains are included, pinsets
// etc. If an "end of string" matches a period in the hostname then the
// information is remembered because, if no more specific node is found, then
// that information applies to the hostname.
//
// Dispatch tables are always given in order, but the "end of string" (zero)
// value always comes before an entry for '.'.
bool DecodeHSTSPreloadRaw(const std::string& hostname,
                          bool* out_found,
                          PreloadResult* out) {
  HuffmanDecoder huffman(kHSTSHuffmanTree, sizeof(kHSTSHuffmanTree));
  BitReader reader(kPreloadedHSTSData, kPreloadedHSTSBits);
  size_t bit_offset = kHSTSRootPosition;
  static const char kEndOfString = 0;
  static const char kEndOfTable = 127;

  *out_found = false;

  if (hostname.empty()) {
    return true;
  }
  // hostname_offset contains one more than the index of the current character
  // in the hostname that is being considered. It's one greater so that we can
  // represent the position just before the beginning (with zero).
  size_t hostname_offset = hostname.size();

  for (;;) {
    // Seek to the desired location.
    if (!reader.Seek(bit_offset)) {
      return false;
    }

    // Decode the unary length of the common prefix.
    size_t prefix_length;
    if (!reader.Unary(&prefix_length)) {
      return false;
    }

    // Match each character in the prefix.
    for (size_t i = 0; i < prefix_length; ++i) {
      if (hostname_offset == 0) {
        // We can't match the terminator with a prefix string.
        return true;
      }

      char c;
      if (!huffman.Decode(&reader, &c)) {
        return false;
      }
      if (hostname[hostname_offset - 1] != c) {
        return true;
      }
      hostname_offset--;
    }

    bool is_first_offset = true;
    size_t current_offset = 0;

    // Next is the dispatch table.
    for (;;) {
      char c;
      if (!huffman.Decode(&reader, &c)) {
        return false;
      }
      if (c == kEndOfTable) {
        // No exact match.
        return true;
      }

      if (c == kEndOfString) {
        PreloadResult tmp;
        if (!reader.Next(&tmp.include_subdomains) ||
            !reader.Next(&tmp.force_https) ||
            !reader.Next(&tmp.has_pins)) {
          return false;
        }

        if (tmp.has_pins) {
          if (!reader.Read(4, &tmp.pinset_id) ||
              !reader.Read(9, &tmp.domain_id)) {
            return false;
          }
        }

        tmp.hostname_offset = hostname_offset;

        if (hostname_offset == 0 || hostname[hostname_offset - 1] == '.') {
          *out_found = tmp.include_subdomains;
          *out = tmp;
        }

        if (hostname_offset == 0) {
          *out_found = true;
          return true;
        }

        continue;
      }

      // The entries in a dispatch table are in order thus we can tell if there
      // will be no match if the current character past the one that we want.
      if (hostname_offset == 0 || hostname[hostname_offset-1] < c) {
        return true;
      }

      if (is_first_offset) {
        // The first offset is backwards from the current position.
        uint32 jump_delta_bits;
        uint32 jump_delta;
        if (!reader.Read(5, &jump_delta_bits) ||
            !reader.Read(jump_delta_bits, &jump_delta)) {
          return false;
        }

        if (bit_offset < jump_delta) {
          return false;
        }

        current_offset = bit_offset - jump_delta;
        is_first_offset = false;
      } else {
        // Subsequent offsets are forward from the target of the first offset.
        uint32 is_long_jump;
        if (!reader.Read(1, &is_long_jump)) {
          return false;
        }

        uint32 jump_delta;
        if (!is_long_jump) {
          if (!reader.Read(7, &jump_delta)) {
            return false;
          }
        } else {
          uint32 jump_delta_bits;
          if (!reader.Read(4, &jump_delta_bits) ||
              !reader.Read(jump_delta_bits + 8, &jump_delta)) {
            return false;
          }
        }

        current_offset += jump_delta;
        if (current_offset >= bit_offset) {
          return false;
        }
      }

      DCHECK_LT(0u, hostname_offset);
      if (hostname[hostname_offset - 1] == c) {
        bit_offset = current_offset;
        hostname_offset--;
        break;
      }
    }
  }
}

bool DecodeHSTSPreload(const std::string& hostname,
                       PreloadResult* out) {
  bool found;
  if (!DecodeHSTSPreloadRaw(hostname, &found, out)) {
    DCHECK(false) << "Internal error in DecodeHSTSPreloadRaw for hostname "
                  << hostname;
    return false;
  }

  return found;
}

bool TransportSecurityState::AddHSTSHeader(const std::string& host,
                                           const std::string& value) {
  DCHECK(CalledOnValidThread());

  base::Time now = base::Time::Now();
  base::TimeDelta max_age;
  TransportSecurityState::DomainState domain_state;
  GetDynamicDomainState(host, &domain_state);
  if (ParseHSTSHeader(value, &max_age, &domain_state.sts.include_subdomains)) {
    // Handle max-age == 0.
    if (max_age.InSeconds() == 0)
      domain_state.sts.upgrade_mode = DomainState::MODE_DEFAULT;
    else
      domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
    domain_state.sts.last_observed = now;
    domain_state.sts.expiry = now + max_age;
    EnableHost(host, domain_state);
    return true;
  }
  return false;
}

bool TransportSecurityState::AddHPKPHeader(const std::string& host,
                                           const std::string& value,
                                           const SSLInfo& ssl_info) {
  DCHECK(CalledOnValidThread());

  base::Time now = base::Time::Now();
  base::TimeDelta max_age;
  TransportSecurityState::DomainState domain_state;
  GetDynamicDomainState(host, &domain_state);
  if (ParseHPKPHeader(value,
                      ssl_info.public_key_hashes,
                      &max_age,
                      &domain_state.pkp.include_subdomains,
                      &domain_state.pkp.spki_hashes)) {
    // Handle max-age == 0.
    if (max_age.InSeconds() == 0)
      domain_state.pkp.spki_hashes.clear();
    domain_state.pkp.last_observed = now;
    domain_state.pkp.expiry = now + max_age;
    EnableHost(host, domain_state);
    return true;
  }
  return false;
}

bool TransportSecurityState::AddHSTS(const std::string& host,
                                     const base::Time& expiry,
                                     bool include_subdomains) {
  DCHECK(CalledOnValidThread());

  // Copy-and-modify the existing DomainState for this host (if any).
  TransportSecurityState::DomainState domain_state;
  const std::string canonicalized_host = CanonicalizeHost(host);
  const std::string hashed_host = HashHost(canonicalized_host);
  DomainStateMap::const_iterator i = enabled_hosts_.find(
      hashed_host);
  if (i != enabled_hosts_.end())
    domain_state = i->second;

  domain_state.sts.last_observed = base::Time::Now();
  domain_state.sts.include_subdomains = include_subdomains;
  domain_state.sts.expiry = expiry;
  domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
  EnableHost(host, domain_state);
  return true;
}

bool TransportSecurityState::AddHPKP(const std::string& host,
                                     const base::Time& expiry,
                                     bool include_subdomains,
                                     const HashValueVector& hashes) {
  DCHECK(CalledOnValidThread());

  // Copy-and-modify the existing DomainState for this host (if any).
  TransportSecurityState::DomainState domain_state;
  const std::string canonicalized_host = CanonicalizeHost(host);
  const std::string hashed_host = HashHost(canonicalized_host);
  DomainStateMap::const_iterator i = enabled_hosts_.find(
      hashed_host);
  if (i != enabled_hosts_.end())
    domain_state = i->second;

  domain_state.pkp.last_observed = base::Time::Now();
  domain_state.pkp.include_subdomains = include_subdomains;
  domain_state.pkp.expiry = expiry;
  domain_state.pkp.spki_hashes = hashes;
  EnableHost(host, domain_state);
  return true;
}

// static
bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) {
  PreloadResult result;
  return DecodeHSTSPreload(host, &result) && result.has_pins &&
         kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts;
}

// static
void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) {
  PreloadResult result;
  if (!DecodeHSTSPreload(host, &result) ||
      !result.has_pins) {
    return;
  }

  DCHECK(result.domain_id != DOMAIN_NOT_PINNED);

  UMA_HISTOGRAM_ENUMERATION(
      "Net.PublicKeyPinFailureDomain", result.domain_id, DOMAIN_NUM_EVENTS);
}

// static
bool TransportSecurityState::IsBuildTimely() {
  const base::Time build_time = base::GetBuildTime();
  // We consider built-in information to be timely for 10 weeks.
  return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
}

bool TransportSecurityState::CheckPublicKeyPinsImpl(
    const std::string& host,
    const HashValueVector& hashes,
    std::string* failure_log) {
  DomainState dynamic_state;
  if (GetDynamicDomainState(host, &dynamic_state))
    return dynamic_state.CheckPublicKeyPins(hashes, failure_log);

  DomainState static_state;
  if (GetStaticDomainState(host, &static_state))
    return static_state.CheckPublicKeyPins(hashes, failure_log);

  // HasPublicKeyPins should have returned true in order for this method
  // to have been called, so if we fall through to here, it's an error.
  return false;
}

bool TransportSecurityState::GetStaticDomainState(const std::string& host,
                                                  DomainState* out) const {
  DCHECK(CalledOnValidThread());

  out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
  out->sts.include_subdomains = false;
  out->pkp.include_subdomains = false;

  if (!IsBuildTimely())
    return false;

  PreloadResult result;
  if (!DecodeHSTSPreload(host, &result))
    return false;

  out->domain = host.substr(result.hostname_offset);
  out->sts.include_subdomains = result.include_subdomains;
  out->sts.last_observed = base::GetBuildTime();
  out->sts.upgrade_mode =
      TransportSecurityState::DomainState::MODE_DEFAULT;
  if (result.force_https) {
    out->sts.upgrade_mode =
        TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
  }

  if (enable_static_pins_ && result.has_pins) {
    out->pkp.include_subdomains = result.include_subdomains;
    out->pkp.last_observed = base::GetBuildTime();

    if (result.pinset_id >= arraysize(kPinsets))
      return false;
    const Pinset *pinset = &kPinsets[result.pinset_id];

    if (pinset->accepted_pins) {
      const char* const* sha1_hash = pinset->accepted_pins;
      while (*sha1_hash) {
        AddHash(*sha1_hash, &out->pkp.spki_hashes);
        sha1_hash++;
      }
    }
    if (pinset->rejected_pins) {
      const char* const* sha1_hash = pinset->rejected_pins;
      while (*sha1_hash) {
        AddHash(*sha1_hash, &out->pkp.bad_spki_hashes);
        sha1_hash++;
      }
    }
  }

  return true;
}

bool TransportSecurityState::GetDynamicDomainState(const std::string& host,
                                                   DomainState* result) {
  DCHECK(CalledOnValidThread());

  DomainState state;
  const std::string canonicalized_host = CanonicalizeHost(host);
  if (canonicalized_host.empty())
    return false;

  base::Time current_time(base::Time::Now());

  for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
    std::string host_sub_chunk(&canonicalized_host[i],
                               canonicalized_host.size() - i);
    DomainStateMap::iterator j =
        enabled_hosts_.find(HashHost(host_sub_chunk));
    if (j == enabled_hosts_.end())
      continue;

    if (current_time > j->second.sts.expiry &&
        current_time > j->second.pkp.expiry) {
      enabled_hosts_.erase(j);
      DirtyNotify();
      continue;
    }

    state = j->second;
    state.domain = DNSDomainToString(host_sub_chunk);

    // Succeed if we matched the domain exactly or if subdomain matches are
    // allowed.
    if (i == 0 || j->second.sts.include_subdomains ||
        j->second.pkp.include_subdomains) {
      *result = state;
      return true;
    }

    return false;
  }

  return false;
}

void TransportSecurityState::AddOrUpdateEnabledHosts(
    const std::string& hashed_host, const DomainState& state) {
  DCHECK(CalledOnValidThread());
  enabled_hosts_[hashed_host] = state;
}

TransportSecurityState::DomainState::DomainState() {
  sts.upgrade_mode = MODE_DEFAULT;
  sts.include_subdomains = false;
  pkp.include_subdomains = false;
}

TransportSecurityState::DomainState::~DomainState() {
}

bool TransportSecurityState::DomainState::CheckPublicKeyPins(
    const HashValueVector& hashes, std::string* failure_log) const {
  // Validate that hashes is not empty. By the time this code is called (in
  // production), that should never happen, but it's good to be defensive.
  // And, hashes *can* be empty in some test scenarios.
  if (hashes.empty()) {
    failure_log->append(
        "Rejecting empty public key chain for public-key-pinned domains: " +
        domain);
    return false;
  }

  if (HashesIntersect(pkp.bad_spki_hashes, hashes)) {
    failure_log->append("Rejecting public key chain for domain " + domain +
                        ". Validated chain: " + HashesToBase64String(hashes) +
                        ", matches one or more bad hashes: " +
                        HashesToBase64String(pkp.bad_spki_hashes));
    return false;
  }

  // If there are no pins, then any valid chain is acceptable.
  if (pkp.spki_hashes.empty())
    return true;

  if (HashesIntersect(pkp.spki_hashes, hashes)) {
    return true;
  }

  failure_log->append("Rejecting public key chain for domain " + domain +
                      ". Validated chain: " + HashesToBase64String(hashes) +
                      ", expected: " + HashesToBase64String(pkp.spki_hashes));
  return false;
}

bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const {
  return sts.upgrade_mode == MODE_FORCE_HTTPS;
}

bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const {
  return true;
}

bool TransportSecurityState::DomainState::HasPublicKeyPins() const {
  return pkp.spki_hashes.size() > 0 || pkp.bad_spki_hashes.size() > 0;
}

TransportSecurityState::DomainState::PKPState::PKPState() {
}

TransportSecurityState::DomainState::PKPState::~PKPState() {
}

}  // namespace
