15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/transport_security_state.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_OPENSSL)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <openssl/ecdsa.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <openssl/ssl.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else  // !defined(USE_OPENSSL)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cryptohi.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <hasht.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <keyhi.h>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <nspr.h>
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <pk11pub.h>
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base64.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/build_time.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sha1.h"
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/sha2.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/dns_util.h"
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/x509_cert_types.h"
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/x509_certificate.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_security_headers.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_info.h"
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_OPENSSL)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/openssl_util.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string HashesToBase64String(const HashValueVector& hashes) {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string str;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i != hashes.size(); ++i) {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i != 0)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      str += ",";
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    str += hashes[i].ToString();
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return str;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string HashHost(const std::string& canonicalized_host) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char hashed[crypto::kSHA256Length];
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  crypto::SHA256HashString(canonicalized_host, hashed, sizeof(hashed));
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::string(hashed, sizeof(hashed));
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if the intersection of |a| and |b| is not empty. If either
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |a| or |b| is empty, returns false.
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HashesIntersect(const HashValueVector& a,
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const HashValueVector& b) {
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (HashValueVector::const_iterator i = a.begin(); i != a.end(); ++i) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HashValueVector::const_iterator j =
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::find_if(b.begin(), b.end(), HashValuesEqual(*i));
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (j != b.end())
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AddHash(const char* sha1_hash,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             HashValueVector* out) {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HashValue hash(HASH_VALUE_SHA1);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memcpy(hash.data(), sha1_hash, hash.size());
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out->push_back(hash);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportSecurityState::TransportSecurityState()
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  : delegate_(NULL) {
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(CalledOnValidThread());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : iterator_(state.enabled_hosts_.begin()),
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      end_(state.enabled_hosts_.end()) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportSecurityState::Iterator::~Iterator() {}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TransportSecurityState::SetDelegate(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TransportSecurityState::Delegate* delegate) {
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = delegate;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TransportSecurityState::EnableHost(const std::string& host,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const DomainState& state) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string canonicalized_host = CanonicalizeHost(host);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (canonicalized_host.empty())
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DomainState state_copy(state);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No need to store this value since it is redundant. (|canonicalized_host|
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is the map key.)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state_copy.domain.clear();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enabled_hosts_[HashHost(canonicalized_host)] = state_copy;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DirtyNotify();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string canonicalized_host = CanonicalizeHost(host);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (canonicalized_host.empty())
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DomainStateMap::iterator i = enabled_hosts_.find(
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HashHost(canonicalized_host));
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i != enabled_hosts_.end()) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enabled_hosts_.erase(i);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DirtyNotify();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TransportSecurityState::GetDomainState(const std::string& host,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            bool sni_enabled,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            DomainState* result) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DomainState state;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string canonicalized_host = CanonicalizeHost(host);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (canonicalized_host.empty())
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_preload = GetStaticDomainState(canonicalized_host, sni_enabled,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          &state);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string canonicalized_preload = CanonicalizeHost(state.domain);
151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetDynamicDomainState(host, &state);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time current_time(base::Time::Now());
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string host_sub_chunk(&canonicalized_host[i],
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               canonicalized_host.size() - i);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Exact match of a preload always wins.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_preload && host_sub_chunk == canonicalized_preload) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *result = state;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DomainStateMap::iterator j =
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        enabled_hosts_.find(HashHost(host_sub_chunk));
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (j == enabled_hosts_.end())
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (current_time > j->second.upgrade_expiry &&
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current_time > j->second.dynamic_spki_hashes_expiry) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      enabled_hosts_.erase(j);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DirtyNotify();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state = j->second;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state.domain = DNSDomainToString(host_sub_chunk);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Succeed if we matched the domain exactly or if subdomain matches are
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // allowed.
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (i == 0 || j->second.sts_include_subdomains ||
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        j->second.pkp_include_subdomains) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *result = state;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TransportSecurityState::ClearDynamicData() {
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enabled_hosts_.clear();
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool dirtied = false;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DomainStateMap::iterator i = enabled_hosts_.begin();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (i != enabled_hosts_.end()) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i->second.created >= time) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dirtied = true;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      enabled_hosts_.erase(i++);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      i++;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dirtied)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DirtyNotify();
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TransportSecurityState::~TransportSecurityState() {
2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TransportSecurityState::DirtyNotify() {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->StateIsDirty(this);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TransportSecurityState::CanonicalizeHost(const std::string& host) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We cannot perform the operations as detailed in the spec here as |host|
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has already undergone IDN processing before it reached us. Thus, we check
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that there are no invalid characters in the host and lowercase the result.
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string new_host;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!DNSDomainFromDot(host, &new_host)) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // DNSDomainFromDot can fail if any label is > 63 bytes or if the whole
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // name is >255 bytes. However, search terms can have those properties.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::string();
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; new_host[i]; i += new_host[i] + 1) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned label_length = static_cast<unsigned>(new_host[i]);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!label_length)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < label_length; ++j) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // RFC 3490, 4.1, step 3
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!IsSTD3ASCIIValidCharacter(new_host[i + 1 + j]))
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return std::string();
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_host[i + 1 + j] = tolower(new_host[i + 1 + j]);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // step 3(b)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (new_host[i + 1] == '-' ||
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new_host[i + label_length] == '-') {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return std::string();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new_host;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |ReportUMAOnPinFailure| uses these to report which domain was associated
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with the public key pinning failure.
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DO NOT CHANGE THE ORDERING OF THESE NAMES OR REMOVE ANY OF THEM. Add new
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// domains at the END of the listing (but before DOMAIN_NUM_EVENTS).
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum SecondLevelDomainName {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_NOT_PINNED,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_COM,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_ANDROID_COM,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_ANALYTICS_COM,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLEPLEX_COM,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_YTIMG_COM,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLEUSERCONTENT_COM,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_YOUTUBE_COM,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLEAPIS_COM,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLEADSERVICES_COM,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLECODE_COM,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_APPSPOT_COM,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLESYNDICATION_COM,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_DOUBLECLICK_NET,
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GSTATIC_COM,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GMAIL_COM,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLEMAIL_COM,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLEGROUPS_COM,
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_TORPROJECT_ORG,
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_TWITTER_COM,
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_TWIMG_COM,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_AKAMAIHD_NET,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_TOR2WEB_ORG,
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_YOUTU_BE,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLECOMMERCE_COM,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_URCHIN_COM,
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOO_GL,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_G_CO,
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_AC,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_AD,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_AE,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_AF,
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_AG,
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_AM,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_AS,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_AT,
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_AZ,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_BA,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_BE,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_BF,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_BG,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_BI,
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_BJ,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_BS,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_BY,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CA,
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CAT,
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CC,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CD,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CF,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CG,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CH,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CI,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CL,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CM,
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CN,
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_AO,
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_BW,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_CK,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_CR,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_HU,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_ID,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_IL,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_IM,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_IN,
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_JE,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_JP,
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_KE,
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_KR,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_LS,
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_MA,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_MZ,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_NZ,
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_TH,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_TZ,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_UG,
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_UK,
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_UZ,
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_VE,
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_VI,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_ZA,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_ZM,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_CO_ZW,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_AF,
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_AG,
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_AI,
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_AR,
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_AU,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_BD,
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_BH,
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_BN,
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_BO,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_BR,
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_BY,
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_BZ,
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_CN,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_CO,
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_CU,
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_CY,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_DO,
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_EC,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_EG,
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_ET,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_FJ,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_GE,
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_GH,
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_GI,
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_GR,
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_GT,
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_HK,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_IQ,
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_JM,
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_JO,
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_KH,
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_KW,
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_LB,
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_LY,
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_MT,
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_MX,
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_MY,
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_NA,
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_NF,
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_NG,
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_NI,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_NP,
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_NR,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_OM,
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_PA,
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_PE,
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_PH,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_PK,
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_PL,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_PR,
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_PY,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_QA,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_RU,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_SA,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_SB,
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_SG,
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_SL,
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_SV,
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_TJ,
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_TN,
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_TR,
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_TW,
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_UA,
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_UY,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_VC,
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_VE,
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_COM_VN,
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CV,
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_CZ,
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_DE,
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_DJ,
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_DK,
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_DM,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_DZ,
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_EE,
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_ES,
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_FI,
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_FM,
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_FR,
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_GA,
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_GE,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_GG,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_GL,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_GM,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_GP,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_GR,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_GY,
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_HK,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_HN,
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_HR,
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_HT,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_HU,
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_IE,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_IM,
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_INFO,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_IQ,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_IS,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_IT,
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_IT_AO,
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_JE,
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_JO,
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_JOBS,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_JP,
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_KG,
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_KI,
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_KZ,
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_LA,
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_LI,
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_LK,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_LT,
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_LU,
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_LV,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_MD,
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_ME,
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_MG,
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_MK,
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_ML,
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_MN,
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_MS,
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_MU,
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_MV,
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_MW,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_NE,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_NE_JP,
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_NET,
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_NL,
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_NO,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_NR,
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_NU,
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_OFF_AI,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_PK,
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_PL,
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_PN,
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_PS,
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_PT,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_RO,
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_RS,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_RU,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_RW,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_SC,
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_SE,
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_SH,
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_SI,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_SK,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_SM,
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_SN,
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_SO,
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_ST,
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_TD,
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_TG,
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_TK,
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_TL,
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_TM,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_TN,
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_TO,
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_TP,
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_TT,
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_US,
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_UZ,
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_VG,
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_VU,
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_GOOGLE_WS,
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DOMAIN_CHROMIUM_ORG,
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DOMAIN_CRYPTO_CAT,
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Boundary value for UMA_HISTOGRAM_ENUMERATION:
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DOMAIN_NUM_EVENTS
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PublicKeyPins contains a number of SubjectPublicKeyInfo hashes for a site.
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The validated certificate chain for the site must not include any of
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |excluded_hashes| and must include one or more of |required_hashes|.
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PublicKeyPins {
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const* required_hashes;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const* excluded_hashes;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct HSTSPreload {
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8 length;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool include_subdomains;
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  char dns_name[38];
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool https_required;
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PublicKeyPins pins;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SecondLevelDomainName second_level_domain_name;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool HasPreload(const struct HSTSPreload* entries, size_t num_entries,
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const std::string& canonicalized_host, size_t i,
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       TransportSecurityState::DomainState* out, bool* ret) {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t j = 0; j < num_entries; j++) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (entries[j].length == canonicalized_host.size() - i &&
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        memcmp(entries[j].dns_name, &canonicalized_host[i],
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               entries[j].length) == 0) {
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!entries[j].include_subdomains && i != 0) {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *ret = false;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
5577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        out->sts_include_subdomains = entries[j].include_subdomains;
5587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        out->pkp_include_subdomains = entries[j].include_subdomains;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *ret = true;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!entries[j].https_required)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          out->upgrade_mode = TransportSecurityState::DomainState::MODE_DEFAULT;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (entries[j].pins.required_hashes) {
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          const char* const* sha1_hash = entries[j].pins.required_hashes;
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          while (*sha1_hash) {
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            AddHash(*sha1_hash, &out->static_spki_hashes);
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            sha1_hash++;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (entries[j].pins.excluded_hashes) {
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          const char* const* sha1_hash = entries[j].pins.excluded_hashes;
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          while (*sha1_hash) {
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            AddHash(*sha1_hash, &out->bad_static_spki_hashes);
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            sha1_hash++;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/transport_security_state_static.h"
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the HSTSPreload entry for the |canonicalized_host| in |entries|,
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or NULL if there is none. Prefers exact hostname matches to those that
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// match only because HSTSPreload.include_subdomains is true.
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |canonicalized_host| should be the hostname as canonicalized by
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CanonicalizeHost.
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const struct HSTSPreload* GetHSTSPreload(
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& canonicalized_host,
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const struct HSTSPreload* entries,
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t num_entries) {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < num_entries; j++) {
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const struct HSTSPreload* entry = entries + j;
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (i != 0 && !entry->include_subdomains)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (entry->length == canonicalized_host.size() - i &&
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          memcmp(entry->dns_name, &canonicalized_host[i], entry->length) == 0) {
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return entry;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TransportSecurityState::AddHSTSHeader(const std::string& host,
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const std::string& value) {
6147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(CalledOnValidThread());
6157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Time now = base::Time::Now();
61790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::TimeDelta max_age;
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TransportSecurityState::DomainState domain_state;
619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetDynamicDomainState(host, &domain_state);
6207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (ParseHSTSHeader(value, &max_age, &domain_state.sts_include_subdomains)) {
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Handle max-age == 0
62290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (max_age.InSeconds() == 0)
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      domain_state.upgrade_mode = DomainState::MODE_DEFAULT;
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    domain_state.created = now;
62790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    domain_state.upgrade_expiry = now + max_age;
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EnableHost(host, domain_state);
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TransportSecurityState::AddHPKPHeader(const std::string& host,
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const std::string& value,
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const SSLInfo& ssl_info) {
6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(CalledOnValidThread());
6387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Time now = base::Time::Now();
64090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::TimeDelta max_age;
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TransportSecurityState::DomainState domain_state;
642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetDynamicDomainState(host, &domain_state);
64390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (ParseHPKPHeader(value, ssl_info.public_key_hashes,
644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                      &max_age, &domain_state.pkp_include_subdomains,
645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                      &domain_state.dynamic_spki_hashes)) {
646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // TODO(palmer): http://crbug.com/243865 handle max-age == 0.
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    domain_state.created = now;
64890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    domain_state.dynamic_spki_hashes_expiry = now + max_age;
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EnableHost(host, domain_state);
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TransportSecurityState::AddHSTS(const std::string& host,
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const base::Time& expiry,
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     bool include_subdomains) {
6587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(CalledOnValidThread());
6597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Copy-and-modify the existing DomainState for this host (if any).
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TransportSecurityState::DomainState domain_state;
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string canonicalized_host = CanonicalizeHost(host);
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string hashed_host = HashHost(canonicalized_host);
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DomainStateMap::const_iterator i = enabled_hosts_.find(
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      hashed_host);
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (i != enabled_hosts_.end())
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    domain_state = i->second;
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  domain_state.created = base::Time::Now();
6707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  domain_state.sts_include_subdomains = include_subdomains;
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  domain_state.upgrade_expiry = expiry;
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnableHost(host, domain_state);
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TransportSecurityState::AddHPKP(const std::string& host,
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const base::Time& expiry,
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     bool include_subdomains,
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const HashValueVector& hashes) {
6817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(CalledOnValidThread());
6827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Copy-and-modify the existing DomainState for this host (if any).
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TransportSecurityState::DomainState domain_state;
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string canonicalized_host = CanonicalizeHost(host);
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string hashed_host = HashHost(canonicalized_host);
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DomainStateMap::const_iterator i = enabled_hosts_.find(
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      hashed_host);
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (i != enabled_hosts_.end())
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    domain_state = i->second;
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  domain_state.created = base::Time::Now();
6937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  domain_state.pkp_include_subdomains = include_subdomains;
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  domain_state.dynamic_spki_hashes_expiry = expiry;
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  domain_state.dynamic_spki_hashes = hashes;
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnableHost(host, domain_state);
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host,
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    bool sni_enabled) {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string canonicalized_host = CanonicalizeHost(host);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct HSTSPreload* entry =
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS);
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (entry && entry->pins.required_hashes == kGoogleAcceptableCerts)
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sni_enabled) {
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry = GetHSTSPreload(canonicalized_host, kPreloadedSNISTS,
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           kNumPreloadedSNISTS);
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (entry && entry->pins.required_hashes == kGoogleAcceptableCerts)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) {
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string canonicalized_host = CanonicalizeHost(host);
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct HSTSPreload* entry =
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!entry) {
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry = GetHSTSPreload(canonicalized_host, kPreloadedSNISTS,
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           kNumPreloadedSNISTS);
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!entry) {
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't care to report pin failures for dynamic pins.
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(entry);
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(entry->pins.required_hashes);
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(entry->second_level_domain_name != DOMAIN_NOT_PINNED);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Net.PublicKeyPinFailureDomain",
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            entry->second_level_domain_name, DOMAIN_NUM_EVENTS);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TransportSecurityState::IsBuildTimely() {
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::Time build_time = base::GetBuildTime();
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We consider built-in information to be timely for 10 weeks.
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TransportSecurityState::GetStaticDomainState(
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& canonicalized_host,
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool sni_enabled,
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DomainState* out) {
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out->upgrade_mode = DomainState::MODE_FORCE_HTTPS;
7597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  out->sts_include_subdomains = false;
7607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  out->pkp_include_subdomains = false;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool is_build_timely = IsBuildTimely();
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string host_sub_chunk(&canonicalized_host[i],
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               canonicalized_host.size() - i);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out->domain = DNSDomainToString(host_sub_chunk);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool ret;
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (is_build_timely &&
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        HasPreload(kPreloadedSTS, kNumPreloadedSTS, canonicalized_host, i, out,
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   &ret)) {
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ret;
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sni_enabled &&
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        is_build_timely &&
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HasPreload(kPreloadedSNISTS, kNumPreloadedSNISTS, canonicalized_host, i,
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   out, &ret)) {
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ret;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool TransportSecurityState::GetDynamicDomainState(const std::string& host,
786eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                                   DomainState* result) {
787eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(CalledOnValidThread());
788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
789eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DomainState state;
790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const std::string canonicalized_host = CanonicalizeHost(host);
791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (canonicalized_host.empty())
792eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return false;
793eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::Time current_time(base::Time::Now());
795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
797eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string host_sub_chunk(&canonicalized_host[i],
798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                               canonicalized_host.size() - i);
799eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DomainStateMap::iterator j =
800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        enabled_hosts_.find(HashHost(host_sub_chunk));
801eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (j == enabled_hosts_.end())
802eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      continue;
803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (current_time > j->second.upgrade_expiry &&
805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        current_time > j->second.dynamic_spki_hashes_expiry) {
806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      enabled_hosts_.erase(j);
807eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      DirtyNotify();
808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      continue;
809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
811eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    state = j->second;
812eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    state.domain = DNSDomainToString(host_sub_chunk);
813eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
814eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Succeed if we matched the domain exactly or if subdomain matches are
815eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // allowed.
816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (i == 0 || j->second.sts_include_subdomains ||
817eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        j->second.pkp_include_subdomains) {
818eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      *result = state;
819eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return true;
820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
821eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return false;
823eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
824eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
825eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return false;
826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
827eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
828eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TransportSecurityState::AddOrUpdateEnabledHosts(
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& hashed_host, const DomainState& state) {
8317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(CalledOnValidThread());
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enabled_hosts_[hashed_host] = state;
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportSecurityState::DomainState::DomainState()
836eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : upgrade_mode(MODE_DEFAULT),
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      created(base::Time::Now()),
8387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      sts_include_subdomains(false),
8397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      pkp_include_subdomains(false) {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportSecurityState::DomainState::~DomainState() {
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TransportSecurityState::DomainState::CheckPublicKeyPins(
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HashValueVector& hashes) const {
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Validate that hashes is not empty. By the time this code is called (in
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // production), that should never happen, but it's good to be defensive.
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And, hashes *can* be empty in some test scenarios.
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (hashes.empty()) {
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Rejecting empty public key chain for public-key-pinned "
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  "domain " << domain;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HashesIntersect(bad_static_spki_hashes, hashes)) {
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Rejecting public key chain for domain " << domain
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << ". Validated chain: " << HashesToBase64String(hashes)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << ", matches one or more bad hashes: "
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << HashesToBase64String(bad_static_spki_hashes);
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there are no pins, then any valid chain is acceptable.
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dynamic_spki_hashes.empty() && static_spki_hashes.empty())
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HashesIntersect(dynamic_spki_hashes, hashes) ||
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HashesIntersect(static_spki_hashes, hashes)) {
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(ERROR) << "Rejecting public key chain for domain " << domain
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             << ". Validated chain: " << HashesToBase64String(hashes)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             << ", expected: " << HashesToBase64String(dynamic_spki_hashes)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             << " or: " << HashesToBase64String(static_spki_hashes);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const {
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return upgrade_mode == MODE_FORCE_HTTPS;
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const {
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TransportSecurityState::DomainState::HasPublicKeyPins() const {
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_spki_hashes.size() > 0 ||
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         bad_static_spki_hashes.size() > 0 ||
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         dynamic_spki_hashes.size() > 0;
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
895