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

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

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

Powered by Google App Engine
This is Rietveld 408576698