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

Side by Side Diff: components/security_state/security_state_model_unittest.cc

Issue 2448943002: Refactor SecurityStateModel/Clients for simplicity and reusability. (Closed)
Patch Set: update comments. Created 4 years, 1 month 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
(Empty)
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.
4
5 #include "components/security_state/security_state_model.h"
6
7 #include <stdint.h>
8
9 #include "base/command_line.h"
10 #include "base/test/histogram_tester.h"
11 #include "components/security_state/security_state_model_client.h"
12 #include "components/security_state/switches.h"
13 #include "net/cert/x509_certificate.h"
14 #include "net/ssl/ssl_cipher_suite_names.h"
15 #include "net/ssl/ssl_connection_status_flags.h"
16 #include "net/test/cert_test_util.h"
17 #include "net/test/test_certificate_data.h"
18 #include "net/test/test_data_directory.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace security_state {
22
23 namespace {
24
25 const char kHttpsUrl[] = "https://foo.test";
26 const char kHttpUrl[] = "http://foo.test";
27
28 class TestSecurityStateModelClient : public SecurityStateModelClient {
29 public:
30 TestSecurityStateModelClient()
31 : url_(kHttpsUrl),
32 connection_status_(net::SSL_CONNECTION_VERSION_TLS1_2
33 << net::SSL_CONNECTION_VERSION_SHIFT),
34 cert_status_(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT),
35 displayed_mixed_content_(false),
36 ran_mixed_content_(false),
37 fails_malware_check_(false),
38 displayed_password_field_on_http_(false),
39 displayed_credit_card_field_on_http_(false) {
40 cert_ =
41 net::ImportCertFromFile(net::GetTestCertsDirectory(), "sha1_2016.pem");
42 }
43 ~TestSecurityStateModelClient() override {}
44
45 void set_connection_status(int connection_status) {
46 connection_status_ = connection_status;
47 }
48 void SetCipherSuite(uint16_t ciphersuite) {
49 net::SSLConnectionStatusSetCipherSuite(ciphersuite, &connection_status_);
50 }
51 void AddCertStatus(net::CertStatus cert_status) {
52 cert_status_ |= cert_status;
53 }
54 void SetDisplayedMixedContent(bool displayed_mixed_content) {
55 displayed_mixed_content_ = displayed_mixed_content;
56 }
57 void SetRanMixedContent(bool ran_mixed_content) {
58 ran_mixed_content_ = ran_mixed_content;
59 }
60 void set_fails_malware_check(bool fails_malware_check) {
61 fails_malware_check_ = fails_malware_check;
62 }
63 void set_displayed_password_field_on_http(
64 bool displayed_password_field_on_http) {
65 displayed_password_field_on_http_ = displayed_password_field_on_http;
66 }
67 void set_displayed_credit_card_field_on_http(
68 bool displayed_credit_card_field_on_http) {
69 displayed_credit_card_field_on_http_ = displayed_credit_card_field_on_http;
70 }
71
72 void UseHttpUrl() { url_ = GURL(kHttpUrl); }
73
74 // SecurityStateModelClient:
75 void GetVisibleSecurityState(
76 SecurityStateModel::VisibleSecurityState* state) override {
77 state->connection_info_initialized = true;
78 state->url = url_;
79 state->certificate = cert_;
80 state->cert_status = cert_status_;
81 state->connection_status = connection_status_;
82 state->security_bits = 256;
83 state->displayed_mixed_content = displayed_mixed_content_;
84 state->ran_mixed_content = ran_mixed_content_;
85 state->fails_malware_check = fails_malware_check_;
86 state->displayed_password_field_on_http = displayed_password_field_on_http_;
87 state->displayed_credit_card_field_on_http =
88 displayed_credit_card_field_on_http_;
89 }
90
91 bool UsedPolicyInstalledCertificate() override { return false; }
92
93 bool IsOriginSecure(const GURL& url) override {
94 return url_ == GURL(kHttpsUrl);
95 }
96
97 private:
98 GURL url_;
99 scoped_refptr<net::X509Certificate> cert_;
100 int connection_status_;
101 net::CertStatus cert_status_;
102 bool displayed_mixed_content_;
103 bool ran_mixed_content_;
104 bool fails_malware_check_;
105 bool displayed_password_field_on_http_;
106 bool displayed_credit_card_field_on_http_;
107 };
108
109 // Tests that SHA1-signed certificates expiring in 2016 downgrade the
110 // security state of the page.
111 TEST(SecurityStateModelTest, SHA1Warning) {
112 TestSecurityStateModelClient client;
113 SecurityStateModel model;
114 model.SetClient(&client);
115 SecurityStateModel::SecurityInfo security_info;
116 model.GetSecurityInfo(&security_info);
117 EXPECT_EQ(SecurityStateModel::DEPRECATED_SHA1_MINOR,
118 security_info.sha1_deprecation_status);
119 EXPECT_EQ(SecurityStateModel::NONE, security_info.security_level);
120 }
121
122 // Tests that SHA1 warnings don't interfere with the handling of mixed
123 // content.
124 TEST(SecurityStateModelTest, SHA1WarningMixedContent) {
125 TestSecurityStateModelClient client;
126 SecurityStateModel model;
127 model.SetClient(&client);
128 client.SetDisplayedMixedContent(true);
129 SecurityStateModel::SecurityInfo security_info1;
130 model.GetSecurityInfo(&security_info1);
131 EXPECT_EQ(SecurityStateModel::DEPRECATED_SHA1_MINOR,
132 security_info1.sha1_deprecation_status);
133 EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_DISPLAYED,
134 security_info1.mixed_content_status);
135 EXPECT_EQ(SecurityStateModel::NONE, security_info1.security_level);
136
137 client.SetDisplayedMixedContent(false);
138 client.SetRanMixedContent(true);
139 SecurityStateModel::SecurityInfo security_info2;
140 model.GetSecurityInfo(&security_info2);
141 EXPECT_EQ(SecurityStateModel::DEPRECATED_SHA1_MINOR,
142 security_info2.sha1_deprecation_status);
143 EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_RAN,
144 security_info2.mixed_content_status);
145 EXPECT_EQ(SecurityStateModel::DANGEROUS, security_info2.security_level);
146 }
147
148 // Tests that SHA1 warnings don't interfere with the handling of major
149 // cert errors.
150 TEST(SecurityStateModelTest, SHA1WarningBrokenHTTPS) {
151 TestSecurityStateModelClient client;
152 SecurityStateModel model;
153 model.SetClient(&client);
154 client.AddCertStatus(net::CERT_STATUS_DATE_INVALID);
155 SecurityStateModel::SecurityInfo security_info;
156 model.GetSecurityInfo(&security_info);
157 EXPECT_EQ(SecurityStateModel::DEPRECATED_SHA1_MINOR,
158 security_info.sha1_deprecation_status);
159 EXPECT_EQ(SecurityStateModel::DANGEROUS, security_info.security_level);
160 }
161
162 // Tests that |security_info.is_secure_protocol_and_ciphersuite| is
163 // computed correctly.
164 TEST(SecurityStateModelTest, SecureProtocolAndCiphersuite) {
165 TestSecurityStateModelClient client;
166 SecurityStateModel model;
167 model.SetClient(&client);
168 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 from
169 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-param eters-4
170 const uint16_t ciphersuite = 0xc02f;
171 client.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_2
172 << net::SSL_CONNECTION_VERSION_SHIFT);
173 client.SetCipherSuite(ciphersuite);
174 SecurityStateModel::SecurityInfo security_info;
175 model.GetSecurityInfo(&security_info);
176 EXPECT_EQ(net::OBSOLETE_SSL_NONE, security_info.obsolete_ssl_status);
177 }
178
179 TEST(SecurityStateModelTest, NonsecureProtocol) {
180 TestSecurityStateModelClient client;
181 SecurityStateModel model;
182 model.SetClient(&client);
183 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 from
184 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-param eters-4
185 const uint16_t ciphersuite = 0xc02f;
186 client.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_1
187 << net::SSL_CONNECTION_VERSION_SHIFT);
188 client.SetCipherSuite(ciphersuite);
189 SecurityStateModel::SecurityInfo security_info;
190 model.GetSecurityInfo(&security_info);
191 EXPECT_EQ(net::OBSOLETE_SSL_MASK_PROTOCOL, security_info.obsolete_ssl_status);
192 }
193
194 TEST(SecurityStateModelTest, NonsecureCiphersuite) {
195 TestSecurityStateModelClient client;
196 SecurityStateModel model;
197 model.SetClient(&client);
198 // TLS_RSA_WITH_AES_128_CCM_8 from
199 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-param eters-4
200 const uint16_t ciphersuite = 0xc0a0;
201 client.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_2
202 << net::SSL_CONNECTION_VERSION_SHIFT);
203 client.SetCipherSuite(ciphersuite);
204 SecurityStateModel::SecurityInfo security_info;
205 model.GetSecurityInfo(&security_info);
206 EXPECT_EQ(net::OBSOLETE_SSL_MASK_KEY_EXCHANGE | net::OBSOLETE_SSL_MASK_CIPHER,
207 security_info.obsolete_ssl_status);
208 }
209
210 // Tests that the malware/phishing status is set, and it overrides valid HTTPS.
211 TEST(SecurityStateModelTest, MalwareOverride) {
212 TestSecurityStateModelClient client;
213 SecurityStateModel model;
214 model.SetClient(&client);
215 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 from
216 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-param eters-4
217 const uint16_t ciphersuite = 0xc02f;
218 client.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_2
219 << net::SSL_CONNECTION_VERSION_SHIFT);
220 client.SetCipherSuite(ciphersuite);
221 client.set_fails_malware_check(true);
222 SecurityStateModel::SecurityInfo security_info;
223 model.GetSecurityInfo(&security_info);
224 EXPECT_TRUE(security_info.fails_malware_check);
225 EXPECT_EQ(SecurityStateModel::DANGEROUS, security_info.security_level);
226 }
227
228 // Tests that the malware/phishing status is set, even if other connection info
229 // is not available.
230 TEST(SecurityStateModelTest, MalwareWithoutCOnnectionState) {
231 TestSecurityStateModelClient client;
232 SecurityStateModel model;
233 model.SetClient(&client);
234 client.set_fails_malware_check(true);
235 SecurityStateModel::SecurityInfo security_info;
236 model.GetSecurityInfo(&security_info);
237 EXPECT_TRUE(security_info.fails_malware_check);
238 EXPECT_EQ(SecurityStateModel::DANGEROUS, security_info.security_level);
239 }
240
241 // Tests that password fields cause the security level to be downgraded
242 // to HTTP_SHOW_WARNING when the command-line switch is set.
243 TEST(SecurityStateModelTest, PasswordFieldWarning) {
244 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
245 switches::kMarkHttpAs,
246 switches::kMarkHttpWithPasswordsOrCcWithChip);
247 TestSecurityStateModelClient client;
248 client.UseHttpUrl();
249 SecurityStateModel model;
250 model.SetClient(&client);
251 client.set_displayed_password_field_on_http(true);
252 SecurityStateModel::SecurityInfo security_info;
253 model.GetSecurityInfo(&security_info);
254 EXPECT_TRUE(security_info.displayed_private_user_data_input_on_http);
255 EXPECT_EQ(SecurityStateModel::HTTP_SHOW_WARNING,
256 security_info.security_level);
257 }
258
259 // Tests that credit card fields cause the security level to be downgraded
260 // to HTTP_SHOW_WARNING when the command-line switch is set.
261 TEST(SecurityStateModelTest, CreditCardFieldWarning) {
262 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
263 switches::kMarkHttpAs,
264 switches::kMarkHttpWithPasswordsOrCcWithChip);
265 TestSecurityStateModelClient client;
266 client.UseHttpUrl();
267 SecurityStateModel model;
268 model.SetClient(&client);
269 client.set_displayed_credit_card_field_on_http(true);
270 SecurityStateModel::SecurityInfo security_info;
271 model.GetSecurityInfo(&security_info);
272 EXPECT_TRUE(security_info.displayed_private_user_data_input_on_http);
273 EXPECT_EQ(SecurityStateModel::HTTP_SHOW_WARNING,
274 security_info.security_level);
275 }
276
277 // Tests that neither password nor credit fields cause the security
278 // level to be downgraded to HTTP_SHOW_WARNING when the command-line switch
279 // is NOT set.
280 TEST(SecurityStateModelTest, HttpWarningNotSetWithoutSwitch) {
281 TestSecurityStateModelClient client;
282 client.UseHttpUrl();
283 SecurityStateModel model;
284 model.SetClient(&client);
285 client.set_displayed_password_field_on_http(true);
286 client.set_displayed_credit_card_field_on_http(true);
287 SecurityStateModel::SecurityInfo security_info;
288 model.GetSecurityInfo(&security_info);
289 EXPECT_TRUE(security_info.displayed_private_user_data_input_on_http);
290 EXPECT_EQ(SecurityStateModel::NONE, security_info.security_level);
291 }
292
293 // Tests that |displayed_private_user_data_input_on_http| is not set
294 // when the corresponding VisibleSecurityState flags are not set.
295 TEST(SecurityStateModelTest, PrivateUserDataNotSet) {
296 TestSecurityStateModelClient client;
297 client.UseHttpUrl();
298 SecurityStateModel model;
299 model.SetClient(&client);
300 SecurityStateModel::SecurityInfo security_info;
301 model.GetSecurityInfo(&security_info);
302 EXPECT_FALSE(security_info.displayed_private_user_data_input_on_http);
303 EXPECT_EQ(SecurityStateModel::NONE, security_info.security_level);
304 }
305
306 // Tests that SSL.MarkHttpAsStatus histogram is updated when security state is
307 // computed for a page.
308 TEST(SecurityStateModelTest, MarkHttpAsStatusHistogram) {
309 const char* kHistogramName = "SSL.MarkHttpAsStatus";
310 base::HistogramTester histograms;
311 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
312 switches::kMarkHttpAs, switches::kMarkHttpWithPasswordsOrCcWithChip);
313 TestSecurityStateModelClient client;
314 client.UseHttpUrl();
315 SecurityStateModel model;
316 model.SetClient(&client);
317
318 // Ensure histogram recorded correctly when a non-secure password input is
319 // found on the page.
320 client.set_displayed_password_field_on_http(true);
321 SecurityStateModel::SecurityInfo security_info;
322 histograms.ExpectTotalCount(kHistogramName, 0);
323 model.GetSecurityInfo(&security_info);
324 histograms.ExpectUniqueSample(kHistogramName, 2 /* HTTP_SHOW_WARNING */, 1);
325
326 // Ensure histogram recorded correctly even without a password input.
327 client.set_displayed_password_field_on_http(false);
328 model.GetSecurityInfo(&security_info);
329 histograms.ExpectUniqueSample(kHistogramName, 2 /* HTTP_SHOW_WARNING */, 2);
330 }
331
332 } // namespace
333
334 } // namespace security_state
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698