1 // Copyright 2015 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.
5 #include "chrome/browser/ssl/certificate_reporting_test_utils.h"
8 #include "base/bind_helpers.h"
9 #include "base/metrics/field_trial.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/run_loop.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/safe_browsing/ping_manager.h"
16 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
17 #include "chrome/browser/safe_browsing/ui_manager.h"
18 #include "chrome/browser/ssl/cert_report_helper.h"
19 #include "chrome/browser/ssl/certificate_error_report.h"
20 #include "chrome/browser/ssl/ssl_cert_reporter.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/common/pref_names.h"
23 #include "components/variations/variations_associated_data.h"
24 #include "net/url_request/certificate_report_sender.h"
25 #include "net/url_request/url_request_context.h"
26 #include "testing/gtest/include/gtest/gtest.h"
29 using chrome_browser_net::CertificateErrorReporter
;
33 void SetMockReporter(SafeBrowsingService
* safe_browsing_service
,
34 scoped_ptr
<CertificateErrorReporter
> reporter
) {
35 safe_browsing_service
->ping_manager()->SetCertificateErrorReporterForTesting(
39 // This is a test implementation of the interface that blocking pages
40 // use to send certificate reports. It checks that the blocking page
41 // calls or does not call the report method when a report should or
42 // should not be sent, respectively.
43 class MockSSLCertReporter
: public SSLCertReporter
{
46 const scoped_refptr
<SafeBrowsingUIManager
>& safe_browsing_ui_manager
,
47 const base::Closure
& report_sent_callback
)
48 : safe_browsing_ui_manager_(safe_browsing_ui_manager
),
50 expect_report_(false),
51 report_sent_callback_(report_sent_callback
) {}
53 ~MockSSLCertReporter() override
{ EXPECT_EQ(expect_report_
, reported_
); }
55 // SSLCertReporter implementation.
56 void ReportInvalidCertificateChain(
57 const std::string
& serialized_report
) override
{
60 safe_browsing_ui_manager_
->ReportInvalidCertificateChain(
61 serialized_report
, report_sent_callback_
);
65 void set_expect_report(bool expect_report
) { expect_report_
= expect_report
; }
68 const scoped_refptr
<SafeBrowsingUIManager
> safe_browsing_ui_manager_
;
71 base::Closure report_sent_callback_
;
76 namespace certificate_reporting_test_utils
{
78 // This class is used to test invalid certificate chain reporting when
79 // the user opts in to do so on the interstitial. It keeps track of the
80 // most recent hostname for which an extended reporting report would
81 // have been sent over the network.
82 class CertificateReportingTest::MockReporter
83 : public chrome_browser_net::CertificateErrorReporter
{
86 net::URLRequestContext
* request_context
,
87 const GURL
& upload_url
,
88 net::CertificateReportSender::CookiesPreference cookies_preference
);
90 // CertificateErrorReporter implementation.
91 void SendExtendedReportingReport(
92 const std::string
& serialized_report
) override
;
94 // Returns the hostname in the report for the last call to
96 const std::string
& latest_hostname_reported() {
97 return latest_hostname_reported_
;
101 std::string latest_hostname_reported_
;
103 DISALLOW_COPY_AND_ASSIGN(MockReporter
);
106 CertificateReportingTest::MockReporter::MockReporter(
107 net::URLRequestContext
* request_context
,
108 const GURL
& upload_url
,
109 net::CertificateReportSender::CookiesPreference cookies_preference
)
110 : CertificateErrorReporter(request_context
,
112 cookies_preference
) {}
114 void CertificateReportingTest::MockReporter::SendExtendedReportingReport(
115 const std::string
& serialized_report
) {
116 CertificateErrorReport report
;
117 ASSERT_TRUE(report
.InitializeFromString(serialized_report
));
118 latest_hostname_reported_
= report
.hostname();
121 void CertificateReportingTest::SetUpMockReporter() {
122 // Set up the mock reporter to track the hostnames that reports get
123 // sent for. The request_context argument is null here
124 // because the MockReporter doesn't actually use a
125 // request_context. (In order to pass a real request_context, the
126 // reporter would have to be constructed on the IO thread.)
127 reporter_
= new CertificateReportingTest::MockReporter(
128 nullptr, GURL("http://example.test"),
129 net::CertificateReportSender::DO_NOT_SEND_COOKIES
);
131 scoped_refptr
<SafeBrowsingService
> safe_browsing_service
=
132 g_browser_process
->safe_browsing_service();
133 ASSERT_TRUE(safe_browsing_service
);
135 content::BrowserThread::PostTask(
136 content::BrowserThread::IO
, FROM_HERE
,
138 SetMockReporter
, safe_browsing_service
,
139 base::Passed(scoped_ptr
<CertificateErrorReporter
>(reporter_
))));
142 const std::string
& CertificateReportingTest::GetLatestHostnameReported() const {
143 return reporter_
->latest_hostname_reported();
146 void SetCertReportingOptIn(Browser
* browser
, OptIn opt_in
) {
147 browser
->profile()->GetPrefs()->SetBoolean(
148 prefs::kSafeBrowsingExtendedReportingEnabled
,
149 opt_in
== EXTENDED_REPORTING_OPT_IN
);
152 scoped_ptr
<SSLCertReporter
> SetUpMockSSLCertReporter(
153 base::RunLoop
* run_loop
,
154 ExpectReport expect_report
) {
155 // Set up a MockSSLCertReporter to keep track of when the blocking
156 // page invokes the cert reporter.
157 SafeBrowsingService
* sb_service
= g_browser_process
->safe_browsing_service();
158 EXPECT_TRUE(sb_service
);
162 scoped_ptr
<MockSSLCertReporter
> ssl_cert_reporter(new MockSSLCertReporter(
163 sb_service
->ui_manager(), expect_report
== CERT_REPORT_EXPECTED
164 ? run_loop
->QuitClosure()
165 : base::Bind(&base::DoNothing
)));
166 ssl_cert_reporter
->set_expect_report(expect_report
== CERT_REPORT_EXPECTED
);
167 return ssl_cert_reporter
.Pass();
170 ExpectReport
GetReportExpectedFromFinch() {
171 const std::string group_name
= base::FieldTrialList::FindFullName(
172 CertReportHelper::kFinchExperimentName
);
174 if (group_name
== CertReportHelper::kFinchGroupShowPossiblySend
) {
175 const std::string param
= variations::GetVariationParamValue(
176 CertReportHelper::kFinchExperimentName
,
177 CertReportHelper::kFinchParamName
);
178 double sendingThreshold
;
179 if (!base::StringToDouble(param
, &sendingThreshold
))
180 return CERT_REPORT_NOT_EXPECTED
;
182 if (sendingThreshold
== 1.0)
183 return certificate_reporting_test_utils::CERT_REPORT_EXPECTED
;
185 return certificate_reporting_test_utils::CERT_REPORT_NOT_EXPECTED
;
188 } // namespace certificate_reporting_test_utils