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

Side by Side Diff: chrome/browser/transport_security_persister_unittest.cc

Issue 9415040: Refactor TransportSecurityState. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/transport_security_persister.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/file_path.h"
11 #include "base/file_util.h"
12 #include "base/message_loop.h"
13 #include "base/scoped_temp_dir.h"
14 #include "content/test/test_browser_thread.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "net/base/transport_security_state.h"
17 #include "net/base/x509_cert_types.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using net::TransportSecurityState;
21 using content::BrowserThread;
22
23 class TransportSecurityPersisterTest : public testing::Test {
24 public:
25 TransportSecurityPersisterTest()
26 : message_loop(MessageLoop::TYPE_IO),
27 test_io_thread(BrowserThread::IO, &message_loop),
28 persister(&state, temp_dir.path(), false) {
29 }
30
31 virtual void SetUp() { }
32
33 MessageLoop message_loop;
34 content::TestBrowserThread test_io_thread;
35 ScopedTempDir temp_dir;
36 TransportSecurityPersister persister;
37 TransportSecurityState state;
38 };
39
40 TEST_F(TransportSecurityPersisterTest, SerializeData1) {
41 std::string output;
42 bool dirty;
43
44 EXPECT_TRUE(persister.SerializeData(&output));
45 EXPECT_TRUE(persister.LoadEntries(output, &dirty));
46 EXPECT_FALSE(dirty);
47 }
48
49 TEST_F(TransportSecurityPersisterTest, SerializeData2) {
50 TransportSecurityState::DomainState domain_state;
51 const base::Time current_time(base::Time::Now());
52 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
53
54 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
55 domain_state.upgrade_mode =
56 TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
57 domain_state.upgrade_expiry = expiry;
58 domain_state.include_subdomains = true;
59 state.EnableHost("yahoo.com", domain_state);
60
61 std::string output;
62 bool dirty;
63 EXPECT_TRUE(persister.SerializeData(&output));
64 EXPECT_TRUE(persister.LoadEntries(output, &dirty));
65
66 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
67 EXPECT_EQ(domain_state.upgrade_mode,
68 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
69 EXPECT_TRUE(state.GetDomainState("foo.yahoo.com", true, &domain_state));
70 EXPECT_EQ(domain_state.upgrade_mode,
71 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
72 EXPECT_TRUE(state.GetDomainState("foo.bar.yahoo.com", true, &domain_state));
73 EXPECT_EQ(domain_state.upgrade_mode,
74 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
75 EXPECT_TRUE(state.GetDomainState("foo.bar.baz.yahoo.com", true,
76 &domain_state));
77 EXPECT_EQ(domain_state.upgrade_mode,
78 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
79 EXPECT_FALSE(state.GetDomainState("com", true, &domain_state));
80 }
81
82 TEST_F(TransportSecurityPersisterTest, SerializeData3) {
83 using std::string;
84 using net::SHA1Fingerprint;
85
86 // Add an entry.
87 SHA1Fingerprint fp1;
88 memset(fp1.data, 0, sizeof(fp1.data));
89 SHA1Fingerprint fp2;
90 memset(fp2.data, 1, sizeof(fp2.data));
91 TransportSecurityState::DomainState example_state;
92 example_state.upgrade_expiry =
93 base::Time::Now() + base::TimeDelta::FromSeconds(1000);
94 example_state.upgrade_mode =
95 TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
96 example_state.dynamic_spki_hashes_expiry = example_state.upgrade_expiry;
97 example_state.dynamic_spki_hashes.push_back(fp1);
98 example_state.dynamic_spki_hashes.push_back(fp2);
99 state.EnableHost("www.example.com", example_state);
100
101 // Add another entry.
102 memset(fp1.data, 2, sizeof(fp1.data));
103 memset(fp2.data, 3, sizeof(fp2.data));
104 example_state.upgrade_expiry =
105 base::Time::Now() + base::TimeDelta::FromSeconds(3000);
106 example_state.upgrade_mode =
107 TransportSecurityState::DomainState::MODE_DEFAULT;
108 example_state.dynamic_spki_hashes_expiry = example_state.upgrade_expiry;
109 example_state.dynamic_spki_hashes.push_back(fp1);
110 example_state.dynamic_spki_hashes.push_back(fp2);
111 state.EnableHost("www.example.net", example_state);
112
113 // Save a copy of everything.
114 std::map<string, TransportSecurityState::DomainState> saved;
115 TransportSecurityState::Iterator i(state);
116 while (i.HasNext()) {
117 saved[i.hostname()] = i.domain_state();
118 i.Advance();
119 }
120
121 std::string serialized;
122 EXPECT_TRUE(persister.SerializeData(&serialized));
123
124 // Persist the data to the file. For the test to be fast and not flaky, we
125 // just do it directly rather than call persister.StateIsDirty. (That uses
126 // ImportantFileWriter, which has an asynchronous commit interval rather
127 // than block.) Use a different basename just for cleanliness.
128 FilePath path = temp_dir.path().AppendASCII("TransportSecurityPersisterTest");
129 EXPECT_TRUE(file_util::WriteFile(path, serialized.c_str(),
130 serialized.size()));
131
132 // Read the data back.
133 std::string persisted;
134 EXPECT_TRUE(file_util::ReadFileToString(path, &persisted));
135 EXPECT_EQ(persisted, serialized);
136 bool dirty;
137 EXPECT_TRUE(persister.LoadEntries(persisted, &dirty));
138 EXPECT_FALSE(dirty);
139
140 // Check that states are the same as saved.
141 size_t count = 0;
142 TransportSecurityState::Iterator j(state);
143 while (j.HasNext()) {
144 EXPECT_TRUE(saved[j.hostname()].Equals(j.domain_state()));
145 count++;
146 j.Advance();
147 }
148 EXPECT_EQ(count, saved.size());
149 }
150
151 TEST_F(TransportSecurityPersisterTest, SerializeDataOld) {
152 // This is an old-style piece of transport state JSON, which has no creation
153 // date.
154 std::string output =
155 "{ "
156 "\"NiyD+3J1r6z1wjl2n1ALBu94Zj9OsEAMo0kCN8js0Uk=\": {"
157 "\"expiry\": 1266815027.983453, "
158 "\"include_subdomains\": false, "
159 "\"mode\": \"strict\" "
160 "}"
161 "}";
162 bool dirty;
163 EXPECT_TRUE(persister.LoadEntries(output, &dirty));
164 EXPECT_TRUE(dirty);
165 }
166
167 TEST_F(TransportSecurityPersisterTest, PublicKeyHashes) {
168 TransportSecurityState::DomainState domain_state;
169 EXPECT_FALSE(state.GetDomainState("example.com", false, &domain_state));
170 net::FingerprintVector hashes;
171 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(hashes));
172
173 net::SHA1Fingerprint hash;
174 memset(hash.data, '1', sizeof(hash.data));
175 domain_state.static_spki_hashes.push_back(hash);
176
177 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes));
178 hashes.push_back(hash);
179 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(hashes));
180 hashes[0].data[0] = '2';
181 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes));
182
183 const base::Time current_time(base::Time::Now());
184 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
185 domain_state.upgrade_expiry = expiry;
186 state.EnableHost("example.com", domain_state);
187 std::string ser;
188 EXPECT_TRUE(persister.SerializeData(&ser));
189 bool dirty;
190 EXPECT_TRUE(persister.LoadEntries(ser, &dirty));
191 EXPECT_TRUE(state.GetDomainState("example.com", false, &domain_state));
192 EXPECT_EQ(1u, domain_state.static_spki_hashes.size());
193 EXPECT_EQ(0, memcmp(domain_state.static_spki_hashes[0].data, hash.data,
194 sizeof(hash.data)));
195 }
196
197 TEST_F(TransportSecurityPersisterTest, ForcePreloads) {
198 // The static state for docs.google.com, defined in
199 // net/base/transport_security_state_static.h, has pins and mode strict.
200 // This new policy overrides that with no pins and a weaker mode. We apply
201 // this new policy with |DeserializeFromCommandLine| and expect that the
202 // new policy is in effect, overriding the static policy.
203 std::string preload("{"
204 "\"4AGT3lHihuMSd5rUj7B4u6At0jlSH3HFePovjPR+oLE=\": {"
205 "\"created\": 0.0,"
206 "\"expiry\": 2000000000.0,"
207 "\"include_subdomains\": false,"
208 "\"mode\": \"pinning-only\""
209 "}}");
210
211 EXPECT_TRUE(persister.DeserializeFromCommandLine(preload));
212
213 TransportSecurityState::DomainState domain_state;
214 EXPECT_TRUE(state.GetDomainState("docs.google.com", true, &domain_state));
215 EXPECT_FALSE(domain_state.HasPins());
216 EXPECT_FALSE(domain_state.ShouldRedirectHTTPToHTTPS());
217 }
218
OLDNEW
« no previous file with comments | « chrome/browser/transport_security_persister.cc ('k') | chrome/browser/ui/webui/net_internals/net_internals_ui.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698