1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ssl/certificate_reporting_test_utils.h"
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/prefs/pref_service.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/ping_manager.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/safe_browsing/ui_manager.h"
#include "chrome/browser/ssl/cert_report_helper.h"
#include "chrome/browser/ssl/ssl_cert_reporter.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/pref_names.h"
#include "components/certificate_reporting/error_report.h"
#include "components/certificate_reporting/error_reporter.h"
#include "components/variations/variations_associated_data.h"
#include "net/url_request/certificate_report_sender.h"
#include "net/url_request/url_request_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
using safe_browsing::SafeBrowsingService;
using safe_browsing::SafeBrowsingUIManager;
namespace {
void SetMockReporter(
SafeBrowsingService* safe_browsing_service,
scoped_ptr<certificate_reporting::ErrorReporter> reporter) {
safe_browsing_service->ping_manager()->SetCertificateErrorReporterForTesting(
std::move(reporter));
}
// This is a test implementation of the interface that blocking pages
// use to send certificate reports. It checks that the blocking page
// calls or does not call the report method when a report should or
// should not be sent, respectively.
class MockSSLCertReporter : public SSLCertReporter {
public:
MockSSLCertReporter(
const scoped_refptr<SafeBrowsingUIManager>& safe_browsing_ui_manager,
const base::Closure& report_sent_callback)
: safe_browsing_ui_manager_(safe_browsing_ui_manager),
reported_(false),
expect_report_(false),
report_sent_callback_(report_sent_callback) {}
~MockSSLCertReporter() override { EXPECT_EQ(expect_report_, reported_); }
// SSLCertReporter implementation.
void ReportInvalidCertificateChain(
const std::string& serialized_report) override {
reported_ = true;
if (expect_report_) {
safe_browsing_ui_manager_->ReportInvalidCertificateChain(
serialized_report, report_sent_callback_);
}
}
void set_expect_report(bool expect_report) { expect_report_ = expect_report; }
private:
const scoped_refptr<SafeBrowsingUIManager> safe_browsing_ui_manager_;
bool reported_;
bool expect_report_;
base::Closure report_sent_callback_;
};
} // namespace
namespace certificate_reporting_test_utils {
// This class is used to test invalid certificate chain reporting when
// the user opts in to do so on the interstitial. It keeps track of the
// most recent hostname for which an extended reporting report would
// have been sent over the network.
class CertificateReportingTest::MockReporter
: public certificate_reporting::ErrorReporter {
public:
MockReporter(
net::URLRequestContext* request_context,
const GURL& upload_url,
net::CertificateReportSender::CookiesPreference cookies_preference);
// ErrorReporter implementation.
void SendExtendedReportingReport(
const std::string& serialized_report) override;
// Returns the hostname in the report for the last call to
// |SendReport|.
const std::string& latest_hostname_reported() {
return latest_hostname_reported_;
}
private:
std::string latest_hostname_reported_;
DISALLOW_COPY_AND_ASSIGN(MockReporter);
};
CertificateReportingTest::MockReporter::MockReporter(
net::URLRequestContext* request_context,
const GURL& upload_url,
net::CertificateReportSender::CookiesPreference cookies_preference)
: certificate_reporting::ErrorReporter(request_context,
upload_url,
cookies_preference) {}
void CertificateReportingTest::MockReporter::SendExtendedReportingReport(
const std::string& serialized_report) {
certificate_reporting::ErrorReport report;
ASSERT_TRUE(report.InitializeFromString(serialized_report));
latest_hostname_reported_ = report.hostname();
}
void CertificateReportingTest::SetUpMockReporter() {
// Set up the mock reporter to track the hostnames that reports get
// sent for. The request_context argument is null here
// because the MockReporter doesn't actually use a
// request_context. (In order to pass a real request_context, the
// reporter would have to be constructed on the IO thread.)
reporter_ = new CertificateReportingTest::MockReporter(
nullptr, GURL("http://example.test"),
net::CertificateReportSender::DO_NOT_SEND_COOKIES);
scoped_refptr<SafeBrowsingService> safe_browsing_service =
g_browser_process->safe_browsing_service();
ASSERT_TRUE(safe_browsing_service);
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(SetMockReporter, safe_browsing_service,
base::Passed(scoped_ptr<certificate_reporting::ErrorReporter>(
reporter_))));
}
const std::string& CertificateReportingTest::GetLatestHostnameReported() const {
return reporter_->latest_hostname_reported();
}
void SetCertReportingOptIn(Browser* browser, OptIn opt_in) {
browser->profile()->GetPrefs()->SetBoolean(
prefs::kSafeBrowsingExtendedReportingEnabled,
opt_in == EXTENDED_REPORTING_OPT_IN);
}
scoped_ptr<SSLCertReporter> SetUpMockSSLCertReporter(
base::RunLoop* run_loop,
ExpectReport expect_report) {
// Set up a MockSSLCertReporter to keep track of when the blocking
// page invokes the cert reporter.
SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
EXPECT_TRUE(sb_service);
if (!sb_service)
return nullptr;
scoped_ptr<MockSSLCertReporter> ssl_cert_reporter(new MockSSLCertReporter(
sb_service->ui_manager(), expect_report == CERT_REPORT_EXPECTED
? run_loop->QuitClosure()
: base::Bind(&base::DoNothing)));
ssl_cert_reporter->set_expect_report(expect_report == CERT_REPORT_EXPECTED);
return std::move(ssl_cert_reporter);
}
ExpectReport GetReportExpectedFromFinch() {
const std::string group_name = base::FieldTrialList::FindFullName(
CertReportHelper::kFinchExperimentName);
if (group_name == CertReportHelper::kFinchGroupShowPossiblySend) {
const std::string param = variations::GetVariationParamValue(
CertReportHelper::kFinchExperimentName,
CertReportHelper::kFinchParamName);
double sendingThreshold;
if (!base::StringToDouble(param, &sendingThreshold))
return CERT_REPORT_NOT_EXPECTED;
if (sendingThreshold == 1.0)
return certificate_reporting_test_utils::CERT_REPORT_EXPECTED;
}
return certificate_reporting_test_utils::CERT_REPORT_NOT_EXPECTED;
}
} // namespace certificate_reporting_test_utils
|