 Chromium Code Reviews
 Chromium Code Reviews Issue 433123003:
  Centralize the logic for checking public key pins  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 433123003:
  Centralize the logic for checking public key pins  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| Index: net/http/transport_security_state.cc | 
| diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc | 
| index 0b209b356e834dc7018bb0d9a743711b3e02cff5..b18087974a26672efa418cffdb643006376f526a 100644 | 
| --- a/net/http/transport_security_state.cc | 
| +++ b/net/http/transport_security_state.cc | 
| @@ -84,7 +84,13 @@ bool AddHash(const char* sha1_hash, | 
| } // namespace | 
| TransportSecurityState::TransportSecurityState() | 
| - : delegate_(NULL) { | 
| + : delegate_(NULL), | 
| + enable_static_pinning_(true) { | 
| + // Static pinning is only enabled for official builds to make sure that | 
| + // others don't end up with pins that cannot be easily updated. | 
| +#if !defined(OFFICIAL_BUILD) || defined(OS_ANDROID) || defined(OS_IOS) | 
| + enable_static_pinning_ = false; | 
| +#endif | 
| DCHECK(CalledOnValidThread()); | 
| } | 
| @@ -118,20 +124,53 @@ bool TransportSecurityState::ShouldUpgradeToSSL(const std::string& host, | 
| return false; | 
| } | 
| -bool TransportSecurityState::CheckPublicKeyPins(const std::string& host, | 
| - bool sni_enabled, | 
| - const HashValueVector& hashes, | 
| - std::string* failure_log) { | 
| +bool TransportSecurityState::CheckPublicKeyPins( | 
| + const std::string& host, | 
| + bool sni_available, | 
| + bool is_issued_by_known_root, | 
| + const HashValueVector& public_key_hashes, | 
| + std::string* pinning_failure_log) { | 
| + // Perform pin validation if, and only if, all these conditions obtain: | 
| + // | 
| + // * the server's certificate chain chains up to a known root (i.e. not a | 
| + // user-installed trust anchor); and | 
| + // * the build is recent (very old builds should fail open so that users | 
| + // have some chance to recover). | 
| + // | 
| + if (!is_issued_by_known_root || | 
| + !IsBuildTimely() || | 
| + !HasPublicKeyPins(host, sni_available)) { | 
| + return true; | 
| 
Ryan Sleevi
2014/08/07 23:31:19
Re-git-cl-format this?
 
Ryan Hamilton
2014/08/08 00:54:00
Done.
 | 
| + } | 
| + | 
| + bool pins_are_valid = CheckPublicKeyPinsImpl(host, | 
| + sni_available, | 
| + public_key_hashes, | 
| + pinning_failure_log); | 
| + if (!pins_are_valid) { | 
| + LOG(ERROR) << *pinning_failure_log; | 
| + ReportUMAOnPinFailure(host); | 
| + } | 
| + | 
| + UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid); | 
| + return pins_are_valid; | 
| +} | 
| + | 
| +bool TransportSecurityState::CheckPublicKeyPinsImpl( | 
| + const std::string& host, | 
| + bool sni_enabled, | 
| + const HashValueVector& hashes, | 
| + std::string* failure_log) { | 
| DomainState dynamic_state; | 
| if (GetDynamicDomainState(host, &dynamic_state)) | 
| return dynamic_state.CheckPublicKeyPins(hashes, failure_log); | 
| DomainState static_state; | 
| - if (GetStaticDomainState(host, sni_enabled, &static_state) && | 
| - static_state.CheckPublicKeyPins(hashes, failure_log)) { | 
| - return true; | 
| - } | 
| + if (GetStaticDomainState(host, sni_enabled, &static_state)) | 
| + return static_state.CheckPublicKeyPins(hashes, failure_log); | 
| + // HasPublicKeyPins should have returned true in order for this method | 
| + // to have been called, so if we fall through to here, it's an error. | 
| return false; | 
| } | 
| @@ -768,6 +807,9 @@ bool TransportSecurityState::GetStaticDomainState(const std::string& host, | 
| DomainState* out) const { | 
| DCHECK(CalledOnValidThread()); | 
| + if (!enable_static_pinning_) | 
| + return false; | 
| 
Ryan Sleevi
2014/08/07 23:31:19
Ugh and crap.
This breaks HSTS. And we didn't hav
 
Ryan Hamilton
2014/08/08 00:54:00
Done. (I hope :>)
 | 
| + | 
| const std::string canonicalized_host = CanonicalizeHost(host); | 
| out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS; |