Update V8 to version 4.6.48.
[chromium-blink-merge.git] / net / http / transport_security_persister_unittest.cc
blob7e460ad49865f7248c0be236c1a49ca16eabe1c5
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 const char kReportUri[] = "http://www.example.test/report";
24 class TransportSecurityPersisterTest : public testing::Test {
25 public:
26 TransportSecurityPersisterTest() {
29 ~TransportSecurityPersisterTest() override {
30 base::MessageLoopForIO::current()->RunUntilIdle();
33 void SetUp() override {
34 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
35 persister_.reset(new TransportSecurityPersister(
36 &state_, temp_dir_.path(),
37 base::MessageLoopForIO::current()->task_runner(), 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::STSState sts_state;
57 TransportSecurityState::PKPState pkp_state;
58 const base::Time current_time(base::Time::Now());
59 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
60 static const char kYahooDomain[] = "yahoo.com";
62 EXPECT_FALSE(
63 state_.GetStaticDomainState(kYahooDomain, &sts_state, &pkp_state));
64 EXPECT_FALSE(state_.GetDynamicSTSState(kYahooDomain, &sts_state));
65 EXPECT_FALSE(state_.GetDynamicPKPState(kYahooDomain, &pkp_state));
67 bool include_subdomains = true;
68 state_.AddHSTS(kYahooDomain, expiry, include_subdomains);
70 std::string output;
71 bool dirty;
72 EXPECT_TRUE(persister_->SerializeData(&output));
73 EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
75 EXPECT_TRUE(state_.GetDynamicSTSState(kYahooDomain, &sts_state));
76 EXPECT_EQ(sts_state.upgrade_mode,
77 TransportSecurityState::STSState::MODE_FORCE_HTTPS);
78 EXPECT_TRUE(state_.GetDynamicSTSState("foo.yahoo.com", &sts_state));
79 EXPECT_EQ(sts_state.upgrade_mode,
80 TransportSecurityState::STSState::MODE_FORCE_HTTPS);
81 EXPECT_TRUE(state_.GetDynamicSTSState("foo.bar.yahoo.com", &sts_state));
82 EXPECT_EQ(sts_state.upgrade_mode,
83 TransportSecurityState::STSState::MODE_FORCE_HTTPS);
84 EXPECT_TRUE(state_.GetDynamicSTSState("foo.bar.baz.yahoo.com", &sts_state));
85 EXPECT_EQ(sts_state.upgrade_mode,
86 TransportSecurityState::STSState::MODE_FORCE_HTTPS);
87 EXPECT_FALSE(state_.GetStaticDomainState("com", &sts_state, &pkp_state));
90 TEST_F(TransportSecurityPersisterTest, SerializeData3) {
91 const GURL report_uri(kReportUri);
92 // Add an entry.
93 HashValue fp1(HASH_VALUE_SHA1);
94 memset(fp1.data(), 0, fp1.size());
95 HashValue fp2(HASH_VALUE_SHA1);
96 memset(fp2.data(), 1, fp2.size());
97 base::Time expiry =
98 base::Time::Now() + base::TimeDelta::FromSeconds(1000);
99 HashValueVector dynamic_spki_hashes;
100 dynamic_spki_hashes.push_back(fp1);
101 dynamic_spki_hashes.push_back(fp2);
102 bool include_subdomains = false;
103 state_.AddHSTS("www.example.com", expiry, include_subdomains);
104 state_.AddHPKP("www.example.com", expiry, include_subdomains,
105 dynamic_spki_hashes, report_uri);
107 // Add another entry.
108 memset(fp1.data(), 2, fp1.size());
109 memset(fp2.data(), 3, fp2.size());
110 expiry =
111 base::Time::Now() + base::TimeDelta::FromSeconds(3000);
112 dynamic_spki_hashes.push_back(fp1);
113 dynamic_spki_hashes.push_back(fp2);
114 state_.AddHSTS("www.example.net", expiry, include_subdomains);
115 state_.AddHPKP("www.example.net", expiry, include_subdomains,
116 dynamic_spki_hashes, report_uri);
118 // Save a copy of everything.
119 std::set<std::string> sts_saved;
120 TransportSecurityState::STSStateIterator sts_iter(state_);
121 while (sts_iter.HasNext()) {
122 sts_saved.insert(sts_iter.hostname());
123 sts_iter.Advance();
126 std::set<std::string> pkp_saved;
127 TransportSecurityState::PKPStateIterator pkp_iter(state_);
128 while (pkp_iter.HasNext()) {
129 pkp_saved.insert(pkp_iter.hostname());
130 pkp_iter.Advance();
133 std::string serialized;
134 EXPECT_TRUE(persister_->SerializeData(&serialized));
136 // Persist the data to the file. For the test to be fast and not flaky, we
137 // just do it directly rather than call persister_->StateIsDirty. (That uses
138 // ImportantFileWriter, which has an asynchronous commit interval rather
139 // than block.) Use a different basename just for cleanliness.
140 base::FilePath path =
141 temp_dir_.path().AppendASCII("TransportSecurityPersisterTest");
142 EXPECT_TRUE(base::WriteFile(path, serialized.c_str(), serialized.size()));
144 // Read the data back.
145 std::string persisted;
146 EXPECT_TRUE(base::ReadFileToString(path, &persisted));
147 EXPECT_EQ(persisted, serialized);
148 bool dirty;
149 EXPECT_TRUE(persister_->LoadEntries(persisted, &dirty));
150 EXPECT_FALSE(dirty);
152 // Check that states are the same as saved.
153 size_t count = 0;
154 TransportSecurityState::STSStateIterator sts_iter2(state_);
155 while (sts_iter2.HasNext()) {
156 count++;
157 sts_iter2.Advance();
159 EXPECT_EQ(count, sts_saved.size());
161 count = 0;
162 TransportSecurityState::PKPStateIterator pkp_iter2(state_);
163 while (pkp_iter2.HasNext()) {
164 count++;
165 pkp_iter2.Advance();
167 EXPECT_EQ(count, pkp_saved.size());
170 TEST_F(TransportSecurityPersisterTest, SerializeDataOld) {
171 // This is an old-style piece of transport state JSON, which has no creation
172 // date.
173 std::string output =
174 "{ "
175 "\"NiyD+3J1r6z1wjl2n1ALBu94Zj9OsEAMo0kCN8js0Uk=\": {"
176 "\"expiry\": 1266815027.983453, "
177 "\"include_subdomains\": false, "
178 "\"mode\": \"strict\" "
180 "}";
181 bool dirty;
182 EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
183 EXPECT_TRUE(dirty);
186 TEST_F(TransportSecurityPersisterTest, PublicKeyPins) {
187 const GURL report_uri(kReportUri);
188 TransportSecurityState::PKPState pkp_state;
189 static const char kTestDomain[] = "example.com";
191 EXPECT_FALSE(state_.GetDynamicPKPState(kTestDomain, &pkp_state));
192 HashValueVector hashes;
193 std::string failure_log;
194 EXPECT_FALSE(pkp_state.CheckPublicKeyPins(hashes, &failure_log));
196 HashValue sha1(HASH_VALUE_SHA1);
197 memset(sha1.data(), '1', sha1.size());
198 pkp_state.spki_hashes.push_back(sha1);
200 EXPECT_FALSE(pkp_state.CheckPublicKeyPins(hashes, &failure_log));
202 hashes.push_back(sha1);
203 EXPECT_TRUE(pkp_state.CheckPublicKeyPins(hashes, &failure_log));
205 hashes[0].data()[0] = '2';
206 EXPECT_FALSE(pkp_state.CheckPublicKeyPins(hashes, &failure_log));
208 const base::Time current_time(base::Time::Now());
209 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
210 bool include_subdomains = false;
211 state_.AddHSTS(kTestDomain, expiry, include_subdomains);
212 state_.AddHPKP(kTestDomain, expiry, include_subdomains, pkp_state.spki_hashes,
213 report_uri);
214 std::string serialized;
215 EXPECT_TRUE(persister_->SerializeData(&serialized));
216 bool dirty;
217 EXPECT_TRUE(persister_->LoadEntries(serialized, &dirty));
219 TransportSecurityState::PKPState new_pkp_state;
220 EXPECT_TRUE(state_.GetDynamicPKPState(kTestDomain, &new_pkp_state));
221 EXPECT_EQ(1u, new_pkp_state.spki_hashes.size());
222 EXPECT_EQ(sha1.tag, new_pkp_state.spki_hashes[0].tag);
223 EXPECT_EQ(
224 0, memcmp(new_pkp_state.spki_hashes[0].data(), sha1.data(), sha1.size()));
225 EXPECT_EQ(report_uri, new_pkp_state.report_uri);
228 } // namespace
230 } // namespace net