Home | History | Annotate | Download | only in http
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/http/transport_security_state.h"
      6 
      7 #if defined(USE_OPENSSL)
      8 #include <openssl/ecdsa.h>
      9 #include <openssl/ssl.h>
     10 #else  // !defined(USE_OPENSSL)
     11 #include <cryptohi.h>
     12 #include <hasht.h>
     13 #include <keyhi.h>
     14 #include <nspr.h>
     15 #include <pk11pub.h>
     16 #endif
     17 
     18 #include <algorithm>
     19 
     20 #include "base/base64.h"
     21 #include "base/build_time.h"
     22 #include "base/logging.h"
     23 #include "base/memory/scoped_ptr.h"
     24 #include "base/metrics/histogram.h"
     25 #include "base/sha1.h"
     26 #include "base/strings/string_number_conversions.h"
     27 #include "base/strings/string_util.h"
     28 #include "base/strings/utf_string_conversions.h"
     29 #include "base/time/time.h"
     30 #include "base/values.h"
     31 #include "crypto/sha2.h"
     32 #include "net/base/dns_util.h"
     33 #include "net/cert/x509_cert_types.h"
     34 #include "net/cert/x509_certificate.h"
     35 #include "net/http/http_security_headers.h"
     36 #include "net/ssl/ssl_info.h"
     37 #include "url/gurl.h"
     38 
     39 #if defined(USE_OPENSSL)
     40 #include "crypto/openssl_util.h"
     41 #endif
     42 
     43 namespace net {
     44 
     45 namespace {
     46 
     47 std::string HashesToBase64String(const HashValueVector& hashes) {
     48   std::string str;
     49   for (size_t i = 0; i != hashes.size(); ++i) {
     50     if (i != 0)
     51       str += ",";
     52     str += hashes[i].ToString();
     53   }
     54   return str;
     55 }
     56 
     57 std::string HashHost(const std::string& canonicalized_host) {
     58   char hashed[crypto::kSHA256Length];
     59   crypto::SHA256HashString(canonicalized_host, hashed, sizeof(hashed));
     60   return std::string(hashed, sizeof(hashed));
     61 }
     62 
     63 // Returns true if the intersection of |a| and |b| is not empty. If either
     64 // |a| or |b| is empty, returns false.
     65 bool HashesIntersect(const HashValueVector& a,
     66                      const HashValueVector& b) {
     67   for (HashValueVector::const_iterator i = a.begin(); i != a.end(); ++i) {
     68     HashValueVector::const_iterator j =
     69         std::find_if(b.begin(), b.end(), HashValuesEqual(*i));
     70     if (j != b.end())
     71       return true;
     72   }
     73   return false;
     74 }
     75 
     76 bool AddHash(const char* sha1_hash,
     77              HashValueVector* out) {
     78   HashValue hash(HASH_VALUE_SHA1);
     79   memcpy(hash.data(), sha1_hash, hash.size());
     80   out->push_back(hash);
     81   return true;
     82 }
     83 
     84 }  // namespace
     85 
     86 TransportSecurityState::TransportSecurityState()
     87     : delegate_(NULL), enable_static_pins_(true) {
     88 // Static pinning is only enabled for official builds to make sure that
     89 // others don't end up with pins that cannot be easily updated.
     90 #if !defined(OFFICIAL_BUILD) || defined(OS_ANDROID) || defined(OS_IOS)
     91   enable_static_pins_ = false;
     92 #endif
     93   DCHECK(CalledOnValidThread());
     94 }
     95 
     96 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state)
     97     : iterator_(state.enabled_hosts_.begin()),
     98       end_(state.enabled_hosts_.end()) {
     99 }
    100 
    101 TransportSecurityState::Iterator::~Iterator() {}
    102 
    103 bool TransportSecurityState::ShouldSSLErrorsBeFatal(const std::string& host) {
    104   DomainState state;
    105   if (GetStaticDomainState(host, &state))
    106     return true;
    107   return GetDynamicDomainState(host, &state);
    108 }
    109 
    110 bool TransportSecurityState::ShouldUpgradeToSSL(const std::string& host) {
    111   DomainState dynamic_state;
    112   if (GetDynamicDomainState(host, &dynamic_state))
    113     return dynamic_state.ShouldUpgradeToSSL();
    114 
    115   DomainState static_state;
    116   if (GetStaticDomainState(host, &static_state) &&
    117       static_state.ShouldUpgradeToSSL()) {
    118       return true;
    119   }
    120 
    121   return false;
    122 }
    123 
    124 bool TransportSecurityState::CheckPublicKeyPins(
    125     const std::string& host,
    126     bool is_issued_by_known_root,
    127     const HashValueVector& public_key_hashes,
    128     std::string* pinning_failure_log) {
    129   // Perform pin validation if, and only if, all these conditions obtain:
    130   //
    131   // * the server's certificate chain chains up to a known root (i.e. not a
    132   //   user-installed trust anchor); and
    133   // * the server actually has public key pins.
    134   if (!is_issued_by_known_root || !HasPublicKeyPins(host)) {
    135     return true;
    136   }
    137 
    138   bool pins_are_valid = CheckPublicKeyPinsImpl(
    139       host, public_key_hashes, pinning_failure_log);
    140   if (!pins_are_valid) {
    141     LOG(ERROR) << *pinning_failure_log;
    142     ReportUMAOnPinFailure(host);
    143   }
    144 
    145   UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid);
    146   return pins_are_valid;
    147 }
    148 
    149 bool TransportSecurityState::HasPublicKeyPins(const std::string& host) {
    150   DomainState dynamic_state;
    151   if (GetDynamicDomainState(host, &dynamic_state))
    152     return dynamic_state.HasPublicKeyPins();
    153 
    154   DomainState static_state;
    155   if (GetStaticDomainState(host, &static_state)) {
    156     if (static_state.HasPublicKeyPins())
    157       return true;
    158   }
    159 
    160   return false;
    161 }
    162 
    163 void TransportSecurityState::SetDelegate(
    164     TransportSecurityState::Delegate* delegate) {
    165   DCHECK(CalledOnValidThread());
    166   delegate_ = delegate;
    167 }
    168 
    169 void TransportSecurityState::EnableHost(const std::string& host,
    170                                         const DomainState& state) {
    171   DCHECK(CalledOnValidThread());
    172 
    173   const std::string canonicalized_host = CanonicalizeHost(host);
    174   if (canonicalized_host.empty())
    175     return;
    176 
    177   DomainState state_copy(state);
    178   // No need to store this value since it is redundant. (|canonicalized_host|
    179   // is the map key.)
    180   state_copy.domain.clear();
    181 
    182   enabled_hosts_[HashHost(canonicalized_host)] = state_copy;
    183   DirtyNotify();
    184 }
    185 
    186 bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
    187   DCHECK(CalledOnValidThread());
    188 
    189   const std::string canonicalized_host = CanonicalizeHost(host);
    190   if (canonicalized_host.empty())
    191     return false;
    192 
    193   DomainStateMap::iterator i = enabled_hosts_.find(
    194       HashHost(canonicalized_host));
    195   if (i != enabled_hosts_.end()) {
    196     enabled_hosts_.erase(i);
    197     DirtyNotify();
    198     return true;
    199   }
    200   return false;
    201 }
    202 
    203 void TransportSecurityState::ClearDynamicData() {
    204   DCHECK(CalledOnValidThread());
    205   enabled_hosts_.clear();
    206 }
    207 
    208 void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) {
    209   DCHECK(CalledOnValidThread());
    210 
    211   bool dirtied = false;
    212   DomainStateMap::iterator i = enabled_hosts_.begin();
    213   while (i != enabled_hosts_.end()) {
    214     if (i->second.sts.last_observed >= time &&
    215         i->second.pkp.last_observed >= time) {
    216       dirtied = true;
    217       enabled_hosts_.erase(i++);
    218       continue;
    219     }
    220 
    221     if (i->second.sts.last_observed >= time) {
    222       dirtied = true;
    223       i->second.sts.upgrade_mode = DomainState::MODE_DEFAULT;
    224     } else if (i->second.pkp.last_observed >= time) {
    225       dirtied = true;
    226       i->second.pkp.spki_hashes.clear();
    227       i->second.pkp.expiry = base::Time();
    228     }
    229     ++i;
    230   }
    231 
    232   if (dirtied)
    233     DirtyNotify();
    234 }
    235 
    236 TransportSecurityState::~TransportSecurityState() {
    237   DCHECK(CalledOnValidThread());
    238 }
    239 
    240 void TransportSecurityState::DirtyNotify() {
    241   DCHECK(CalledOnValidThread());
    242 
    243   if (delegate_)
    244     delegate_->StateIsDirty(this);
    245 }
    246 
    247 // static
    248 std::string TransportSecurityState::CanonicalizeHost(const std::string& host) {
    249   // We cannot perform the operations as detailed in the spec here as |host|
    250   // has already undergone IDN processing before it reached us. Thus, we check
    251   // that there are no invalid characters in the host and lowercase the result.
    252 
    253   std::string new_host;
    254   if (!DNSDomainFromDot(host, &new_host)) {
    255     // DNSDomainFromDot can fail if any label is > 63 bytes or if the whole
    256     // name is >255 bytes. However, search terms can have those properties.
    257     return std::string();
    258   }
    259 
    260   for (size_t i = 0; new_host[i]; i += new_host[i] + 1) {
    261     const unsigned label_length = static_cast<unsigned>(new_host[i]);
    262     if (!label_length)
    263       break;
    264 
    265     for (size_t j = 0; j < label_length; ++j) {
    266       new_host[i + 1 + j] = tolower(new_host[i + 1 + j]);
    267     }
    268   }
    269 
    270   return new_host;
    271 }
    272 
    273 // |ReportUMAOnPinFailure| uses these to report which domain was associated
    274 // with the public key pinning failure.
    275 //
    276 // DO NOT CHANGE THE ORDERING OF THESE NAMES OR REMOVE ANY OF THEM. Add new
    277 // domains at the END of the listing (but before DOMAIN_NUM_EVENTS).
    278 enum SecondLevelDomainName {
    279   DOMAIN_NOT_PINNED,
    280 
    281   DOMAIN_GOOGLE_COM,
    282   DOMAIN_ANDROID_COM,
    283   DOMAIN_GOOGLE_ANALYTICS_COM,
    284   DOMAIN_GOOGLEPLEX_COM,
    285   DOMAIN_YTIMG_COM,
    286   DOMAIN_GOOGLEUSERCONTENT_COM,
    287   DOMAIN_YOUTUBE_COM,
    288   DOMAIN_GOOGLEAPIS_COM,
    289   DOMAIN_GOOGLEADSERVICES_COM,
    290   DOMAIN_GOOGLECODE_COM,
    291   DOMAIN_APPSPOT_COM,
    292   DOMAIN_GOOGLESYNDICATION_COM,
    293   DOMAIN_DOUBLECLICK_NET,
    294   DOMAIN_GSTATIC_COM,
    295   DOMAIN_GMAIL_COM,
    296   DOMAIN_GOOGLEMAIL_COM,
    297   DOMAIN_GOOGLEGROUPS_COM,
    298 
    299   DOMAIN_TORPROJECT_ORG,
    300 
    301   DOMAIN_TWITTER_COM,
    302   DOMAIN_TWIMG_COM,
    303 
    304   DOMAIN_AKAMAIHD_NET,
    305 
    306   DOMAIN_TOR2WEB_ORG,
    307 
    308   DOMAIN_YOUTU_BE,
    309   DOMAIN_GOOGLECOMMERCE_COM,
    310   DOMAIN_URCHIN_COM,
    311   DOMAIN_GOO_GL,
    312   DOMAIN_G_CO,
    313   DOMAIN_GOOGLE_AC,
    314   DOMAIN_GOOGLE_AD,
    315   DOMAIN_GOOGLE_AE,
    316   DOMAIN_GOOGLE_AF,
    317   DOMAIN_GOOGLE_AG,
    318   DOMAIN_GOOGLE_AM,
    319   DOMAIN_GOOGLE_AS,
    320   DOMAIN_GOOGLE_AT,
    321   DOMAIN_GOOGLE_AZ,
    322   DOMAIN_GOOGLE_BA,
    323   DOMAIN_GOOGLE_BE,
    324   DOMAIN_GOOGLE_BF,
    325   DOMAIN_GOOGLE_BG,
    326   DOMAIN_GOOGLE_BI,
    327   DOMAIN_GOOGLE_BJ,
    328   DOMAIN_GOOGLE_BS,
    329   DOMAIN_GOOGLE_BY,
    330   DOMAIN_GOOGLE_CA,
    331   DOMAIN_GOOGLE_CAT,
    332   DOMAIN_GOOGLE_CC,
    333   DOMAIN_GOOGLE_CD,
    334   DOMAIN_GOOGLE_CF,
    335   DOMAIN_GOOGLE_CG,
    336   DOMAIN_GOOGLE_CH,
    337   DOMAIN_GOOGLE_CI,
    338   DOMAIN_GOOGLE_CL,
    339   DOMAIN_GOOGLE_CM,
    340   DOMAIN_GOOGLE_CN,
    341   DOMAIN_CO_AO,
    342   DOMAIN_CO_BW,
    343   DOMAIN_CO_CK,
    344   DOMAIN_CO_CR,
    345   DOMAIN_CO_HU,
    346   DOMAIN_CO_ID,
    347   DOMAIN_CO_IL,
    348   DOMAIN_CO_IM,
    349   DOMAIN_CO_IN,
    350   DOMAIN_CO_JE,
    351   DOMAIN_CO_JP,
    352   DOMAIN_CO_KE,
    353   DOMAIN_CO_KR,
    354   DOMAIN_CO_LS,
    355   DOMAIN_CO_MA,
    356   DOMAIN_CO_MZ,
    357   DOMAIN_CO_NZ,
    358   DOMAIN_CO_TH,
    359   DOMAIN_CO_TZ,
    360   DOMAIN_CO_UG,
    361   DOMAIN_CO_UK,
    362   DOMAIN_CO_UZ,
    363   DOMAIN_CO_VE,
    364   DOMAIN_CO_VI,
    365   DOMAIN_CO_ZA,
    366   DOMAIN_CO_ZM,
    367   DOMAIN_CO_ZW,
    368   DOMAIN_COM_AF,
    369   DOMAIN_COM_AG,
    370   DOMAIN_COM_AI,
    371   DOMAIN_COM_AR,
    372   DOMAIN_COM_AU,
    373   DOMAIN_COM_BD,
    374   DOMAIN_COM_BH,
    375   DOMAIN_COM_BN,
    376   DOMAIN_COM_BO,
    377   DOMAIN_COM_BR,
    378   DOMAIN_COM_BY,
    379   DOMAIN_COM_BZ,
    380   DOMAIN_COM_CN,
    381   DOMAIN_COM_CO,
    382   DOMAIN_COM_CU,
    383   DOMAIN_COM_CY,
    384   DOMAIN_COM_DO,
    385   DOMAIN_COM_EC,
    386   DOMAIN_COM_EG,
    387   DOMAIN_COM_ET,
    388   DOMAIN_COM_FJ,
    389   DOMAIN_COM_GE,
    390   DOMAIN_COM_GH,
    391   DOMAIN_COM_GI,
    392   DOMAIN_COM_GR,
    393   DOMAIN_COM_GT,
    394   DOMAIN_COM_HK,
    395   DOMAIN_COM_IQ,
    396   DOMAIN_COM_JM,
    397   DOMAIN_COM_JO,
    398   DOMAIN_COM_KH,
    399   DOMAIN_COM_KW,
    400   DOMAIN_COM_LB,
    401   DOMAIN_COM_LY,
    402   DOMAIN_COM_MT,
    403   DOMAIN_COM_MX,
    404   DOMAIN_COM_MY,
    405   DOMAIN_COM_NA,
    406   DOMAIN_COM_NF,
    407   DOMAIN_COM_NG,
    408   DOMAIN_COM_NI,
    409   DOMAIN_COM_NP,
    410   DOMAIN_COM_NR,
    411   DOMAIN_COM_OM,
    412   DOMAIN_COM_PA,
    413   DOMAIN_COM_PE,
    414   DOMAIN_COM_PH,
    415   DOMAIN_COM_PK,
    416   DOMAIN_COM_PL,
    417   DOMAIN_COM_PR,
    418   DOMAIN_COM_PY,
    419   DOMAIN_COM_QA,
    420   DOMAIN_COM_RU,
    421   DOMAIN_COM_SA,
    422   DOMAIN_COM_SB,
    423   DOMAIN_COM_SG,
    424   DOMAIN_COM_SL,
    425   DOMAIN_COM_SV,
    426   DOMAIN_COM_TJ,
    427   DOMAIN_COM_TN,
    428   DOMAIN_COM_TR,
    429   DOMAIN_COM_TW,
    430   DOMAIN_COM_UA,
    431   DOMAIN_COM_UY,
    432   DOMAIN_COM_VC,
    433   DOMAIN_COM_VE,
    434   DOMAIN_COM_VN,
    435   DOMAIN_GOOGLE_CV,
    436   DOMAIN_GOOGLE_CZ,
    437   DOMAIN_GOOGLE_DE,
    438   DOMAIN_GOOGLE_DJ,
    439   DOMAIN_GOOGLE_DK,
    440   DOMAIN_GOOGLE_DM,
    441   DOMAIN_GOOGLE_DZ,
    442   DOMAIN_GOOGLE_EE,
    443   DOMAIN_GOOGLE_ES,
    444   DOMAIN_GOOGLE_FI,
    445   DOMAIN_GOOGLE_FM,
    446   DOMAIN_GOOGLE_FR,
    447   DOMAIN_GOOGLE_GA,
    448   DOMAIN_GOOGLE_GE,
    449   DOMAIN_GOOGLE_GG,
    450   DOMAIN_GOOGLE_GL,
    451   DOMAIN_GOOGLE_GM,
    452   DOMAIN_GOOGLE_GP,
    453   DOMAIN_GOOGLE_GR,
    454   DOMAIN_GOOGLE_GY,
    455   DOMAIN_GOOGLE_HK,
    456   DOMAIN_GOOGLE_HN,
    457   DOMAIN_GOOGLE_HR,
    458   DOMAIN_GOOGLE_HT,
    459   DOMAIN_GOOGLE_HU,
    460   DOMAIN_GOOGLE_IE,
    461   DOMAIN_GOOGLE_IM,
    462   DOMAIN_GOOGLE_INFO,
    463   DOMAIN_GOOGLE_IQ,
    464   DOMAIN_GOOGLE_IS,
    465   DOMAIN_GOOGLE_IT,
    466   DOMAIN_IT_AO,
    467   DOMAIN_GOOGLE_JE,
    468   DOMAIN_GOOGLE_JO,
    469   DOMAIN_GOOGLE_JOBS,
    470   DOMAIN_GOOGLE_JP,
    471   DOMAIN_GOOGLE_KG,
    472   DOMAIN_GOOGLE_KI,
    473   DOMAIN_GOOGLE_KZ,
    474   DOMAIN_GOOGLE_LA,
    475   DOMAIN_GOOGLE_LI,
    476   DOMAIN_GOOGLE_LK,
    477   DOMAIN_GOOGLE_LT,
    478   DOMAIN_GOOGLE_LU,
    479   DOMAIN_GOOGLE_LV,
    480   DOMAIN_GOOGLE_MD,
    481   DOMAIN_GOOGLE_ME,
    482   DOMAIN_GOOGLE_MG,
    483   DOMAIN_GOOGLE_MK,
    484   DOMAIN_GOOGLE_ML,
    485   DOMAIN_GOOGLE_MN,
    486   DOMAIN_GOOGLE_MS,
    487   DOMAIN_GOOGLE_MU,
    488   DOMAIN_GOOGLE_MV,
    489   DOMAIN_GOOGLE_MW,
    490   DOMAIN_GOOGLE_NE,
    491   DOMAIN_NE_JP,
    492   DOMAIN_GOOGLE_NET,
    493   DOMAIN_GOOGLE_NL,
    494   DOMAIN_GOOGLE_NO,
    495   DOMAIN_GOOGLE_NR,
    496   DOMAIN_GOOGLE_NU,
    497   DOMAIN_OFF_AI,
    498   DOMAIN_GOOGLE_PK,
    499   DOMAIN_GOOGLE_PL,
    500   DOMAIN_GOOGLE_PN,
    501   DOMAIN_GOOGLE_PS,
    502   DOMAIN_GOOGLE_PT,
    503   DOMAIN_GOOGLE_RO,
    504   DOMAIN_GOOGLE_RS,
    505   DOMAIN_GOOGLE_RU,
    506   DOMAIN_GOOGLE_RW,
    507   DOMAIN_GOOGLE_SC,
    508   DOMAIN_GOOGLE_SE,
    509   DOMAIN_GOOGLE_SH,
    510   DOMAIN_GOOGLE_SI,
    511   DOMAIN_GOOGLE_SK,
    512   DOMAIN_GOOGLE_SM,
    513   DOMAIN_GOOGLE_SN,
    514   DOMAIN_GOOGLE_SO,
    515   DOMAIN_GOOGLE_ST,
    516   DOMAIN_GOOGLE_TD,
    517   DOMAIN_GOOGLE_TG,
    518   DOMAIN_GOOGLE_TK,
    519   DOMAIN_GOOGLE_TL,
    520   DOMAIN_GOOGLE_TM,
    521   DOMAIN_GOOGLE_TN,
    522   DOMAIN_GOOGLE_TO,
    523   DOMAIN_GOOGLE_TP,
    524   DOMAIN_GOOGLE_TT,
    525   DOMAIN_GOOGLE_US,
    526   DOMAIN_GOOGLE_UZ,
    527   DOMAIN_GOOGLE_VG,
    528   DOMAIN_GOOGLE_VU,
    529   DOMAIN_GOOGLE_WS,
    530 
    531   DOMAIN_CHROMIUM_ORG,
    532 
    533   DOMAIN_CRYPTO_CAT,
    534   DOMAIN_LAVABIT_COM,
    535 
    536   DOMAIN_GOOGLETAGMANAGER_COM,
    537   DOMAIN_GOOGLETAGSERVICES_COM,
    538 
    539   DOMAIN_DROPBOX_COM,
    540   DOMAIN_YOUTUBE_NOCOOKIE_COM,
    541   DOMAIN_2MDN_NET,
    542 
    543   // Boundary value for UMA_HISTOGRAM_ENUMERATION:
    544   DOMAIN_NUM_EVENTS
    545 };
    546 
    547 // PublicKeyPins contains a number of SubjectPublicKeyInfo hashes for a site.
    548 // The validated certificate chain for the site must not include any of
    549 // |excluded_hashes| and must include one or more of |required_hashes|.
    550 struct PublicKeyPins {
    551   const char* const* required_hashes;
    552   const char* const* excluded_hashes;
    553 };
    554 
    555 struct HSTSPreload {
    556   uint8 length;
    557   bool include_subdomains;
    558   char dns_name[38];
    559   bool https_required;
    560   PublicKeyPins pins;
    561   SecondLevelDomainName second_level_domain_name;
    562 };
    563 
    564 static bool HasPreload(const struct HSTSPreload* entries,
    565                        size_t num_entries,
    566                        const std::string& canonicalized_host,
    567                        size_t i,
    568                        bool enable_static_pins,
    569                        TransportSecurityState::DomainState* out,
    570                        bool* ret) {
    571   for (size_t j = 0; j < num_entries; j++) {
    572     if (entries[j].length == canonicalized_host.size() - i &&
    573         memcmp(entries[j].dns_name, &canonicalized_host[i],
    574                entries[j].length) == 0) {
    575       if (!entries[j].include_subdomains && i != 0) {
    576         *ret = false;
    577       } else {
    578         out->sts.include_subdomains = entries[j].include_subdomains;
    579         out->sts.last_observed = base::GetBuildTime();
    580         *ret = true;
    581         out->sts.upgrade_mode =
    582             TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
    583         if (!entries[j].https_required)
    584           out->sts.upgrade_mode =
    585               TransportSecurityState::DomainState::MODE_DEFAULT;
    586 
    587         if (enable_static_pins) {
    588           out->pkp.include_subdomains = entries[j].include_subdomains;
    589           out->pkp.last_observed = base::GetBuildTime();
    590           if (entries[j].pins.required_hashes) {
    591             const char* const* sha1_hash = entries[j].pins.required_hashes;
    592             while (*sha1_hash) {
    593               AddHash(*sha1_hash, &out->pkp.spki_hashes);
    594               sha1_hash++;
    595             }
    596           }
    597           if (entries[j].pins.excluded_hashes) {
    598             const char* const* sha1_hash = entries[j].pins.excluded_hashes;
    599             while (*sha1_hash) {
    600               AddHash(*sha1_hash, &out->pkp.bad_spki_hashes);
    601               sha1_hash++;
    602             }
    603           }
    604         }
    605       }
    606       return true;
    607     }
    608   }
    609   return false;
    610 }
    611 
    612 #include "net/http/transport_security_state_static.h"
    613 
    614 // Returns the HSTSPreload entry for the |canonicalized_host| in |entries|,
    615 // or NULL if there is none. Prefers exact hostname matches to those that
    616 // match only because HSTSPreload.include_subdomains is true.
    617 //
    618 // |canonicalized_host| should be the hostname as canonicalized by
    619 // CanonicalizeHost.
    620 static const struct HSTSPreload* GetHSTSPreload(
    621     const std::string& canonicalized_host,
    622     const struct HSTSPreload* entries,
    623     size_t num_entries) {
    624   for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
    625     for (size_t j = 0; j < num_entries; j++) {
    626       const struct HSTSPreload* entry = entries + j;
    627 
    628       if (i != 0 && !entry->include_subdomains)
    629         continue;
    630 
    631       if (entry->length == canonicalized_host.size() - i &&
    632           memcmp(entry->dns_name, &canonicalized_host[i], entry->length) == 0) {
    633         return entry;
    634       }
    635     }
    636   }
    637 
    638   return NULL;
    639 }
    640 
    641 bool TransportSecurityState::AddHSTSHeader(const std::string& host,
    642                                            const std::string& value) {
    643   DCHECK(CalledOnValidThread());
    644 
    645   base::Time now = base::Time::Now();
    646   base::TimeDelta max_age;
    647   TransportSecurityState::DomainState domain_state;
    648   GetDynamicDomainState(host, &domain_state);
    649   if (ParseHSTSHeader(value, &max_age, &domain_state.sts.include_subdomains)) {
    650     // Handle max-age == 0.
    651     if (max_age.InSeconds() == 0)
    652       domain_state.sts.upgrade_mode = DomainState::MODE_DEFAULT;
    653     else
    654       domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
    655     domain_state.sts.last_observed = now;
    656     domain_state.sts.expiry = now + max_age;
    657     EnableHost(host, domain_state);
    658     return true;
    659   }
    660   return false;
    661 }
    662 
    663 bool TransportSecurityState::AddHPKPHeader(const std::string& host,
    664                                            const std::string& value,
    665                                            const SSLInfo& ssl_info) {
    666   DCHECK(CalledOnValidThread());
    667 
    668   base::Time now = base::Time::Now();
    669   base::TimeDelta max_age;
    670   TransportSecurityState::DomainState domain_state;
    671   GetDynamicDomainState(host, &domain_state);
    672   if (ParseHPKPHeader(value,
    673                       ssl_info.public_key_hashes,
    674                       &max_age,
    675                       &domain_state.pkp.include_subdomains,
    676                       &domain_state.pkp.spki_hashes)) {
    677     // Handle max-age == 0.
    678     if (max_age.InSeconds() == 0)
    679       domain_state.pkp.spki_hashes.clear();
    680     domain_state.pkp.last_observed = now;
    681     domain_state.pkp.expiry = now + max_age;
    682     EnableHost(host, domain_state);
    683     return true;
    684   }
    685   return false;
    686 }
    687 
    688 bool TransportSecurityState::AddHSTS(const std::string& host,
    689                                      const base::Time& expiry,
    690                                      bool include_subdomains) {
    691   DCHECK(CalledOnValidThread());
    692 
    693   // Copy-and-modify the existing DomainState for this host (if any).
    694   TransportSecurityState::DomainState domain_state;
    695   const std::string canonicalized_host = CanonicalizeHost(host);
    696   const std::string hashed_host = HashHost(canonicalized_host);
    697   DomainStateMap::const_iterator i = enabled_hosts_.find(
    698       hashed_host);
    699   if (i != enabled_hosts_.end())
    700     domain_state = i->second;
    701 
    702   domain_state.sts.last_observed = base::Time::Now();
    703   domain_state.sts.include_subdomains = include_subdomains;
    704   domain_state.sts.expiry = expiry;
    705   domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
    706   EnableHost(host, domain_state);
    707   return true;
    708 }
    709 
    710 bool TransportSecurityState::AddHPKP(const std::string& host,
    711                                      const base::Time& expiry,
    712                                      bool include_subdomains,
    713                                      const HashValueVector& hashes) {
    714   DCHECK(CalledOnValidThread());
    715 
    716   // Copy-and-modify the existing DomainState for this host (if any).
    717   TransportSecurityState::DomainState domain_state;
    718   const std::string canonicalized_host = CanonicalizeHost(host);
    719   const std::string hashed_host = HashHost(canonicalized_host);
    720   DomainStateMap::const_iterator i = enabled_hosts_.find(
    721       hashed_host);
    722   if (i != enabled_hosts_.end())
    723     domain_state = i->second;
    724 
    725   domain_state.pkp.last_observed = base::Time::Now();
    726   domain_state.pkp.include_subdomains = include_subdomains;
    727   domain_state.pkp.expiry = expiry;
    728   domain_state.pkp.spki_hashes = hashes;
    729   EnableHost(host, domain_state);
    730   return true;
    731 }
    732 
    733 // static
    734 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) {
    735   std::string canonicalized_host = CanonicalizeHost(host);
    736   const struct HSTSPreload* entry =
    737       GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS);
    738 
    739   return entry && entry->pins.required_hashes == kGoogleAcceptableCerts;
    740 }
    741 
    742 // static
    743 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) {
    744   std::string canonicalized_host = CanonicalizeHost(host);
    745 
    746   const struct HSTSPreload* entry =
    747       GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS);
    748 
    749   if (!entry) {
    750     // We don't care to report pin failures for dynamic pins.
    751     return;
    752   }
    753 
    754   DCHECK(entry);
    755   DCHECK(entry->pins.required_hashes);
    756   DCHECK(entry->second_level_domain_name != DOMAIN_NOT_PINNED);
    757 
    758   UMA_HISTOGRAM_ENUMERATION("Net.PublicKeyPinFailureDomain",
    759                             entry->second_level_domain_name, DOMAIN_NUM_EVENTS);
    760 }
    761 
    762 // static
    763 bool TransportSecurityState::IsBuildTimely() {
    764   const base::Time build_time = base::GetBuildTime();
    765   // We consider built-in information to be timely for 10 weeks.
    766   return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
    767 }
    768 
    769 bool TransportSecurityState::CheckPublicKeyPinsImpl(
    770     const std::string& host,
    771     const HashValueVector& hashes,
    772     std::string* failure_log) {
    773   DomainState dynamic_state;
    774   if (GetDynamicDomainState(host, &dynamic_state))
    775     return dynamic_state.CheckPublicKeyPins(hashes, failure_log);
    776 
    777   DomainState static_state;
    778   if (GetStaticDomainState(host, &static_state))
    779     return static_state.CheckPublicKeyPins(hashes, failure_log);
    780 
    781   // HasPublicKeyPins should have returned true in order for this method
    782   // to have been called, so if we fall through to here, it's an error.
    783   return false;
    784 }
    785 
    786 bool TransportSecurityState::GetStaticDomainState(const std::string& host,
    787                                                   DomainState* out) const {
    788   DCHECK(CalledOnValidThread());
    789 
    790   const std::string canonicalized_host = CanonicalizeHost(host);
    791 
    792   out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
    793   out->sts.include_subdomains = false;
    794   out->pkp.include_subdomains = false;
    795 
    796   const bool is_build_timely = IsBuildTimely();
    797 
    798   for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
    799     std::string host_sub_chunk(&canonicalized_host[i],
    800                                canonicalized_host.size() - i);
    801     out->domain = DNSDomainToString(host_sub_chunk);
    802     bool ret;
    803     if (is_build_timely && HasPreload(kPreloadedSTS,
    804                                       kNumPreloadedSTS,
    805                                       canonicalized_host,
    806                                       i,
    807                                       enable_static_pins_,
    808                                       out,
    809                                       &ret)) {
    810       return ret;
    811     }
    812   }
    813 
    814   return false;
    815 }
    816 
    817 bool TransportSecurityState::GetDynamicDomainState(const std::string& host,
    818                                                    DomainState* result) {
    819   DCHECK(CalledOnValidThread());
    820 
    821   DomainState state;
    822   const std::string canonicalized_host = CanonicalizeHost(host);
    823   if (canonicalized_host.empty())
    824     return false;
    825 
    826   base::Time current_time(base::Time::Now());
    827 
    828   for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
    829     std::string host_sub_chunk(&canonicalized_host[i],
    830                                canonicalized_host.size() - i);
    831     DomainStateMap::iterator j =
    832         enabled_hosts_.find(HashHost(host_sub_chunk));
    833     if (j == enabled_hosts_.end())
    834       continue;
    835 
    836     if (current_time > j->second.sts.expiry &&
    837         current_time > j->second.pkp.expiry) {
    838       enabled_hosts_.erase(j);
    839       DirtyNotify();
    840       continue;
    841     }
    842 
    843     state = j->second;
    844     state.domain = DNSDomainToString(host_sub_chunk);
    845 
    846     // Succeed if we matched the domain exactly or if subdomain matches are
    847     // allowed.
    848     if (i == 0 || j->second.sts.include_subdomains ||
    849         j->second.pkp.include_subdomains) {
    850       *result = state;
    851       return true;
    852     }
    853 
    854     return false;
    855   }
    856 
    857   return false;
    858 }
    859 
    860 void TransportSecurityState::AddOrUpdateEnabledHosts(
    861     const std::string& hashed_host, const DomainState& state) {
    862   DCHECK(CalledOnValidThread());
    863   enabled_hosts_[hashed_host] = state;
    864 }
    865 
    866 TransportSecurityState::DomainState::DomainState() {
    867   sts.upgrade_mode = MODE_DEFAULT;
    868   sts.include_subdomains = false;
    869   pkp.include_subdomains = false;
    870 }
    871 
    872 TransportSecurityState::DomainState::~DomainState() {
    873 }
    874 
    875 bool TransportSecurityState::DomainState::CheckPublicKeyPins(
    876     const HashValueVector& hashes, std::string* failure_log) const {
    877   // Validate that hashes is not empty. By the time this code is called (in
    878   // production), that should never happen, but it's good to be defensive.
    879   // And, hashes *can* be empty in some test scenarios.
    880   if (hashes.empty()) {
    881     failure_log->append(
    882         "Rejecting empty public key chain for public-key-pinned domains: " +
    883         domain);
    884     return false;
    885   }
    886 
    887   if (HashesIntersect(pkp.bad_spki_hashes, hashes)) {
    888     failure_log->append("Rejecting public key chain for domain " + domain +
    889                         ". Validated chain: " + HashesToBase64String(hashes) +
    890                         ", matches one or more bad hashes: " +
    891                         HashesToBase64String(pkp.bad_spki_hashes));
    892     return false;
    893   }
    894 
    895   // If there are no pins, then any valid chain is acceptable.
    896   if (pkp.spki_hashes.empty())
    897     return true;
    898 
    899   if (HashesIntersect(pkp.spki_hashes, hashes)) {
    900     return true;
    901   }
    902 
    903   failure_log->append("Rejecting public key chain for domain " + domain +
    904                       ". Validated chain: " + HashesToBase64String(hashes) +
    905                       ", expected: " + HashesToBase64String(pkp.spki_hashes));
    906   return false;
    907 }
    908 
    909 bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const {
    910   return sts.upgrade_mode == MODE_FORCE_HTTPS;
    911 }
    912 
    913 bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const {
    914   return true;
    915 }
    916 
    917 bool TransportSecurityState::DomainState::HasPublicKeyPins() const {
    918   return pkp.spki_hashes.size() > 0 || pkp.bad_spki_hashes.size() > 0;
    919 }
    920 
    921 TransportSecurityState::DomainState::PKPState::PKPState() {
    922 }
    923 
    924 TransportSecurityState::DomainState::PKPState::~PKPState() {
    925 }
    926 
    927 }  // namespace
    928