Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ssl/ssl_error_handler.h" | 5 #include "chrome/browser/ssl/ssl_error_handler.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <unordered_set> | 8 #include <unordered_set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 UMA_HISTOGRAM_ENUMERATION(kHistogram, event, | 132 UMA_HISTOGRAM_ENUMERATION(kHistogram, event, |
| 133 SSLErrorHandler::SSL_ERROR_HANDLER_EVENT_COUNT); | 133 SSLErrorHandler::SSL_ERROR_HANDLER_EVENT_COUNT); |
| 134 } | 134 } |
| 135 | 135 |
| 136 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) | 136 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 137 bool IsCaptivePortalInterstitialEnabled() { | 137 bool IsCaptivePortalInterstitialEnabled() { |
| 138 return base::FeatureList::IsEnabled(kCaptivePortalInterstitial); | 138 return base::FeatureList::IsEnabled(kCaptivePortalInterstitial); |
| 139 } | 139 } |
| 140 | 140 |
| 141 // Reads the SSL error assistant configuration from the resource bundle. | 141 // Reads the SSL error assistant configuration from the resource bundle. |
| 142 bool ReadErrorAssistantProtoFromResourceBundle( | 142 std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> |
| 143 chrome_browser_ssl::SSLErrorAssistantConfig* proto) { | 143 ReadErrorAssistantProtoFromResourceBundle() { |
| 144 auto proto = base::MakeUnique<chrome_browser_ssl::SSLErrorAssistantConfig>(); | |
| 144 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 145 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 145 DCHECK(proto); | 146 DCHECK(proto); |
| 146 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | 147 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
| 147 base::StringPiece data = | 148 base::StringPiece data = |
| 148 bundle.GetRawDataResource(IDR_SSL_ERROR_ASSISTANT_PB); | 149 bundle.GetRawDataResource(IDR_SSL_ERROR_ASSISTANT_PB); |
| 149 google::protobuf::io::ArrayInputStream stream(data.data(), data.size()); | 150 google::protobuf::io::ArrayInputStream stream(data.data(), data.size()); |
| 150 return proto->ParseFromZeroCopyStream(&stream); | 151 return proto->ParseFromZeroCopyStream(&stream) ? std::move(proto) : nullptr; |
| 151 } | 152 } |
| 152 | 153 |
| 153 std::unique_ptr<std::unordered_set<std::string>> LoadCaptivePortalCertHashes( | 154 std::unique_ptr<std::unordered_set<std::string>> LoadCaptivePortalCertHashes( |
| 154 const chrome_browser_ssl::SSLErrorAssistantConfig& proto) { | 155 const chrome_browser_ssl::SSLErrorAssistantConfig& proto) { |
| 155 auto hashes = base::MakeUnique<std::unordered_set<std::string>>(); | 156 auto hashes = base::MakeUnique<std::unordered_set<std::string>>(); |
| 156 for (const chrome_browser_ssl::CaptivePortalCert& cert : | 157 for (const chrome_browser_ssl::CaptivePortalCert& cert : |
| 157 proto.captive_portal_cert()) { | 158 proto.captive_portal_cert()) { |
| 158 hashes.get()->insert(cert.sha256_hash()); | 159 hashes.get()->insert(cert.sha256_hash()); |
| 159 } | 160 } |
| 160 return hashes; | 161 return hashes; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 185 // Testing methods: | 186 // Testing methods: |
| 186 void ResetForTesting(); | 187 void ResetForTesting(); |
| 187 void SetInterstitialDelayForTesting(const base::TimeDelta& delay); | 188 void SetInterstitialDelayForTesting(const base::TimeDelta& delay); |
| 188 void SetTimerStartedCallbackForTesting( | 189 void SetTimerStartedCallbackForTesting( |
| 189 SSLErrorHandler::TimerStartedCallback* callback); | 190 SSLErrorHandler::TimerStartedCallback* callback); |
| 190 void SetClockForTesting(base::Clock* clock); | 191 void SetClockForTesting(base::Clock* clock); |
| 191 void SetNetworkTimeTrackerForTesting( | 192 void SetNetworkTimeTrackerForTesting( |
| 192 network_time::NetworkTimeTracker* tracker); | 193 network_time::NetworkTimeTracker* tracker); |
| 193 | 194 |
| 194 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) | 195 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 195 void SetErrorAssistantProtoForTesting( | 196 void SetErrorAssistantProto( |
| 196 const chrome_browser_ssl::SSLErrorAssistantConfig& error_assistant_proto); | 197 std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> |
| 198 error_assistant_proto); | |
| 197 #endif | 199 #endif |
| 198 | 200 |
| 199 private: | 201 private: |
| 200 base::TimeDelta interstitial_delay_; | 202 base::TimeDelta interstitial_delay_; |
| 201 | 203 |
| 202 // Callback to call when the interstitial timer is started. Used for | 204 // Callback to call when the interstitial timer is started. Used for |
| 203 // testing. | 205 // testing. |
| 204 SSLErrorHandler::TimerStartedCallback* timer_started_callback_ = nullptr; | 206 SSLErrorHandler::TimerStartedCallback* timer_started_callback_ = nullptr; |
| 205 | 207 |
| 206 // The clock to use when deciding which error type to display. Used for | 208 // The clock to use when deciding which error type to display. Used for |
| 207 // testing. | 209 // testing. |
| 208 base::Clock* testing_clock_ = nullptr; | 210 base::Clock* testing_clock_ = nullptr; |
| 209 | 211 |
| 210 network_time::NetworkTimeTracker* network_time_tracker_ = nullptr; | 212 network_time::NetworkTimeTracker* network_time_tracker_ = nullptr; |
| 211 | 213 |
| 212 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) | 214 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 215 // Error assistant configuration. | |
| 216 std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> | |
| 217 error_assistant_proto_; | |
| 218 | |
| 213 // SPKI hashes belonging to certs treated as captive portals. Null until the | 219 // SPKI hashes belonging to certs treated as captive portals. Null until the |
| 214 // first time IsKnownCaptivePortalCert() or SetErrorAssistantProtoForTesting() | 220 // first time IsKnownCaptivePortalCert() or SetErrorAssistantProto() |
| 215 // is called. | 221 // is called. |
| 216 std::unique_ptr<std::unordered_set<std::string>> captive_portal_spki_hashes_; | 222 std::unique_ptr<std::unordered_set<std::string>> captive_portal_spki_hashes_; |
| 217 #endif | 223 #endif |
| 218 }; | 224 }; |
| 219 | 225 |
| 220 ConfigSingleton::ConfigSingleton() | 226 ConfigSingleton::ConfigSingleton() |
| 221 : interstitial_delay_( | 227 : interstitial_delay_( |
| 222 base::TimeDelta::FromMilliseconds(kInterstitialDelayInMilliseconds)) { | 228 base::TimeDelta::FromMilliseconds(kInterstitialDelayInMilliseconds)) { |
| 223 } | 229 } |
| 224 | 230 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 241 return testing_clock_; | 247 return testing_clock_; |
| 242 } | 248 } |
| 243 | 249 |
| 244 void ConfigSingleton::ResetForTesting() { | 250 void ConfigSingleton::ResetForTesting() { |
| 245 interstitial_delay_ = | 251 interstitial_delay_ = |
| 246 base::TimeDelta::FromMilliseconds(kInterstitialDelayInMilliseconds); | 252 base::TimeDelta::FromMilliseconds(kInterstitialDelayInMilliseconds); |
| 247 timer_started_callback_ = nullptr; | 253 timer_started_callback_ = nullptr; |
| 248 network_time_tracker_ = nullptr; | 254 network_time_tracker_ = nullptr; |
| 249 testing_clock_ = nullptr; | 255 testing_clock_ = nullptr; |
| 250 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) | 256 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 257 error_assistant_proto_.reset(); | |
| 251 captive_portal_spki_hashes_.reset(); | 258 captive_portal_spki_hashes_.reset(); |
| 252 #endif | 259 #endif |
| 253 } | 260 } |
| 254 | 261 |
| 255 void ConfigSingleton::SetInterstitialDelayForTesting( | 262 void ConfigSingleton::SetInterstitialDelayForTesting( |
| 256 const base::TimeDelta& delay) { | 263 const base::TimeDelta& delay) { |
| 257 interstitial_delay_ = delay; | 264 interstitial_delay_ = delay; |
| 258 } | 265 } |
| 259 | 266 |
| 260 void ConfigSingleton::SetTimerStartedCallbackForTesting( | 267 void ConfigSingleton::SetTimerStartedCallbackForTesting( |
| 261 SSLErrorHandler::TimerStartedCallback* callback) { | 268 SSLErrorHandler::TimerStartedCallback* callback) { |
| 262 DCHECK(!callback || !callback->is_null()); | 269 DCHECK(!callback || !callback->is_null()); |
| 263 timer_started_callback_ = callback; | 270 timer_started_callback_ = callback; |
| 264 } | 271 } |
| 265 | 272 |
| 266 void ConfigSingleton::SetClockForTesting(base::Clock* clock) { | 273 void ConfigSingleton::SetClockForTesting(base::Clock* clock) { |
| 267 testing_clock_ = clock; | 274 testing_clock_ = clock; |
| 268 } | 275 } |
| 269 | 276 |
| 270 void ConfigSingleton::SetNetworkTimeTrackerForTesting( | 277 void ConfigSingleton::SetNetworkTimeTrackerForTesting( |
| 271 network_time::NetworkTimeTracker* tracker) { | 278 network_time::NetworkTimeTracker* tracker) { |
| 272 network_time_tracker_ = tracker; | 279 network_time_tracker_ = tracker; |
| 273 } | 280 } |
| 274 | 281 |
| 275 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) | 282 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 276 void ConfigSingleton::SetErrorAssistantProtoForTesting( | 283 void ConfigSingleton::SetErrorAssistantProto( |
| 277 const chrome_browser_ssl::SSLErrorAssistantConfig& error_assistant_proto) { | 284 std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> proto) { |
| 278 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 285 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 279 DCHECK(!captive_portal_spki_hashes_); | 286 CHECK(proto); |
|
estark
2017/02/08 20:31:17
Why is this a CHECK instead of a DCHECK? (probably
meacer
2017/02/08 22:34:32
If it's null, it's going to crash a couple of line
| |
| 287 // Ignore versions that are not new. | |
| 288 if (error_assistant_proto_ && | |
| 289 proto->version_id() <= error_assistant_proto_->version_id()) { | |
| 290 return; | |
| 291 } | |
| 292 error_assistant_proto_ = std::move(proto); | |
| 280 captive_portal_spki_hashes_ = | 293 captive_portal_spki_hashes_ = |
| 281 LoadCaptivePortalCertHashes(error_assistant_proto); | 294 LoadCaptivePortalCertHashes(*error_assistant_proto_); |
| 282 } | 295 } |
| 283 | 296 |
| 284 bool ConfigSingleton::IsKnownCaptivePortalCert(const net::SSLInfo& ssl_info) { | 297 bool ConfigSingleton::IsKnownCaptivePortalCert(const net::SSLInfo& ssl_info) { |
| 285 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 298 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 286 if (!captive_portal_spki_hashes_) { | 299 if (!captive_portal_spki_hashes_) { |
| 287 chrome_browser_ssl::SSLErrorAssistantConfig proto; | 300 error_assistant_proto_ = ReadErrorAssistantProtoFromResourceBundle(); |
| 288 CHECK(ReadErrorAssistantProtoFromResourceBundle(&proto)); | 301 CHECK(error_assistant_proto_); |
| 289 captive_portal_spki_hashes_ = LoadCaptivePortalCertHashes(proto); | 302 captive_portal_spki_hashes_ = |
| 303 LoadCaptivePortalCertHashes(*error_assistant_proto_); | |
| 290 } | 304 } |
| 291 | 305 |
| 292 for (const net::HashValue& hash_value : ssl_info.public_key_hashes) { | 306 for (const net::HashValue& hash_value : ssl_info.public_key_hashes) { |
| 293 if (hash_value.tag != net::HASH_VALUE_SHA256) { | 307 if (hash_value.tag != net::HASH_VALUE_SHA256) { |
| 294 continue; | 308 continue; |
| 295 } | 309 } |
| 296 if (captive_portal_spki_hashes_->find(hash_value.ToString()) != | 310 if (captive_portal_spki_hashes_->find(hash_value.ToString()) != |
| 297 captive_portal_spki_hashes_->end()) { | 311 captive_portal_spki_hashes_->end()) { |
| 298 return true; | 312 return true; |
| 299 } | 313 } |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 489 | 503 |
| 490 // static | 504 // static |
| 491 std::string SSLErrorHandler::GetHistogramNameForTesting() { | 505 std::string SSLErrorHandler::GetHistogramNameForTesting() { |
| 492 return kHistogram; | 506 return kHistogram; |
| 493 } | 507 } |
| 494 | 508 |
| 495 bool SSLErrorHandler::IsTimerRunningForTesting() const { | 509 bool SSLErrorHandler::IsTimerRunningForTesting() const { |
| 496 return timer_.IsRunning(); | 510 return timer_.IsRunning(); |
| 497 } | 511 } |
| 498 | 512 |
| 499 void SSLErrorHandler::SetErrorAssistantProtoForTesting( | 513 void SSLErrorHandler::SetErrorAssistantProto( |
| 500 const chrome_browser_ssl::SSLErrorAssistantConfig& config_proto) { | 514 std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> config_proto) { |
| 501 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) | 515 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 502 g_config.Pointer()->SetErrorAssistantProtoForTesting(config_proto); | 516 g_config.Pointer()->SetErrorAssistantProto(std::move(config_proto)); |
| 503 #endif | 517 #endif |
| 504 } | 518 } |
| 505 | 519 |
| 506 SSLErrorHandler::SSLErrorHandler( | 520 SSLErrorHandler::SSLErrorHandler( |
| 507 std::unique_ptr<Delegate> delegate, | 521 std::unique_ptr<Delegate> delegate, |
| 508 content::WebContents* web_contents, | 522 content::WebContents* web_contents, |
| 509 Profile* profile, | 523 Profile* profile, |
| 510 int cert_error, | 524 int cert_error, |
| 511 const net::SSLInfo& ssl_info, | 525 const net::SSLInfo& ssl_info, |
| 512 const GURL& request_url, | 526 const GURL& request_url, |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 746 network_time::NetworkTimeTracker* tracker = | 760 network_time::NetworkTimeTracker* tracker = |
| 747 g_config.Pointer()->network_time_tracker(); | 761 g_config.Pointer()->network_time_tracker(); |
| 748 ssl_errors::ClockState clock_state = ssl_errors::GetClockState(now, tracker); | 762 ssl_errors::ClockState clock_state = ssl_errors::GetClockState(now, tracker); |
| 749 if (clock_state == ssl_errors::CLOCK_STATE_FUTURE || | 763 if (clock_state == ssl_errors::CLOCK_STATE_FUTURE || |
| 750 clock_state == ssl_errors::CLOCK_STATE_PAST) { | 764 clock_state == ssl_errors::CLOCK_STATE_PAST) { |
| 751 ShowBadClockInterstitial(now, clock_state); | 765 ShowBadClockInterstitial(now, clock_state); |
| 752 return; // |this| is deleted after showing the interstitial. | 766 return; // |this| is deleted after showing the interstitial. |
| 753 } | 767 } |
| 754 ShowSSLInterstitial(); | 768 ShowSSLInterstitial(); |
| 755 } | 769 } |
| OLD | NEW |