Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / net / http / transport_security_persister_unittest.cc
blob1d547eacf11d22ff453a5efb39658e9fd6bf4e55
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.
5 #include "net/http/transport_security_persister.h"
7 #include <map>
8 #include <string>
9 #include <vector>
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/message_loop/message_loop.h"
15 #include "net/http/transport_security_state.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 namespace net {
20 namespace {
22 class TransportSecurityPersisterTest : public testing::Test {
23 public:
24 TransportSecurityPersisterTest() {
27 ~TransportSecurityPersisterTest() override {
28 base::MessageLoopForIO::current()->RunUntilIdle();
31 void SetUp() override {
32 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
33 persister_.reset(new TransportSecurityPersister(
34 &state_,
35 temp_dir_.path(),
36 base::MessageLoopForIO::current()->message_loop_proxy(),
37 false));
40 protected:
41 base::ScopedTempDir temp_dir_;
42 TransportSecurityState state_;
43 scoped_ptr<TransportSecurityPersister> persister_;
46 TEST_F(TransportSecurityPersisterTest, SerializeData1) {
47 std::string output;
48 bool dirty;
50 EXPECT_TRUE(persister_->SerializeData(&output));
51 EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
52 EXPECT_FALSE(dirty);
55 TEST_F(TransportSecurityPersisterTest, SerializeData2) {
56 TransportSecurityState::DomainState domain_state;
57 const base::Time current_time(base::Time::Now());
58 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
59 static const char kYahooDomain[] = "yahoo.com";
61 EXPECT_FALSE(state_.GetStaticDomainState(kYahooDomain, &domain_state));
62 EXPECT_FALSE(state_.GetDynamicDomainState(kYahooDomain, &domain_state));
64 bool include_subdomains = true;
65 state_.AddHSTS(kYahooDomain, expiry, include_subdomains);
67 std::string output;
68 bool dirty;
69 EXPECT_TRUE(persister_->SerializeData(&output));
70 EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
72 EXPECT_TRUE(state_.GetDynamicDomainState(kYahooDomain, &domain_state));
73 EXPECT_EQ(domain_state.sts.upgrade_mode,
74 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
75 EXPECT_TRUE(state_.GetDynamicDomainState("foo.yahoo.com", &domain_state));
76 EXPECT_EQ(domain_state.sts.upgrade_mode,
77 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
78 EXPECT_TRUE(state_.GetDynamicDomainState("foo.bar.yahoo.com", &domain_state));
79 EXPECT_EQ(domain_state.sts.upgrade_mode,
80 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
81 EXPECT_TRUE(
82 state_.GetDynamicDomainState("foo.bar.baz.yahoo.com", &domain_state));
83 EXPECT_EQ(domain_state.sts.upgrade_mode,
84 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
85 EXPECT_FALSE(state_.GetStaticDomainState("com", &domain_state));
88 TEST_F(TransportSecurityPersisterTest, SerializeData3) {
89 // Add an entry.
90 HashValue fp1(HASH_VALUE_SHA1);
91 memset(fp1.data(), 0, fp1.size());
92 HashValue fp2(HASH_VALUE_SHA1);
93 memset(fp2.data(), 1, fp2.size());
94 base::Time expiry =
95 base::Time::Now() + base::TimeDelta::FromSeconds(1000);
96 HashValueVector dynamic_spki_hashes;
97 dynamic_spki_hashes.push_back(fp1);
98 dynamic_spki_hashes.push_back(fp2);
99 bool include_subdomains = false;
100 state_.AddHSTS("www.example.com", expiry, include_subdomains);
101 state_.AddHPKP("www.example.com", expiry, include_subdomains,
102 dynamic_spki_hashes);
104 // Add another entry.
105 memset(fp1.data(), 2, fp1.size());
106 memset(fp2.data(), 3, fp2.size());
107 expiry =
108 base::Time::Now() + base::TimeDelta::FromSeconds(3000);
109 dynamic_spki_hashes.push_back(fp1);
110 dynamic_spki_hashes.push_back(fp2);
111 state_.AddHSTS("www.example.net", expiry, include_subdomains);
112 state_.AddHPKP("www.example.net", expiry, include_subdomains,
113 dynamic_spki_hashes);
115 // Save a copy of everything.
116 std::map<std::string, TransportSecurityState::DomainState> saved;
117 TransportSecurityState::Iterator i(state_);
118 while (i.HasNext()) {
119 saved[i.hostname()] = i.domain_state();
120 i.Advance();
123 std::string serialized;
124 EXPECT_TRUE(persister_->SerializeData(&serialized));
126 // Persist the data to the file. For the test to be fast and not flaky, we
127 // just do it directly rather than call persister_->StateIsDirty. (That uses
128 // ImportantFileWriter, which has an asynchronous commit interval rather
129 // than block.) Use a different basename just for cleanliness.
130 base::FilePath path =
131 temp_dir_.path().AppendASCII("TransportSecurityPersisterTest");
132 EXPECT_TRUE(base::WriteFile(path, serialized.c_str(), serialized.size()));
134 // Read the data back.
135 std::string persisted;
136 EXPECT_TRUE(base::ReadFileToString(path, &persisted));
137 EXPECT_EQ(persisted, serialized);
138 bool dirty;
139 EXPECT_TRUE(persister_->LoadEntries(persisted, &dirty));
140 EXPECT_FALSE(dirty);
142 // Check that states are the same as saved.
143 size_t count = 0;
144 TransportSecurityState::Iterator j(state_);
145 while (j.HasNext()) {
146 count++;
147 j.Advance();
149 EXPECT_EQ(count, saved.size());
152 TEST_F(TransportSecurityPersisterTest, SerializeDataOld) {
153 // This is an old-style piece of transport state JSON, which has no creation
154 // date.
155 std::string output =
156 "{ "
157 "\"NiyD+3J1r6z1wjl2n1ALBu94Zj9OsEAMo0kCN8js0Uk=\": {"
158 "\"expiry\": 1266815027.983453, "
159 "\"include_subdomains\": false, "
160 "\"mode\": \"strict\" "
162 "}";
163 bool dirty;
164 EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
165 EXPECT_TRUE(dirty);
168 TEST_F(TransportSecurityPersisterTest, PublicKeyHashes) {
169 TransportSecurityState::DomainState domain_state;
170 static const char kTestDomain[] = "example.com";
171 EXPECT_FALSE(state_.GetDynamicDomainState(kTestDomain, &domain_state));
172 HashValueVector hashes;
173 std::string failure_log;
174 EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));
176 HashValue sha1(HASH_VALUE_SHA1);
177 memset(sha1.data(), '1', sha1.size());
178 domain_state.pkp.spki_hashes.push_back(sha1);
180 EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));
182 hashes.push_back(sha1);
183 EXPECT_TRUE(domain_state.CheckPublicKeyPins(hashes, &failure_log));
185 hashes[0].data()[0] = '2';
186 EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));
188 const base::Time current_time(base::Time::Now());
189 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
190 bool include_subdomains = false;
191 state_.AddHSTS(kTestDomain, expiry, include_subdomains);
192 state_.AddHPKP(
193 kTestDomain, expiry, include_subdomains, domain_state.pkp.spki_hashes);
194 std::string serialized;
195 EXPECT_TRUE(persister_->SerializeData(&serialized));
196 bool dirty;
197 EXPECT_TRUE(persister_->LoadEntries(serialized, &dirty));
199 TransportSecurityState::DomainState new_domain_state;
200 EXPECT_TRUE(state_.GetDynamicDomainState(kTestDomain, &new_domain_state));
201 EXPECT_EQ(1u, new_domain_state.pkp.spki_hashes.size());
202 EXPECT_EQ(sha1.tag, new_domain_state.pkp.spki_hashes[0].tag);
203 EXPECT_EQ(0,
204 memcmp(new_domain_state.pkp.spki_hashes[0].data(),
205 sha1.data(),
206 sha1.size()));
209 } // namespace
211 } // namespace net