Add a function to create a bookmark app from a WebApplicationInfo.
[chromium-blink-merge.git] / net / http / transport_security_persister_unittest.cc
blob114e933bde4db0e94abc74f851d5b2e1c2eb804d
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/file_util.h"
12 #include "base/files/file_path.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 using net::TransportSecurityPersister;
19 using net::TransportSecurityState;
21 class TransportSecurityPersisterTest : public testing::Test {
22 public:
23 TransportSecurityPersisterTest() {
26 virtual ~TransportSecurityPersisterTest() {
27 base::MessageLoopForIO::current()->RunUntilIdle();
30 virtual void SetUp() OVERRIDE {
31 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
32 persister_.reset(new TransportSecurityPersister(
33 &state_,
34 temp_dir_.path(),
35 base::MessageLoopForIO::current()->message_loop_proxy(),
36 false));
39 protected:
40 base::ScopedTempDir temp_dir_;
41 TransportSecurityState state_;
42 scoped_ptr<TransportSecurityPersister> persister_;
45 TEST_F(TransportSecurityPersisterTest, SerializeData1) {
46 std::string output;
47 bool dirty;
49 EXPECT_TRUE(persister_->SerializeData(&output));
50 EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
51 EXPECT_FALSE(dirty);
54 TEST_F(TransportSecurityPersisterTest, SerializeData2) {
55 TransportSecurityState::DomainState domain_state;
56 const base::Time current_time(base::Time::Now());
57 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
58 static const char kYahooDomain[] = "yahoo.com";
60 EXPECT_FALSE(state_.GetDomainState(kYahooDomain, true, &domain_state));
62 bool include_subdomains = true;
63 state_.AddHSTS(kYahooDomain, expiry, include_subdomains);
65 std::string output;
66 bool dirty;
67 EXPECT_TRUE(persister_->SerializeData(&output));
68 EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
70 EXPECT_TRUE(state_.GetDomainState(kYahooDomain, true, &domain_state));
71 EXPECT_EQ(domain_state.upgrade_mode,
72 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
73 EXPECT_TRUE(state_.GetDomainState("foo.yahoo.com", true, &domain_state));
74 EXPECT_EQ(domain_state.upgrade_mode,
75 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
76 EXPECT_TRUE(state_.GetDomainState("foo.bar.yahoo.com", true, &domain_state));
77 EXPECT_EQ(domain_state.upgrade_mode,
78 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
79 EXPECT_TRUE(state_.GetDomainState("foo.bar.baz.yahoo.com", true,
80 &domain_state));
81 EXPECT_EQ(domain_state.upgrade_mode,
82 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
83 EXPECT_FALSE(state_.GetDomainState("com", true, &domain_state));
86 TEST_F(TransportSecurityPersisterTest, SerializeData3) {
87 // Add an entry.
88 net::HashValue fp1(net::HASH_VALUE_SHA1);
89 memset(fp1.data(), 0, fp1.size());
90 net::HashValue fp2(net::HASH_VALUE_SHA1);
91 memset(fp2.data(), 1, fp2.size());
92 base::Time expiry =
93 base::Time::Now() + base::TimeDelta::FromSeconds(1000);
94 net::HashValueVector dynamic_spki_hashes;
95 dynamic_spki_hashes.push_back(fp1);
96 dynamic_spki_hashes.push_back(fp2);
97 bool include_subdomains = false;
98 state_.AddHSTS("www.example.com", expiry, include_subdomains);
99 state_.AddHPKP("www.example.com", expiry, include_subdomains,
100 dynamic_spki_hashes);
102 // Add another entry.
103 memset(fp1.data(), 2, fp1.size());
104 memset(fp2.data(), 3, fp2.size());
105 expiry =
106 base::Time::Now() + base::TimeDelta::FromSeconds(3000);
107 dynamic_spki_hashes.push_back(fp1);
108 dynamic_spki_hashes.push_back(fp2);
109 state_.AddHSTS("www.example.net", expiry, include_subdomains);
110 state_.AddHPKP("www.example.net", expiry, include_subdomains,
111 dynamic_spki_hashes);
113 // Save a copy of everything.
114 std::map<std::string, TransportSecurityState::DomainState> saved;
115 TransportSecurityState::Iterator i(state_);
116 while (i.HasNext()) {
117 saved[i.hostname()] = i.domain_state();
118 i.Advance();
121 std::string serialized;
122 EXPECT_TRUE(persister_->SerializeData(&serialized));
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 base::FilePath path =
129 temp_dir_.path().AppendASCII("TransportSecurityPersisterTest");
130 EXPECT_TRUE(base::WriteFile(path, serialized.c_str(), serialized.size()));
132 // Read the data back.
133 std::string persisted;
134 EXPECT_TRUE(base::ReadFileToString(path, &persisted));
135 EXPECT_EQ(persisted, serialized);
136 bool dirty;
137 EXPECT_TRUE(persister_->LoadEntries(persisted, &dirty));
138 EXPECT_FALSE(dirty);
140 // Check that states are the same as saved.
141 size_t count = 0;
142 TransportSecurityState::Iterator j(state_);
143 while (j.HasNext()) {
144 count++;
145 j.Advance();
147 EXPECT_EQ(count, saved.size());
150 TEST_F(TransportSecurityPersisterTest, SerializeDataOld) {
151 // This is an old-style piece of transport state JSON, which has no creation
152 // date.
153 std::string output =
154 "{ "
155 "\"NiyD+3J1r6z1wjl2n1ALBu94Zj9OsEAMo0kCN8js0Uk=\": {"
156 "\"expiry\": 1266815027.983453, "
157 "\"include_subdomains\": false, "
158 "\"mode\": \"strict\" "
160 "}";
161 bool dirty;
162 EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
163 EXPECT_TRUE(dirty);
166 TEST_F(TransportSecurityPersisterTest, PublicKeyHashes) {
167 TransportSecurityState::DomainState domain_state;
168 static const char kTestDomain[] = "example.com";
169 EXPECT_FALSE(state_.GetDomainState(kTestDomain, false, &domain_state));
170 net::HashValueVector hashes;
171 EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes));
173 net::HashValue sha1(net::HASH_VALUE_SHA1);
174 memset(sha1.data(), '1', sha1.size());
175 domain_state.dynamic_spki_hashes.push_back(sha1);
177 EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes));
179 hashes.push_back(sha1);
180 EXPECT_TRUE(domain_state.CheckPublicKeyPins(hashes));
182 hashes[0].data()[0] = '2';
183 EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes));
185 const base::Time current_time(base::Time::Now());
186 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
187 bool include_subdomains = false;
188 state_.AddHSTS(kTestDomain, expiry, include_subdomains);
189 state_.AddHPKP(kTestDomain, expiry, include_subdomains,
190 domain_state.dynamic_spki_hashes);
191 std::string ser;
192 EXPECT_TRUE(persister_->SerializeData(&ser));
193 bool dirty;
194 EXPECT_TRUE(persister_->LoadEntries(ser, &dirty));
195 EXPECT_TRUE(state_.GetDomainState(kTestDomain, false, &domain_state));
196 EXPECT_EQ(1u, domain_state.dynamic_spki_hashes.size());
197 EXPECT_EQ(sha1.tag, domain_state.dynamic_spki_hashes[0].tag);
198 EXPECT_EQ(0, memcmp(domain_state.dynamic_spki_hashes[0].data(), sha1.data(),
199 sha1.size()));