Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(431)

Side by Side Diff: chrome/browser/ssl/ssl_blocking_page.cc

Issue 935663004: Add checkbox for reporting invalid TLS/SSL cert chains (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix comment typo Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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_blocking_page.h" 5 #include "chrome/browser/ssl/ssl_blocking_page.h"
6 6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
7 #include "base/build_time.h" 9 #include "base/build_time.h"
10 #include "base/callback_helpers.h"
8 #include "base/command_line.h" 11 #include "base/command_line.h"
9 #include "base/i18n/rtl.h" 12 #include "base/i18n/rtl.h"
10 #include "base/i18n/time_formatting.h" 13 #include "base/i18n/time_formatting.h"
11 #include "base/metrics/field_trial.h" 14 #include "base/metrics/field_trial.h"
12 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
16 #include "base/prefs/pref_service.h"
13 #include "base/process/launch.h" 17 #include "base/process/launch.h"
14 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_piece.h" 19 #include "base/strings/string_piece.h"
16 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h" 21 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
19 #include "base/time/time.h" 23 #include "base/time/time.h"
20 #include "base/values.h" 24 #include "base/values.h"
21 #include "chrome/browser/browser_process.h" 25 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/chrome_notification_types.h" 26 #include "chrome/browser/chrome_notification_types.h"
27 #include "chrome/browser/net/certificate_error_reporter.h"
23 #include "chrome/browser/profiles/profile.h" 28 #include "chrome/browser/profiles/profile.h"
29 #include "chrome/browser/profiles/profile_io_data.h"
24 #include "chrome/browser/renderer_preferences_util.h" 30 #include "chrome/browser/renderer_preferences_util.h"
25 #include "chrome/browser/ssl/ssl_error_classification.h" 31 #include "chrome/browser/ssl/ssl_error_classification.h"
26 #include "chrome/browser/ssl/ssl_error_info.h" 32 #include "chrome/browser/ssl/ssl_error_info.h"
27 #include "chrome/common/chrome_switches.h" 33 #include "chrome/common/chrome_switches.h"
34 #include "chrome/common/pref_names.h"
28 #include "chrome/grit/chromium_strings.h" 35 #include "chrome/grit/chromium_strings.h"
29 #include "chrome/grit/generated_resources.h" 36 #include "chrome/grit/generated_resources.h"
30 #include "components/google/core/browser/google_util.h" 37 #include "components/google/core/browser/google_util.h"
38 #include "content/public/browser/browser_thread.h"
31 #include "content/public/browser/cert_store.h" 39 #include "content/public/browser/cert_store.h"
32 #include "content/public/browser/interstitial_page.h" 40 #include "content/public/browser/interstitial_page.h"
33 #include "content/public/browser/interstitial_page_delegate.h" 41 #include "content/public/browser/interstitial_page_delegate.h"
34 #include "content/public/browser/navigation_controller.h" 42 #include "content/public/browser/navigation_controller.h"
35 #include "content/public/browser/navigation_entry.h" 43 #include "content/public/browser/navigation_entry.h"
36 #include "content/public/browser/notification_service.h" 44 #include "content/public/browser/notification_service.h"
37 #include "content/public/browser/notification_types.h" 45 #include "content/public/browser/notification_types.h"
38 #include "content/public/browser/render_process_host.h" 46 #include "content/public/browser/render_process_host.h"
39 #include "content/public/browser/render_view_host.h" 47 #include "content/public/browser/render_view_host.h"
40 #include "content/public/browser/web_contents.h" 48 #include "content/public/browser/web_contents.h"
(...skipping 17 matching lines...) Expand all
58 #endif 66 #endif
59 67
60 #if defined(OS_CHROMEOS) 68 #if defined(OS_CHROMEOS)
61 #include "chrome/browser/profiles/profile_manager.h" 69 #include "chrome/browser/profiles/profile_manager.h"
62 #include "chrome/browser/ui/chrome_pages.h" 70 #include "chrome/browser/ui/chrome_pages.h"
63 #include "chrome/common/url_constants.h" 71 #include "chrome/common/url_constants.h"
64 #endif 72 #endif
65 73
66 using base::ASCIIToUTF16; 74 using base::ASCIIToUTF16;
67 using base::TimeTicks; 75 using base::TimeTicks;
76 using chrome_browser_net::CertificateErrorReporter;
77 using content::BrowserThread;
68 using content::InterstitialPage; 78 using content::InterstitialPage;
69 using content::InterstitialPageDelegate; 79 using content::InterstitialPageDelegate;
70 using content::NavigationController; 80 using content::NavigationController;
71 using content::NavigationEntry; 81 using content::NavigationEntry;
72 82
73 namespace { 83 namespace {
74 84
75 // URL for help page. 85 // URL for help page.
76 const char kHelpURL[] = "https://support.google.com/chrome/answer/4454607"; 86 const char kHelpURL[] = "https://support.google.com/chrome/answer/4454607";
77 87
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 214
205 bool IsErrorDueToBadClock(const base::Time& now, int error) { 215 bool IsErrorDueToBadClock(const base::Time& now, int error) {
206 if (SSLErrorInfo::NetErrorToErrorType(error) != 216 if (SSLErrorInfo::NetErrorToErrorType(error) !=
207 SSLErrorInfo::CERT_DATE_INVALID) { 217 SSLErrorInfo::CERT_DATE_INVALID) {
208 return false; 218 return false;
209 } 219 }
210 return SSLErrorClassification::IsUserClockInThePast(now) || 220 return SSLErrorClassification::IsUserClockInThePast(now) ||
211 SSLErrorClassification::IsUserClockInTheFuture(now); 221 SSLErrorClassification::IsUserClockInTheFuture(now);
212 } 222 }
213 223
224 // A helper function that actually sends the cert collection report over
225 // the network.
226 void FinishCertCollectionInternal(
227 const base::WeakPtr<CertificateErrorReporter>& reporter,
228 const std::string& hostname,
229 const net::SSLInfo& ssl_info) {
230 DCHECK_CURRENTLY_ON(BrowserThread::IO);
231 if (reporter) {
232 reporter->SendReport(
233 CertificateErrorReporter::REPORT_TYPE_EXTENDED_REPORTING, hostname,
234 ssl_info);
235 }
236 }
237
214 } // namespace 238 } // namespace
215 239
216 // static 240 // static
217 InterstitialPageDelegate::TypeID SSLBlockingPage::kTypeForTesting = 241 InterstitialPageDelegate::TypeID SSLBlockingPage::kTypeForTesting =
218 &SSLBlockingPage::kTypeForTesting; 242 &SSLBlockingPage::kTypeForTesting;
219 243
220 // Note that we always create a navigation entry with SSL errors. 244 // Note that we always create a navigation entry with SSL errors.
221 // No error happening loading a sub-resource triggers an interstitial so far. 245 // No error happening loading a sub-resource triggers an interstitial so far.
222 SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents, 246 SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents,
223 int cert_error, 247 int cert_error,
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 load_time_data->SetString( 454 load_time_data->SetString(
431 "expirationDate", 455 "expirationDate",
432 base::TimeFormatShortDate(ssl_info_.cert->valid_expiry())); 456 base::TimeFormatShortDate(ssl_info_.cert->valid_expiry()));
433 load_time_data->SetString( 457 load_time_data->SetString(
434 "currentDate", base::TimeFormatShortDate(time_triggered_)); 458 "currentDate", base::TimeFormatShortDate(time_triggered_));
435 std::vector<std::string> encoded_chain; 459 std::vector<std::string> encoded_chain;
436 ssl_info_.cert->GetPEMEncodedChain( 460 ssl_info_.cert->GetPEMEncodedChain(
437 &encoded_chain); 461 &encoded_chain);
438 load_time_data->SetString( 462 load_time_data->SetString(
439 "pem", JoinString(encoded_chain, std::string())); 463 "pem", JoinString(encoded_chain, std::string()));
464
465 PopulateExtendedReportingOption(load_time_data);
466 }
467
468 void SSLBlockingPage::PopulateExtendedReportingOption(
469 base::DictionaryValue* load_time_data) {
470 // Only show the checkbox if not off-the-record and if the
471 // command-line option is set.
472 const bool show = !web_contents()->GetBrowserContext()->IsOffTheRecord() &&
473 base::CommandLine::ForCurrentProcess()->HasSwitch(
474 switches::kEnableInvalidCertCollection);
475
476 load_time_data->SetBoolean(interstitials::kDisplayCheckBox, show);
477 if (!show)
478 return;
479
480 load_time_data->SetBoolean(
481 interstitials::kBoxChecked,
482 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled));
483
484 const std::string privacy_link = base::StringPrintf(
485 interstitials::kPrivacyLinkHtml, CMD_OPEN_REPORTING_PRIVACY,
486 l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE).c_str());
487
488 load_time_data->SetString(
489 interstitials::kOptInLink,
490 l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_MALWARE_REPORTING_AGREE,
491 base::UTF8ToUTF16(privacy_link)));
440 } 492 }
441 493
442 void SSLBlockingPage::OverrideEntry(NavigationEntry* entry) { 494 void SSLBlockingPage::OverrideEntry(NavigationEntry* entry) {
443 int cert_id = content::CertStore::GetInstance()->StoreCert( 495 int cert_id = content::CertStore::GetInstance()->StoreCert(
444 ssl_info_.cert.get(), web_contents()->GetRenderProcessHost()->GetID()); 496 ssl_info_.cert.get(), web_contents()->GetRenderProcessHost()->GetID());
445 DCHECK(cert_id); 497 DCHECK(cert_id);
446 498
447 entry->GetSSL().security_style = 499 entry->GetSSL().security_style =
448 content::SECURITY_STYLE_AUTHENTICATION_BROKEN; 500 content::SECURITY_STYLE_AUTHENTICATION_BROKEN;
449 entry->GetSSL().cert_id = cert_id; 501 entry->GetSSL().cert_id = cert_id;
(...skipping 11 matching lines...) Expand all
461 case CMD_DONT_PROCEED: { 513 case CMD_DONT_PROCEED: {
462 interstitial_page()->DontProceed(); 514 interstitial_page()->DontProceed();
463 break; 515 break;
464 } 516 }
465 case CMD_PROCEED: { 517 case CMD_PROCEED: {
466 if (danger_overridable_) { 518 if (danger_overridable_) {
467 interstitial_page()->Proceed(); 519 interstitial_page()->Proceed();
468 } 520 }
469 break; 521 break;
470 } 522 }
523 case CMD_DO_REPORT: {
524 SetReportingPreference(true);
525 break;
526 }
527 case CMD_DONT_REPORT: {
528 SetReportingPreference(false);
529 break;
530 }
471 case CMD_SHOW_MORE_SECTION: { 531 case CMD_SHOW_MORE_SECTION: {
472 metrics_helper_->RecordUserInteraction( 532 metrics_helper_->RecordUserInteraction(
473 SecurityInterstitialMetricsHelper::SHOW_ADVANCED); 533 SecurityInterstitialMetricsHelper::SHOW_ADVANCED);
474 break; 534 break;
475 } 535 }
476 case CMD_OPEN_HELP_CENTER: { 536 case CMD_OPEN_HELP_CENTER: {
477 metrics_helper_->RecordUserInteraction( 537 metrics_helper_->RecordUserInteraction(
478 SecurityInterstitialMetricsHelper::SHOW_LEARN_MORE); 538 SecurityInterstitialMetricsHelper::SHOW_LEARN_MORE);
479 content::NavigationController::LoadURLParams help_page_params( 539 content::NavigationController::LoadURLParams help_page_params(
480 google_util::AppendGoogleLocaleParam( 540 google_util::AppendGoogleLocaleParam(
481 GURL(kHelpURL), g_browser_process->GetApplicationLocale())); 541 GURL(kHelpURL), g_browser_process->GetApplicationLocale()));
482 web_contents()->GetController().LoadURLWithParams(help_page_params); 542 web_contents()->GetController().LoadURLWithParams(help_page_params);
483 break; 543 break;
484 } 544 }
485 case CMD_RELOAD: { 545 case CMD_RELOAD: {
486 metrics_helper_->RecordUserInteraction( 546 metrics_helper_->RecordUserInteraction(
487 SecurityInterstitialMetricsHelper::RELOAD); 547 SecurityInterstitialMetricsHelper::RELOAD);
488 // The interstitial can't refresh itself. 548 // The interstitial can't refresh itself.
489 web_contents()->GetController().Reload(true); 549 web_contents()->GetController().Reload(true);
490 break; 550 break;
491 } 551 }
492 case CMD_OPEN_DATE_SETTINGS: { 552 case CMD_OPEN_DATE_SETTINGS: {
493 metrics_helper_->RecordUserInteraction( 553 metrics_helper_->RecordUserInteraction(
494 SecurityInterstitialMetricsHelper::OPEN_TIME_SETTINGS); 554 SecurityInterstitialMetricsHelper::OPEN_TIME_SETTINGS);
495 LaunchDateAndTimeSettings(); 555 LaunchDateAndTimeSettings();
496 break; 556 break;
497 } 557 }
558 case CMD_OPEN_REPORTING_PRIVACY:
559 metrics_helper_->RecordUserInteraction(
560 SecurityInterstitialMetricsHelper::SHOW_PRIVACY_POLICY);
561 OpenExtendedReportingPrivacyPolicy();
562 break;
498 case CMD_OPEN_DIAGNOSTIC: 563 case CMD_OPEN_DIAGNOSTIC:
499 // Google doesn't currently have a transparency report for SSL. 564 // Google doesn't currently have a transparency report for SSL.
500 case CMD_DO_REPORT:
501 case CMD_DONT_REPORT:
502 case CMD_OPEN_REPORTING_PRIVACY:
503 // Chrome doesn't currently do Extended Reporting for SSL.
504 NOTREACHED() << "Unexpected command: " << command; 565 NOTREACHED() << "Unexpected command: " << command;
505 } 566 }
506 } 567 }
507 568
508 void SSLBlockingPage::OverrideRendererPrefs( 569 void SSLBlockingPage::OverrideRendererPrefs(
509 content::RendererPreferences* prefs) { 570 content::RendererPreferences* prefs) {
510 Profile* profile = Profile::FromBrowserContext( 571 Profile* profile = Profile::FromBrowserContext(
511 web_contents()->GetBrowserContext()); 572 web_contents()->GetBrowserContext());
512 renderer_preferences_util::UpdateFromSystemSettings( 573 renderer_preferences_util::UpdateFromSystemSettings(
513 prefs, profile, web_contents()); 574 prefs, profile, web_contents());
514 } 575 }
515 576
516 void SSLBlockingPage::OnProceed() { 577 void SSLBlockingPage::OnProceed() {
517 metrics_helper_->RecordUserDecision( 578 metrics_helper_->RecordUserDecision(
518 SecurityInterstitialMetricsHelper::PROCEED); 579 SecurityInterstitialMetricsHelper::PROCEED);
580
581 // Finish collection information about invalid certificates, if the
582 // user opted in to.
583 FinishCertCollection();
584
519 RecordSSLExpirationPageEventState( 585 RecordSSLExpirationPageEventState(
520 expired_but_previously_allowed_, true, overridable_); 586 expired_but_previously_allowed_, true, overridable_);
521 // Accepting the certificate resumes the loading of the page. 587 // Accepting the certificate resumes the loading of the page.
522 NotifyAllowCertificate(); 588 NotifyAllowCertificate();
523 } 589 }
524 590
525 void SSLBlockingPage::OnDontProceed() { 591 void SSLBlockingPage::OnDontProceed() {
526 metrics_helper_->RecordUserDecision( 592 metrics_helper_->RecordUserDecision(
527 SecurityInterstitialMetricsHelper::DONT_PROCEED); 593 SecurityInterstitialMetricsHelper::DONT_PROCEED);
594
595 // Finish collection information about invalid certificates, if the
596 // user opted in to.
597 FinishCertCollection();
598
528 RecordSSLExpirationPageEventState( 599 RecordSSLExpirationPageEventState(
529 expired_but_previously_allowed_, false, overridable_); 600 expired_but_previously_allowed_, false, overridable_);
530 NotifyDenyCertificate(); 601 NotifyDenyCertificate();
531 } 602 }
532 603
533 void SSLBlockingPage::NotifyDenyCertificate() { 604 void SSLBlockingPage::NotifyDenyCertificate() {
534 // It's possible that callback_ may not exist if the user clicks "Proceed" 605 // It's possible that callback_ may not exist if the user clicks "Proceed"
535 // followed by pressing the back button before the interstitial is hidden. 606 // followed by pressing the back button before the interstitial is hidden.
536 // In that case the certificate will still be treated as allowed. 607 // In that case the certificate will still be treated as allowed.
537 if (callback_.is_null()) 608 if (callback_.is_null())
(...skipping 27 matching lines...) Expand all
565 std::string SSLBlockingPage::GetSamplingEventName() const { 636 std::string SSLBlockingPage::GetSamplingEventName() const {
566 std::string event_name(kEventNameBase); 637 std::string event_name(kEventNameBase);
567 if (overridable_) 638 if (overridable_)
568 event_name.append(kEventOverridable); 639 event_name.append(kEventOverridable);
569 else 640 else
570 event_name.append(kEventNotOverridable); 641 event_name.append(kEventNotOverridable);
571 event_name.append(net::ErrorToString(cert_error_)); 642 event_name.append(net::ErrorToString(cert_error_));
572 return event_name; 643 return event_name;
573 } 644 }
574 645
646 void SSLBlockingPage::FinishCertCollection() {
647 base::ScopedClosureRunner scoped_callback(
648 certificate_report_callback_for_testing_);
649
650 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
651 switches::kEnableInvalidCertCollection) ||
652 web_contents()->GetBrowserContext()->IsOffTheRecord()) {
653 return;
654 }
655
656 const bool enabled =
657 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled);
658 UMA_HISTOGRAM_BOOLEAN("SB2.ExtendedReportingIsEnabled", enabled);
659
660 if (!enabled)
661 return;
662
663 if (certificate_report_callback_for_testing_.is_null())
664 scoped_callback.Reset(base::Bind(&base::DoNothing));
665
666 base::WeakPtr<CertificateErrorReporter> reporter =
667 ProfileIOData::FromResourceContext(
668 web_contents()->GetBrowserContext()->GetResourceContext())
669 ->certificate_error_reporter();
670
671 BrowserThread::PostTaskAndReply(
672 BrowserThread::IO, FROM_HERE,
673 base::Bind(FinishCertCollectionInternal, reporter, request_url().host(),
674 ssl_info_),
675 scoped_callback.Release());
676 }
677
575 // static 678 // static
576 bool SSLBlockingPage::IsOptionsOverridable(int options_mask) { 679 bool SSLBlockingPage::IsOptionsOverridable(int options_mask) {
577 return (options_mask & SSLBlockingPage::OVERRIDABLE) && 680 return (options_mask & SSLBlockingPage::OVERRIDABLE) &&
578 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT); 681 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT);
579 } 682 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698