OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
8 #include "base/memory/scoped_vector.h" | 8 #include "base/memory/scoped_vector.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/scoped_temp_dir.h" | 10 #include "base/scoped_temp_dir.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "base/test/thread_test_helper.h" | 12 #include "base/test/thread_test_helper.h" |
13 #include "chrome/browser/net/sqlite_origin_bound_cert_store.h" | 13 #include "chrome/browser/net/sqlite_origin_bound_cert_store.h" |
14 #include "chrome/common/chrome_constants.h" | 14 #include "chrome/common/chrome_constants.h" |
15 #include "content/test/test_browser_thread.h" | 15 #include "content/test/test_browser_thread.h" |
16 #include "net/base/cert_test_util.h" | 16 #include "net/base/cert_test_util.h" |
17 #include "sql/statement.h" | 17 #include "sql/statement.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
19 | 19 |
20 using content::BrowserThread; | 20 using content::BrowserThread; |
21 | 21 |
22 class SQLiteOriginBoundCertStoreTest : public testing::Test { | 22 class SQLiteServerBoundCertStoreTest : public testing::Test { |
23 public: | 23 public: |
24 SQLiteOriginBoundCertStoreTest() | 24 SQLiteServerBoundCertStoreTest() |
25 : db_thread_(BrowserThread::DB) { | 25 : db_thread_(BrowserThread::DB) { |
26 } | 26 } |
27 | 27 |
28 protected: | 28 protected: |
29 static void ReadTestKeyAndCert(std::string* key, std::string* cert) { | 29 static void ReadTestKeyAndCert(std::string* key, std::string* cert) { |
30 FilePath key_path = net::GetTestCertsDirectory().AppendASCII( | 30 FilePath key_path = net::GetTestCertsDirectory().AppendASCII( |
31 "unittest.originbound.key.der"); | 31 "unittest.originbound.key.der"); |
32 FilePath cert_path = net::GetTestCertsDirectory().AppendASCII( | 32 FilePath cert_path = net::GetTestCertsDirectory().AppendASCII( |
33 "unittest.originbound.der"); | 33 "unittest.originbound.der"); |
34 ASSERT_TRUE(file_util::ReadFileToString(key_path, key)); | 34 ASSERT_TRUE(file_util::ReadFileToString(key_path, key)); |
(...skipping 18 matching lines...) Expand all Loading... |
53 exploded_time.hour = 2; | 53 exploded_time.hour = 2; |
54 exploded_time.minute = 23; | 54 exploded_time.minute = 23; |
55 exploded_time.second = 45; | 55 exploded_time.second = 45; |
56 exploded_time.millisecond = 0; | 56 exploded_time.millisecond = 0; |
57 return base::Time::FromUTCExploded(exploded_time); | 57 return base::Time::FromUTCExploded(exploded_time); |
58 } | 58 } |
59 | 59 |
60 virtual void SetUp() { | 60 virtual void SetUp() { |
61 db_thread_.Start(); | 61 db_thread_.Start(); |
62 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 62 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
63 store_ = new SQLiteOriginBoundCertStore( | 63 store_ = new SQLiteServerBoundCertStore( |
64 temp_dir_.path().Append(chrome::kOBCertFilename)); | 64 temp_dir_.path().Append(chrome::kOBCertFilename)); |
65 ScopedVector<net::DefaultOriginBoundCertStore::OriginBoundCert> certs; | 65 ScopedVector<net::DefaultServerBoundCertStore::ServerBoundCert> certs; |
66 ASSERT_TRUE(store_->Load(&certs.get())); | 66 ASSERT_TRUE(store_->Load(&certs.get())); |
67 ASSERT_EQ(0u, certs.size()); | 67 ASSERT_EQ(0u, certs.size()); |
68 // Make sure the store gets written at least once. | 68 // Make sure the store gets written at least once. |
69 store_->AddOriginBoundCert( | 69 store_->AddServerBoundCert( |
70 net::DefaultOriginBoundCertStore::OriginBoundCert( | 70 net::DefaultServerBoundCertStore::ServerBoundCert( |
71 "https://encrypted.google.com:8443", | 71 "google.com", |
72 net::CLIENT_CERT_RSA_SIGN, | 72 net::CLIENT_CERT_RSA_SIGN, |
73 base::Time::FromInternalValue(1), | 73 base::Time::FromInternalValue(1), |
74 base::Time::FromInternalValue(2), | 74 base::Time::FromInternalValue(2), |
75 "a", "b")); | 75 "a", "b")); |
76 } | 76 } |
77 | 77 |
78 content::TestBrowserThread db_thread_; | 78 content::TestBrowserThread db_thread_; |
79 ScopedTempDir temp_dir_; | 79 ScopedTempDir temp_dir_; |
80 scoped_refptr<SQLiteOriginBoundCertStore> store_; | 80 scoped_refptr<SQLiteServerBoundCertStore> store_; |
81 }; | 81 }; |
82 | 82 |
83 TEST_F(SQLiteOriginBoundCertStoreTest, KeepOnDestruction) { | 83 TEST_F(SQLiteServerBoundCertStoreTest, KeepOnDestruction) { |
84 store_->SetClearLocalStateOnExit(false); | 84 store_->SetClearLocalStateOnExit(false); |
85 store_ = NULL; | 85 store_ = NULL; |
86 // Make sure we wait until the destructor has run. | 86 // Make sure we wait until the destructor has run. |
87 scoped_refptr<base::ThreadTestHelper> helper( | 87 scoped_refptr<base::ThreadTestHelper> helper( |
88 new base::ThreadTestHelper( | 88 new base::ThreadTestHelper( |
89 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | 89 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); |
90 ASSERT_TRUE(helper->Run()); | 90 ASSERT_TRUE(helper->Run()); |
91 | 91 |
92 ASSERT_TRUE(file_util::PathExists( | 92 ASSERT_TRUE(file_util::PathExists( |
93 temp_dir_.path().Append(chrome::kOBCertFilename))); | 93 temp_dir_.path().Append(chrome::kOBCertFilename))); |
94 ASSERT_TRUE(file_util::Delete( | 94 ASSERT_TRUE(file_util::Delete( |
95 temp_dir_.path().Append(chrome::kOBCertFilename), false)); | 95 temp_dir_.path().Append(chrome::kOBCertFilename), false)); |
96 } | 96 } |
97 | 97 |
98 TEST_F(SQLiteOriginBoundCertStoreTest, RemoveOnDestruction) { | 98 TEST_F(SQLiteServerBoundCertStoreTest, RemoveOnDestruction) { |
99 store_->SetClearLocalStateOnExit(true); | 99 store_->SetClearLocalStateOnExit(true); |
100 // Replace the store effectively destroying the current one and forcing it | 100 // Replace the store effectively destroying the current one and forcing it |
101 // to write it's data to disk. Then we can see if after loading it again it | 101 // to write it's data to disk. Then we can see if after loading it again it |
102 // is still there. | 102 // is still there. |
103 store_ = NULL; | 103 store_ = NULL; |
104 // Make sure we wait until the destructor has run. | 104 // Make sure we wait until the destructor has run. |
105 scoped_refptr<base::ThreadTestHelper> helper( | 105 scoped_refptr<base::ThreadTestHelper> helper( |
106 new base::ThreadTestHelper( | 106 new base::ThreadTestHelper( |
107 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | 107 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); |
108 ASSERT_TRUE(helper->Run()); | 108 ASSERT_TRUE(helper->Run()); |
109 | 109 |
110 ASSERT_FALSE(file_util::PathExists( | 110 ASSERT_FALSE(file_util::PathExists( |
111 temp_dir_.path().Append(chrome::kOBCertFilename))); | 111 temp_dir_.path().Append(chrome::kOBCertFilename))); |
112 } | 112 } |
113 | 113 |
114 // Test if data is stored as expected in the SQLite database. | 114 // Test if data is stored as expected in the SQLite database. |
115 TEST_F(SQLiteOriginBoundCertStoreTest, TestPersistence) { | 115 TEST_F(SQLiteServerBoundCertStoreTest, TestPersistence) { |
116 store_->AddOriginBoundCert( | 116 store_->AddServerBoundCert( |
117 net::DefaultOriginBoundCertStore::OriginBoundCert( | 117 net::DefaultServerBoundCertStore::ServerBoundCert( |
118 "https://www.google.com/", | 118 "foo.com", |
119 net::CLIENT_CERT_ECDSA_SIGN, | 119 net::CLIENT_CERT_ECDSA_SIGN, |
120 base::Time::FromInternalValue(3), | 120 base::Time::FromInternalValue(3), |
121 base::Time::FromInternalValue(4), | 121 base::Time::FromInternalValue(4), |
122 "c", "d")); | 122 "c", "d")); |
123 | 123 |
124 ScopedVector<net::DefaultOriginBoundCertStore::OriginBoundCert> certs; | 124 ScopedVector<net::DefaultServerBoundCertStore::ServerBoundCert> certs; |
125 // Replace the store effectively destroying the current one and forcing it | 125 // Replace the store effectively destroying the current one and forcing it |
126 // to write it's data to disk. Then we can see if after loading it again it | 126 // to write it's data to disk. Then we can see if after loading it again it |
127 // is still there. | 127 // is still there. |
128 store_ = NULL; | 128 store_ = NULL; |
129 scoped_refptr<base::ThreadTestHelper> helper( | 129 scoped_refptr<base::ThreadTestHelper> helper( |
130 new base::ThreadTestHelper( | 130 new base::ThreadTestHelper( |
131 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | 131 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); |
132 // Make sure we wait until the destructor has run. | 132 // Make sure we wait until the destructor has run. |
133 ASSERT_TRUE(helper->Run()); | 133 ASSERT_TRUE(helper->Run()); |
134 store_ = new SQLiteOriginBoundCertStore( | 134 store_ = new SQLiteServerBoundCertStore( |
135 temp_dir_.path().Append(chrome::kOBCertFilename)); | 135 temp_dir_.path().Append(chrome::kOBCertFilename)); |
136 | 136 |
137 // Reload and test for persistence | 137 // Reload and test for persistence |
138 ASSERT_TRUE(store_->Load(&certs.get())); | 138 ASSERT_TRUE(store_->Load(&certs.get())); |
139 ASSERT_EQ(2U, certs.size()); | 139 ASSERT_EQ(2U, certs.size()); |
140 net::DefaultOriginBoundCertStore::OriginBoundCert* ec_cert; | 140 net::DefaultServerBoundCertStore::ServerBoundCert* ec_cert; |
141 net::DefaultOriginBoundCertStore::OriginBoundCert* rsa_cert; | 141 net::DefaultServerBoundCertStore::ServerBoundCert* rsa_cert; |
142 if (net::CLIENT_CERT_RSA_SIGN == certs[0]->type()) { | 142 if (net::CLIENT_CERT_RSA_SIGN == certs[0]->type()) { |
143 rsa_cert = certs[0]; | 143 rsa_cert = certs[0]; |
144 ec_cert = certs[1]; | 144 ec_cert = certs[1]; |
145 } else { | 145 } else { |
146 rsa_cert = certs[1]; | 146 rsa_cert = certs[1]; |
147 ec_cert = certs[0]; | 147 ec_cert = certs[0]; |
148 } | 148 } |
149 ASSERT_STREQ("https://encrypted.google.com:8443", rsa_cert->origin().c_str()); | 149 ASSERT_STREQ("google.com", rsa_cert->server_identifier().c_str()); |
150 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, rsa_cert->type()); | 150 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, rsa_cert->type()); |
151 ASSERT_STREQ("a", rsa_cert->private_key().c_str()); | 151 ASSERT_STREQ("a", rsa_cert->private_key().c_str()); |
152 ASSERT_STREQ("b", rsa_cert->cert().c_str()); | 152 ASSERT_STREQ("b", rsa_cert->cert().c_str()); |
153 ASSERT_EQ(1, rsa_cert->creation_time().ToInternalValue()); | 153 ASSERT_EQ(1, rsa_cert->creation_time().ToInternalValue()); |
154 ASSERT_EQ(2, rsa_cert->expiration_time().ToInternalValue()); | 154 ASSERT_EQ(2, rsa_cert->expiration_time().ToInternalValue()); |
155 ASSERT_STREQ("https://www.google.com/", ec_cert->origin().c_str()); | 155 ASSERT_STREQ("foo.com", ec_cert->server_identifier().c_str()); |
156 ASSERT_EQ(net::CLIENT_CERT_ECDSA_SIGN, ec_cert->type()); | 156 ASSERT_EQ(net::CLIENT_CERT_ECDSA_SIGN, ec_cert->type()); |
157 ASSERT_STREQ("c", ec_cert->private_key().c_str()); | 157 ASSERT_STREQ("c", ec_cert->private_key().c_str()); |
158 ASSERT_STREQ("d", ec_cert->cert().c_str()); | 158 ASSERT_STREQ("d", ec_cert->cert().c_str()); |
159 ASSERT_EQ(3, ec_cert->creation_time().ToInternalValue()); | 159 ASSERT_EQ(3, ec_cert->creation_time().ToInternalValue()); |
160 ASSERT_EQ(4, ec_cert->expiration_time().ToInternalValue()); | 160 ASSERT_EQ(4, ec_cert->expiration_time().ToInternalValue()); |
161 | 161 |
162 // Now delete the cert and check persistence again. | 162 // Now delete the cert and check persistence again. |
163 store_->DeleteOriginBoundCert(*certs[0]); | 163 store_->DeleteServerBoundCert(*certs[0]); |
164 store_->DeleteOriginBoundCert(*certs[1]); | 164 store_->DeleteServerBoundCert(*certs[1]); |
165 store_ = NULL; | 165 store_ = NULL; |
166 // Make sure we wait until the destructor has run. | 166 // Make sure we wait until the destructor has run. |
167 ASSERT_TRUE(helper->Run()); | 167 ASSERT_TRUE(helper->Run()); |
168 certs.reset(); | 168 certs.reset(); |
169 store_ = new SQLiteOriginBoundCertStore( | 169 store_ = new SQLiteServerBoundCertStore( |
170 temp_dir_.path().Append(chrome::kOBCertFilename)); | 170 temp_dir_.path().Append(chrome::kOBCertFilename)); |
171 | 171 |
172 // Reload and check if the cert has been removed. | 172 // Reload and check if the cert has been removed. |
173 ASSERT_TRUE(store_->Load(&certs.get())); | 173 ASSERT_TRUE(store_->Load(&certs.get())); |
174 ASSERT_EQ(0U, certs.size()); | 174 ASSERT_EQ(0U, certs.size()); |
175 } | 175 } |
176 | 176 |
177 TEST_F(SQLiteOriginBoundCertStoreTest, TestUpgradeV1) { | 177 TEST_F(SQLiteServerBoundCertStoreTest, TestUpgradeV1) { |
178 // Reset the store. We'll be using a different database for this test. | 178 // Reset the store. We'll be using a different database for this test. |
179 store_ = NULL; | 179 store_ = NULL; |
180 | 180 |
181 FilePath v1_db_path(temp_dir_.path().AppendASCII("v1db")); | 181 FilePath v1_db_path(temp_dir_.path().AppendASCII("v1db")); |
182 | 182 |
183 std::string key_data; | 183 std::string key_data; |
184 std::string cert_data; | 184 std::string cert_data; |
185 ReadTestKeyAndCert(&key_data, &cert_data); | 185 ReadTestKeyAndCert(&key_data, &cert_data); |
186 | 186 |
187 // Create a version 1 database. | 187 // Create a version 1 database. |
188 { | 188 { |
189 sql::Connection db; | 189 sql::Connection db; |
190 ASSERT_TRUE(db.Open(v1_db_path)); | 190 ASSERT_TRUE(db.Open(v1_db_path)); |
191 ASSERT_TRUE(db.Execute( | 191 ASSERT_TRUE(db.Execute( |
192 "CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY," | 192 "CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY," |
193 "value LONGVARCHAR);" | 193 "value LONGVARCHAR);" |
194 "INSERT INTO \"meta\" VALUES('version','1');" | 194 "INSERT INTO \"meta\" VALUES('version','1');" |
195 "INSERT INTO \"meta\" VALUES('last_compatible_version','1');" | 195 "INSERT INTO \"meta\" VALUES('last_compatible_version','1');" |
196 "CREATE TABLE origin_bound_certs (" | 196 "CREATE TABLE origin_bound_certs (" |
197 "origin TEXT NOT NULL UNIQUE PRIMARY KEY," | 197 "origin TEXT NOT NULL UNIQUE PRIMARY KEY," |
198 "private_key BLOB NOT NULL,cert BLOB NOT NULL);")); | 198 "private_key BLOB NOT NULL,cert BLOB NOT NULL);")); |
199 | 199 |
200 sql::Statement add_smt(db.GetUniqueStatement( | 200 sql::Statement add_smt(db.GetUniqueStatement( |
201 "INSERT INTO origin_bound_certs (origin, private_key, cert) " | 201 "INSERT INTO origin_bound_certs (origin, private_key, cert) " |
202 "VALUES (?,?,?)")); | 202 "VALUES (?,?,?)")); |
203 add_smt.BindString(0, "https://www.google.com:443"); | 203 add_smt.BindString(0, "google.com"); |
204 add_smt.BindBlob(1, key_data.data(), key_data.size()); | 204 add_smt.BindBlob(1, key_data.data(), key_data.size()); |
205 add_smt.BindBlob(2, cert_data.data(), cert_data.size()); | 205 add_smt.BindBlob(2, cert_data.data(), cert_data.size()); |
206 ASSERT_TRUE(add_smt.Run()); | 206 ASSERT_TRUE(add_smt.Run()); |
207 | 207 |
208 ASSERT_TRUE(db.Execute( | 208 ASSERT_TRUE(db.Execute( |
209 "INSERT INTO \"origin_bound_certs\" VALUES(" | 209 "INSERT INTO \"origin_bound_certs\" VALUES(" |
210 "'https://foo.com',X'AA',X'BB');" | 210 "'foo.com',X'AA',X'BB');" |
211 )); | 211 )); |
212 } | 212 } |
213 | 213 |
214 // Load and test the DB contents twice. First time ensures that we can use | 214 // Load and test the DB contents twice. First time ensures that we can use |
215 // the updated values immediately. Second time ensures that the updated | 215 // the updated values immediately. Second time ensures that the updated |
216 // values are stored and read correctly on next load. | 216 // values are stored and read correctly on next load. |
217 for (int i = 0; i < 2; ++i) { | 217 for (int i = 0; i < 2; ++i) { |
218 SCOPED_TRACE(i); | 218 SCOPED_TRACE(i); |
219 | 219 |
220 ScopedVector<net::DefaultOriginBoundCertStore::OriginBoundCert> certs; | 220 ScopedVector<net::DefaultServerBoundCertStore::ServerBoundCert> certs; |
221 store_ = new SQLiteOriginBoundCertStore(v1_db_path); | 221 store_ = new SQLiteServerBoundCertStore(v1_db_path); |
222 | 222 |
223 // Load the database and ensure the certs can be read and are marked as RSA. | 223 // Load the database and ensure the certs can be read and are marked as RSA. |
224 ASSERT_TRUE(store_->Load(&certs.get())); | 224 ASSERT_TRUE(store_->Load(&certs.get())); |
225 ASSERT_EQ(2U, certs.size()); | 225 ASSERT_EQ(2U, certs.size()); |
226 | 226 |
227 ASSERT_STREQ("https://www.google.com:443", certs[0]->origin().c_str()); | 227 ASSERT_STREQ("google.com", certs[0]->server_identifier().c_str()); |
228 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[0]->type()); | 228 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[0]->type()); |
229 ASSERT_EQ(GetTestCertExpirationTime(), | 229 ASSERT_EQ(GetTestCertExpirationTime(), |
230 certs[0]->expiration_time()); | 230 certs[0]->expiration_time()); |
231 ASSERT_EQ(key_data, certs[0]->private_key()); | 231 ASSERT_EQ(key_data, certs[0]->private_key()); |
232 ASSERT_EQ(cert_data, certs[0]->cert()); | 232 ASSERT_EQ(cert_data, certs[0]->cert()); |
233 | 233 |
234 ASSERT_STREQ("https://foo.com", certs[1]->origin().c_str()); | 234 ASSERT_STREQ("foo.com", certs[1]->server_identifier().c_str()); |
235 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[1]->type()); | 235 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[1]->type()); |
236 // Undecodable cert, expiration time will be uninitialized. | 236 // Undecodable cert, expiration time will be uninitialized. |
237 ASSERT_EQ(base::Time(), certs[1]->expiration_time()); | 237 ASSERT_EQ(base::Time(), certs[1]->expiration_time()); |
238 ASSERT_STREQ("\xaa", certs[1]->private_key().c_str()); | 238 ASSERT_STREQ("\xaa", certs[1]->private_key().c_str()); |
239 ASSERT_STREQ("\xbb", certs[1]->cert().c_str()); | 239 ASSERT_STREQ("\xbb", certs[1]->cert().c_str()); |
240 | 240 |
241 store_ = NULL; | 241 store_ = NULL; |
242 // Make sure we wait until the destructor has run. | 242 // Make sure we wait until the destructor has run. |
243 scoped_refptr<base::ThreadTestHelper> helper( | 243 scoped_refptr<base::ThreadTestHelper> helper( |
244 new base::ThreadTestHelper( | 244 new base::ThreadTestHelper( |
245 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | 245 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); |
246 ASSERT_TRUE(helper->Run()); | 246 ASSERT_TRUE(helper->Run()); |
247 | 247 |
248 // Verify the database version is updated. | 248 // Verify the database version is updated. |
249 { | 249 { |
250 sql::Connection db; | 250 sql::Connection db; |
251 ASSERT_TRUE(db.Open(v1_db_path)); | 251 ASSERT_TRUE(db.Open(v1_db_path)); |
252 sql::Statement smt(db.GetUniqueStatement( | 252 sql::Statement smt(db.GetUniqueStatement( |
253 "SELECT value FROM meta WHERE key = \"version\"")); | 253 "SELECT value FROM meta WHERE key = \"version\"")); |
254 ASSERT_TRUE(smt.Step()); | 254 ASSERT_TRUE(smt.Step()); |
255 EXPECT_EQ(4, smt.ColumnInt(0)); | 255 EXPECT_EQ(4, smt.ColumnInt(0)); |
256 EXPECT_FALSE(smt.Step()); | 256 EXPECT_FALSE(smt.Step()); |
257 } | 257 } |
258 } | 258 } |
259 } | 259 } |
260 | 260 |
261 TEST_F(SQLiteOriginBoundCertStoreTest, TestUpgradeV2) { | 261 TEST_F(SQLiteServerBoundCertStoreTest, TestUpgradeV2) { |
262 // Reset the store. We'll be using a different database for this test. | 262 // Reset the store. We'll be using a different database for this test. |
263 store_ = NULL; | 263 store_ = NULL; |
264 | 264 |
265 FilePath v2_db_path(temp_dir_.path().AppendASCII("v2db")); | 265 FilePath v2_db_path(temp_dir_.path().AppendASCII("v2db")); |
266 | 266 |
267 std::string key_data; | 267 std::string key_data; |
268 std::string cert_data; | 268 std::string cert_data; |
269 ReadTestKeyAndCert(&key_data, &cert_data); | 269 ReadTestKeyAndCert(&key_data, &cert_data); |
270 | 270 |
271 // Create a version 2 database. | 271 // Create a version 2 database. |
272 { | 272 { |
273 sql::Connection db; | 273 sql::Connection db; |
274 ASSERT_TRUE(db.Open(v2_db_path)); | 274 ASSERT_TRUE(db.Open(v2_db_path)); |
275 ASSERT_TRUE(db.Execute( | 275 ASSERT_TRUE(db.Execute( |
276 "CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY," | 276 "CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY," |
277 "value LONGVARCHAR);" | 277 "value LONGVARCHAR);" |
278 "INSERT INTO \"meta\" VALUES('version','2');" | 278 "INSERT INTO \"meta\" VALUES('version','2');" |
279 "INSERT INTO \"meta\" VALUES('last_compatible_version','1');" | 279 "INSERT INTO \"meta\" VALUES('last_compatible_version','1');" |
280 "CREATE TABLE origin_bound_certs (" | 280 "CREATE TABLE origin_bound_certs (" |
281 "origin TEXT NOT NULL UNIQUE PRIMARY KEY," | 281 "origin TEXT NOT NULL UNIQUE PRIMARY KEY," |
282 "private_key BLOB NOT NULL," | 282 "private_key BLOB NOT NULL," |
283 "cert BLOB NOT NULL," | 283 "cert BLOB NOT NULL," |
284 "cert_type INTEGER);" | 284 "cert_type INTEGER);" |
285 )); | 285 )); |
286 | 286 |
287 sql::Statement add_smt(db.GetUniqueStatement( | 287 sql::Statement add_smt(db.GetUniqueStatement( |
288 "INSERT INTO origin_bound_certs (origin, private_key, cert, cert_type) " | 288 "INSERT INTO origin_bound_certs (origin, private_key, cert, cert_type) " |
289 "VALUES (?,?,?,?)")); | 289 "VALUES (?,?,?,?)")); |
290 add_smt.BindString(0, "https://www.google.com:443"); | 290 add_smt.BindString(0, "google.com"); |
291 add_smt.BindBlob(1, key_data.data(), key_data.size()); | 291 add_smt.BindBlob(1, key_data.data(), key_data.size()); |
292 add_smt.BindBlob(2, cert_data.data(), cert_data.size()); | 292 add_smt.BindBlob(2, cert_data.data(), cert_data.size()); |
293 add_smt.BindInt64(3, 1); | 293 add_smt.BindInt64(3, 1); |
294 ASSERT_TRUE(add_smt.Run()); | 294 ASSERT_TRUE(add_smt.Run()); |
295 | 295 |
296 ASSERT_TRUE(db.Execute( | 296 ASSERT_TRUE(db.Execute( |
297 "INSERT INTO \"origin_bound_certs\" VALUES(" | 297 "INSERT INTO \"origin_bound_certs\" VALUES(" |
298 "'https://foo.com',X'AA',X'BB',64);" | 298 "'foo.com',X'AA',X'BB',64);" |
299 )); | 299 )); |
300 } | 300 } |
301 | 301 |
302 // Load and test the DB contents twice. First time ensures that we can use | 302 // Load and test the DB contents twice. First time ensures that we can use |
303 // the updated values immediately. Second time ensures that the updated | 303 // the updated values immediately. Second time ensures that the updated |
304 // values are saved and read correctly on next load. | 304 // values are saved and read correctly on next load. |
305 for (int i = 0; i < 2; ++i) { | 305 for (int i = 0; i < 2; ++i) { |
306 SCOPED_TRACE(i); | 306 SCOPED_TRACE(i); |
307 | 307 |
308 ScopedVector<net::DefaultOriginBoundCertStore::OriginBoundCert> certs; | 308 ScopedVector<net::DefaultServerBoundCertStore::ServerBoundCert> certs; |
309 store_ = new SQLiteOriginBoundCertStore(v2_db_path); | 309 store_ = new SQLiteServerBoundCertStore(v2_db_path); |
310 | 310 |
311 // Load the database and ensure the certs can be read and are marked as RSA. | 311 // Load the database and ensure the certs can be read and are marked as RSA. |
312 ASSERT_TRUE(store_->Load(&certs.get())); | 312 ASSERT_TRUE(store_->Load(&certs.get())); |
313 ASSERT_EQ(2U, certs.size()); | 313 ASSERT_EQ(2U, certs.size()); |
314 | 314 |
315 ASSERT_STREQ("https://www.google.com:443", certs[0]->origin().c_str()); | 315 ASSERT_STREQ("google.com", certs[0]->server_identifier().c_str()); |
316 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[0]->type()); | 316 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[0]->type()); |
317 ASSERT_EQ(GetTestCertExpirationTime(), | 317 ASSERT_EQ(GetTestCertExpirationTime(), |
318 certs[0]->expiration_time()); | 318 certs[0]->expiration_time()); |
319 ASSERT_EQ(key_data, certs[0]->private_key()); | 319 ASSERT_EQ(key_data, certs[0]->private_key()); |
320 ASSERT_EQ(cert_data, certs[0]->cert()); | 320 ASSERT_EQ(cert_data, certs[0]->cert()); |
321 | 321 |
322 ASSERT_STREQ("https://foo.com", certs[1]->origin().c_str()); | 322 ASSERT_STREQ("foo.com", certs[1]->server_identifier().c_str()); |
323 ASSERT_EQ(net::CLIENT_CERT_ECDSA_SIGN, certs[1]->type()); | 323 ASSERT_EQ(net::CLIENT_CERT_ECDSA_SIGN, certs[1]->type()); |
324 // Undecodable cert, expiration time will be uninitialized. | 324 // Undecodable cert, expiration time will be uninitialized. |
325 ASSERT_EQ(base::Time(), certs[1]->expiration_time()); | 325 ASSERT_EQ(base::Time(), certs[1]->expiration_time()); |
326 ASSERT_STREQ("\xaa", certs[1]->private_key().c_str()); | 326 ASSERT_STREQ("\xaa", certs[1]->private_key().c_str()); |
327 ASSERT_STREQ("\xbb", certs[1]->cert().c_str()); | 327 ASSERT_STREQ("\xbb", certs[1]->cert().c_str()); |
328 | 328 |
329 store_ = NULL; | 329 store_ = NULL; |
330 // Make sure we wait until the destructor has run. | 330 // Make sure we wait until the destructor has run. |
331 scoped_refptr<base::ThreadTestHelper> helper( | 331 scoped_refptr<base::ThreadTestHelper> helper( |
332 new base::ThreadTestHelper( | 332 new base::ThreadTestHelper( |
333 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | 333 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); |
334 ASSERT_TRUE(helper->Run()); | 334 ASSERT_TRUE(helper->Run()); |
335 | 335 |
336 // Verify the database version is updated. | 336 // Verify the database version is updated. |
337 { | 337 { |
338 sql::Connection db; | 338 sql::Connection db; |
339 ASSERT_TRUE(db.Open(v2_db_path)); | 339 ASSERT_TRUE(db.Open(v2_db_path)); |
340 sql::Statement smt(db.GetUniqueStatement( | 340 sql::Statement smt(db.GetUniqueStatement( |
341 "SELECT value FROM meta WHERE key = \"version\"")); | 341 "SELECT value FROM meta WHERE key = \"version\"")); |
342 ASSERT_TRUE(smt.Step()); | 342 ASSERT_TRUE(smt.Step()); |
343 EXPECT_EQ(4, smt.ColumnInt(0)); | 343 EXPECT_EQ(4, smt.ColumnInt(0)); |
344 EXPECT_FALSE(smt.Step()); | 344 EXPECT_FALSE(smt.Step()); |
345 } | 345 } |
346 } | 346 } |
347 } | 347 } |
348 | 348 |
349 TEST_F(SQLiteOriginBoundCertStoreTest, TestUpgradeV3) { | 349 TEST_F(SQLiteServerBoundCertStoreTest, TestUpgradeV3) { |
350 // Reset the store. We'll be using a different database for this test. | 350 // Reset the store. We'll be using a different database for this test. |
351 store_ = NULL; | 351 store_ = NULL; |
352 | 352 |
353 FilePath v3_db_path(temp_dir_.path().AppendASCII("v3db")); | 353 FilePath v3_db_path(temp_dir_.path().AppendASCII("v3db")); |
354 | 354 |
355 std::string key_data; | 355 std::string key_data; |
356 std::string cert_data; | 356 std::string cert_data; |
357 ReadTestKeyAndCert(&key_data, &cert_data); | 357 ReadTestKeyAndCert(&key_data, &cert_data); |
358 | 358 |
359 // Create a version 3 database. | 359 // Create a version 3 database. |
360 { | 360 { |
361 sql::Connection db; | 361 sql::Connection db; |
362 ASSERT_TRUE(db.Open(v3_db_path)); | 362 ASSERT_TRUE(db.Open(v3_db_path)); |
363 ASSERT_TRUE(db.Execute( | 363 ASSERT_TRUE(db.Execute( |
364 "CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY," | 364 "CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY," |
365 "value LONGVARCHAR);" | 365 "value LONGVARCHAR);" |
366 "INSERT INTO \"meta\" VALUES('version','3');" | 366 "INSERT INTO \"meta\" VALUES('version','3');" |
367 "INSERT INTO \"meta\" VALUES('last_compatible_version','1');" | 367 "INSERT INTO \"meta\" VALUES('last_compatible_version','1');" |
368 "CREATE TABLE origin_bound_certs (" | 368 "CREATE TABLE origin_bound_certs (" |
369 "origin TEXT NOT NULL UNIQUE PRIMARY KEY," | 369 "origin TEXT NOT NULL UNIQUE PRIMARY KEY," |
370 "private_key BLOB NOT NULL," | 370 "private_key BLOB NOT NULL," |
371 "cert BLOB NOT NULL," | 371 "cert BLOB NOT NULL," |
372 "cert_type INTEGER," | 372 "cert_type INTEGER," |
373 "expiration_time INTEGER);" | 373 "expiration_time INTEGER);" |
374 )); | 374 )); |
375 | 375 |
376 sql::Statement add_smt(db.GetUniqueStatement( | 376 sql::Statement add_smt(db.GetUniqueStatement( |
377 "INSERT INTO origin_bound_certs (origin, private_key, cert, cert_type, " | 377 "INSERT INTO origin_bound_certs (origin, private_key, cert, cert_type, " |
378 "expiration_time) VALUES (?,?,?,?,?)")); | 378 "expiration_time) VALUES (?,?,?,?,?)")); |
379 add_smt.BindString(0, "https://www.google.com:443"); | 379 add_smt.BindString(0, "google.com"); |
380 add_smt.BindBlob(1, key_data.data(), key_data.size()); | 380 add_smt.BindBlob(1, key_data.data(), key_data.size()); |
381 add_smt.BindBlob(2, cert_data.data(), cert_data.size()); | 381 add_smt.BindBlob(2, cert_data.data(), cert_data.size()); |
382 add_smt.BindInt64(3, 1); | 382 add_smt.BindInt64(3, 1); |
383 add_smt.BindInt64(4, 1000); | 383 add_smt.BindInt64(4, 1000); |
384 ASSERT_TRUE(add_smt.Run()); | 384 ASSERT_TRUE(add_smt.Run()); |
385 | 385 |
386 ASSERT_TRUE(db.Execute( | 386 ASSERT_TRUE(db.Execute( |
387 "INSERT INTO \"origin_bound_certs\" VALUES(" | 387 "INSERT INTO \"origin_bound_certs\" VALUES(" |
388 "'https://foo.com',X'AA',X'BB',64,2000);" | 388 "'foo.com',X'AA',X'BB',64,2000);" |
389 )); | 389 )); |
390 } | 390 } |
391 | 391 |
392 // Load and test the DB contents twice. First time ensures that we can use | 392 // Load and test the DB contents twice. First time ensures that we can use |
393 // the updated values immediately. Second time ensures that the updated | 393 // the updated values immediately. Second time ensures that the updated |
394 // values are saved and read correctly on next load. | 394 // values are saved and read correctly on next load. |
395 for (int i = 0; i < 2; ++i) { | 395 for (int i = 0; i < 2; ++i) { |
396 SCOPED_TRACE(i); | 396 SCOPED_TRACE(i); |
397 | 397 |
398 ScopedVector<net::DefaultOriginBoundCertStore::OriginBoundCert> certs; | 398 ScopedVector<net::DefaultServerBoundCertStore::ServerBoundCert> certs; |
399 store_ = new SQLiteOriginBoundCertStore(v3_db_path); | 399 store_ = new SQLiteServerBoundCertStore(v3_db_path); |
400 | 400 |
401 // Load the database and ensure the certs can be read and are marked as RSA. | 401 // Load the database and ensure the certs can be read and are marked as RSA. |
402 ASSERT_TRUE(store_->Load(&certs.get())); | 402 ASSERT_TRUE(store_->Load(&certs.get())); |
403 ASSERT_EQ(2U, certs.size()); | 403 ASSERT_EQ(2U, certs.size()); |
404 | 404 |
405 ASSERT_STREQ("https://www.google.com:443", certs[0]->origin().c_str()); | 405 ASSERT_STREQ("google.com", certs[0]->server_identifier().c_str()); |
406 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[0]->type()); | 406 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[0]->type()); |
407 ASSERT_EQ(1000, certs[0]->expiration_time().ToInternalValue()); | 407 ASSERT_EQ(1000, certs[0]->expiration_time().ToInternalValue()); |
408 ASSERT_EQ(GetTestCertCreationTime(), | 408 ASSERT_EQ(GetTestCertCreationTime(), |
409 certs[0]->creation_time()); | 409 certs[0]->creation_time()); |
410 ASSERT_EQ(key_data, certs[0]->private_key()); | 410 ASSERT_EQ(key_data, certs[0]->private_key()); |
411 ASSERT_EQ(cert_data, certs[0]->cert()); | 411 ASSERT_EQ(cert_data, certs[0]->cert()); |
412 | 412 |
413 ASSERT_STREQ("https://foo.com", certs[1]->origin().c_str()); | 413 ASSERT_STREQ("foo.com", certs[1]->server_identifier().c_str()); |
414 ASSERT_EQ(net::CLIENT_CERT_ECDSA_SIGN, certs[1]->type()); | 414 ASSERT_EQ(net::CLIENT_CERT_ECDSA_SIGN, certs[1]->type()); |
415 ASSERT_EQ(2000, certs[1]->expiration_time().ToInternalValue()); | 415 ASSERT_EQ(2000, certs[1]->expiration_time().ToInternalValue()); |
416 // Undecodable cert, creation time will be uninitialized. | 416 // Undecodable cert, creation time will be uninitialized. |
417 ASSERT_EQ(base::Time(), certs[1]->creation_time()); | 417 ASSERT_EQ(base::Time(), certs[1]->creation_time()); |
418 ASSERT_STREQ("\xaa", certs[1]->private_key().c_str()); | 418 ASSERT_STREQ("\xaa", certs[1]->private_key().c_str()); |
419 ASSERT_STREQ("\xbb", certs[1]->cert().c_str()); | 419 ASSERT_STREQ("\xbb", certs[1]->cert().c_str()); |
420 | 420 |
421 store_ = NULL; | 421 store_ = NULL; |
422 // Make sure we wait until the destructor has run. | 422 // Make sure we wait until the destructor has run. |
423 scoped_refptr<base::ThreadTestHelper> helper( | 423 scoped_refptr<base::ThreadTestHelper> helper( |
424 new base::ThreadTestHelper( | 424 new base::ThreadTestHelper( |
425 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | 425 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); |
426 ASSERT_TRUE(helper->Run()); | 426 ASSERT_TRUE(helper->Run()); |
427 | 427 |
428 // Verify the database version is updated. | 428 // Verify the database version is updated. |
429 { | 429 { |
430 sql::Connection db; | 430 sql::Connection db; |
431 ASSERT_TRUE(db.Open(v3_db_path)); | 431 ASSERT_TRUE(db.Open(v3_db_path)); |
432 sql::Statement smt(db.GetUniqueStatement( | 432 sql::Statement smt(db.GetUniqueStatement( |
433 "SELECT value FROM meta WHERE key = \"version\"")); | 433 "SELECT value FROM meta WHERE key = \"version\"")); |
434 ASSERT_TRUE(smt.Step()); | 434 ASSERT_TRUE(smt.Step()); |
435 EXPECT_EQ(4, smt.ColumnInt(0)); | 435 EXPECT_EQ(4, smt.ColumnInt(0)); |
436 EXPECT_FALSE(smt.Step()); | 436 EXPECT_FALSE(smt.Step()); |
437 } | 437 } |
438 } | 438 } |
439 } | 439 } |
440 | 440 |
441 // Test that we can force the database to be written by calling Flush(). | 441 // Test that we can force the database to be written by calling Flush(). |
442 TEST_F(SQLiteOriginBoundCertStoreTest, TestFlush) { | 442 TEST_F(SQLiteServerBoundCertStoreTest, TestFlush) { |
443 // File timestamps don't work well on all platforms, so we'll determine | 443 // File timestamps don't work well on all platforms, so we'll determine |
444 // whether the DB file has been modified by checking its size. | 444 // whether the DB file has been modified by checking its size. |
445 FilePath path = temp_dir_.path().Append(chrome::kOBCertFilename); | 445 FilePath path = temp_dir_.path().Append(chrome::kOBCertFilename); |
446 base::PlatformFileInfo info; | 446 base::PlatformFileInfo info; |
447 ASSERT_TRUE(file_util::GetFileInfo(path, &info)); | 447 ASSERT_TRUE(file_util::GetFileInfo(path, &info)); |
448 int64 base_size = info.size; | 448 int64 base_size = info.size; |
449 | 449 |
450 // Write some certs, so the DB will have to expand by several KB. | 450 // Write some certs, so the DB will have to expand by several KB. |
451 for (char c = 'a'; c < 'z'; ++c) { | 451 for (char c = 'a'; c < 'z'; ++c) { |
452 std::string origin(1, c); | 452 std::string server_identifier(1, c); |
453 std::string private_key(1000, c); | 453 std::string private_key(1000, c); |
454 std::string cert(1000, c); | 454 std::string cert(1000, c); |
455 store_->AddOriginBoundCert( | 455 store_->AddServerBoundCert( |
456 net::DefaultOriginBoundCertStore::OriginBoundCert( | 456 net::DefaultServerBoundCertStore::ServerBoundCert( |
457 origin, | 457 server_identifier, |
458 net::CLIENT_CERT_RSA_SIGN, | 458 net::CLIENT_CERT_RSA_SIGN, |
459 base::Time(), | 459 base::Time(), |
460 base::Time(), | 460 base::Time(), |
461 private_key, | 461 private_key, |
462 cert)); | 462 cert)); |
463 } | 463 } |
464 | 464 |
465 // Call Flush() and wait until the DB thread is idle. | 465 // Call Flush() and wait until the DB thread is idle. |
466 store_->Flush(base::Closure()); | 466 store_->Flush(base::Closure()); |
467 scoped_refptr<base::ThreadTestHelper> helper( | 467 scoped_refptr<base::ThreadTestHelper> helper( |
(...skipping 18 matching lines...) Expand all Loading... |
486 int callback_count() { | 486 int callback_count() { |
487 return callback_count_; | 487 return callback_count_; |
488 } | 488 } |
489 | 489 |
490 private: | 490 private: |
491 friend class base::RefCountedThreadSafe<CallbackCounter>; | 491 friend class base::RefCountedThreadSafe<CallbackCounter>; |
492 volatile int callback_count_; | 492 volatile int callback_count_; |
493 }; | 493 }; |
494 | 494 |
495 // Test that we can get a completion callback after a Flush(). | 495 // Test that we can get a completion callback after a Flush(). |
496 TEST_F(SQLiteOriginBoundCertStoreTest, TestFlushCompletionCallback) { | 496 TEST_F(SQLiteServerBoundCertStoreTest, TestFlushCompletionCallback) { |
497 scoped_refptr<CallbackCounter> counter(new CallbackCounter()); | 497 scoped_refptr<CallbackCounter> counter(new CallbackCounter()); |
498 | 498 |
499 // Callback shouldn't be invoked until we call Flush(). | 499 // Callback shouldn't be invoked until we call Flush(). |
500 ASSERT_EQ(0, counter->callback_count()); | 500 ASSERT_EQ(0, counter->callback_count()); |
501 | 501 |
502 store_->Flush(base::Bind(&CallbackCounter::Callback, counter.get())); | 502 store_->Flush(base::Bind(&CallbackCounter::Callback, counter.get())); |
503 | 503 |
504 scoped_refptr<base::ThreadTestHelper> helper( | 504 scoped_refptr<base::ThreadTestHelper> helper( |
505 new base::ThreadTestHelper( | 505 new base::ThreadTestHelper( |
506 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | 506 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); |
507 ASSERT_TRUE(helper->Run()); | 507 ASSERT_TRUE(helper->Run()); |
508 | 508 |
509 ASSERT_EQ(1, counter->callback_count()); | 509 ASSERT_EQ(1, counter->callback_count()); |
510 } | 510 } |
OLD | NEW |