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

Side by Side Diff: chrome/browser/net/sqlite_origin_bound_cert_store_unittest.cc

Issue 8662036: Support EC certs in OriginBoundCertService and OriginBoundCertStore. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review changes Created 9 years 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/scoped_temp_dir.h" 9 #include "base/scoped_temp_dir.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "base/test/thread_test_helper.h" 11 #include "base/test/thread_test_helper.h"
12 #include "chrome/browser/net/sqlite_origin_bound_cert_store.h" 12 #include "chrome/browser/net/sqlite_origin_bound_cert_store.h"
13 #include "chrome/common/chrome_constants.h" 13 #include "chrome/common/chrome_constants.h"
14 #include "content/test/test_browser_thread.h" 14 #include "content/test/test_browser_thread.h"
15 #include "sql/statement.h"
15 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
16 17
17 using content::BrowserThread; 18 using content::BrowserThread;
18 19
19 class SQLiteOriginBoundCertStoreTest : public testing::Test { 20 class SQLiteOriginBoundCertStoreTest : public testing::Test {
20 public: 21 public:
21 SQLiteOriginBoundCertStoreTest() 22 SQLiteOriginBoundCertStoreTest()
22 : db_thread_(BrowserThread::DB) { 23 : db_thread_(BrowserThread::DB) {
23 } 24 }
24 25
25 protected: 26 protected:
26 virtual void SetUp() { 27 virtual void SetUp() {
27 db_thread_.Start(); 28 db_thread_.Start();
28 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 29 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
29 store_ = new SQLiteOriginBoundCertStore( 30 store_ = new SQLiteOriginBoundCertStore(
30 temp_dir_.path().Append(chrome::kOBCertFilename)); 31 temp_dir_.path().Append(chrome::kOBCertFilename));
31 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs; 32 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs;
32 ASSERT_TRUE(store_->Load(&certs)); 33 ASSERT_TRUE(store_->Load(&certs));
33 ASSERT_EQ(0u, certs.size()); 34 ASSERT_EQ(0u, certs.size());
34 // Make sure the store gets written at least once. 35 // Make sure the store gets written at least once.
35 store_->AddOriginBoundCert( 36 store_->AddOriginBoundCert(
36 net::DefaultOriginBoundCertStore::OriginBoundCert( 37 net::DefaultOriginBoundCertStore::OriginBoundCert(
37 "https://encrypted.google.com:8443", "a", "b")); 38 "https://encrypted.google.com:8443",
39 net::CLIENT_CERT_RSA_SIGN, "a", "b"));
38 } 40 }
39 41
40 content::TestBrowserThread db_thread_; 42 content::TestBrowserThread db_thread_;
41 ScopedTempDir temp_dir_; 43 ScopedTempDir temp_dir_;
42 scoped_refptr<SQLiteOriginBoundCertStore> store_; 44 scoped_refptr<SQLiteOriginBoundCertStore> store_;
43 }; 45 };
44 46
45 TEST_F(SQLiteOriginBoundCertStoreTest, KeepOnDestruction) { 47 TEST_F(SQLiteOriginBoundCertStoreTest, KeepOnDestruction) {
46 store_->SetClearLocalStateOnExit(false); 48 store_->SetClearLocalStateOnExit(false);
47 store_ = NULL; 49 store_ = NULL;
(...skipping 20 matching lines...) Expand all
68 new base::ThreadTestHelper( 70 new base::ThreadTestHelper(
69 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); 71 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)));
70 ASSERT_TRUE(helper->Run()); 72 ASSERT_TRUE(helper->Run());
71 73
72 ASSERT_FALSE(file_util::PathExists( 74 ASSERT_FALSE(file_util::PathExists(
73 temp_dir_.path().Append(chrome::kOBCertFilename))); 75 temp_dir_.path().Append(chrome::kOBCertFilename)));
74 } 76 }
75 77
76 // Test if data is stored as expected in the SQLite database. 78 // Test if data is stored as expected in the SQLite database.
77 TEST_F(SQLiteOriginBoundCertStoreTest, TestPersistence) { 79 TEST_F(SQLiteOriginBoundCertStoreTest, TestPersistence) {
80 store_->AddOriginBoundCert(
81 net::DefaultOriginBoundCertStore::OriginBoundCert(
82 "https://www.google.com/", net::CLIENT_CERT_ECDSA_SIGN, "c", "d"));
83
78 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs; 84 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs;
79 // Replace the store effectively destroying the current one and forcing it 85 // Replace the store effectively destroying the current one and forcing it
80 // to write it's data to disk. Then we can see if after loading it again it 86 // to write it's data to disk. Then we can see if after loading it again it
81 // is still there. 87 // is still there.
82 store_ = NULL; 88 store_ = NULL;
83 scoped_refptr<base::ThreadTestHelper> helper( 89 scoped_refptr<base::ThreadTestHelper> helper(
84 new base::ThreadTestHelper( 90 new base::ThreadTestHelper(
85 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); 91 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)));
86 // Make sure we wait until the destructor has run. 92 // Make sure we wait until the destructor has run.
87 ASSERT_TRUE(helper->Run()); 93 ASSERT_TRUE(helper->Run());
88 store_ = new SQLiteOriginBoundCertStore( 94 store_ = new SQLiteOriginBoundCertStore(
89 temp_dir_.path().Append(chrome::kOBCertFilename)); 95 temp_dir_.path().Append(chrome::kOBCertFilename));
90 96
91 // Reload and test for persistence 97 // Reload and test for persistence
92 ASSERT_TRUE(store_->Load(&certs)); 98 ASSERT_TRUE(store_->Load(&certs));
93 ASSERT_EQ(1U, certs.size()); 99 ASSERT_EQ(2U, certs.size());
94 ASSERT_STREQ("https://encrypted.google.com:8443", certs[0]->origin().c_str()); 100 net::DefaultOriginBoundCertStore::OriginBoundCert* ec_cert;
95 ASSERT_STREQ("a", certs[0]->private_key().c_str()); 101 net::DefaultOriginBoundCertStore::OriginBoundCert* rsa_cert;
96 ASSERT_STREQ("b", certs[0]->cert().c_str()); 102 if (net::CLIENT_CERT_RSA_SIGN == certs[0]->type()) {
103 rsa_cert = certs[0];
104 ec_cert = certs[1];
105 } else {
106 rsa_cert = certs[1];
107 ec_cert = certs[0];
108 }
109 ASSERT_STREQ("https://encrypted.google.com:8443", rsa_cert->origin().c_str());
110 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, rsa_cert->type());
111 ASSERT_STREQ("a", rsa_cert->private_key().c_str());
112 ASSERT_STREQ("b", rsa_cert->cert().c_str());
113 ASSERT_STREQ("https://www.google.com/", ec_cert->origin().c_str());
114 ASSERT_EQ(net::CLIENT_CERT_ECDSA_SIGN, ec_cert->type());
115 ASSERT_STREQ("c", ec_cert->private_key().c_str());
116 ASSERT_STREQ("d", ec_cert->cert().c_str());
97 117
98 // Now delete the cert and check persistence again. 118 // Now delete the cert and check persistence again.
119 store_->DeleteOriginBoundCert(*certs[1]);
wtc 2011/12/02 22:06:59 Nit: if the order of deleting certs doesn't matter
mattm 2011/12/05 22:19:20 Done.
99 store_->DeleteOriginBoundCert(*certs[0]); 120 store_->DeleteOriginBoundCert(*certs[0]);
100 store_ = NULL; 121 store_ = NULL;
101 // Make sure we wait until the destructor has run. 122 // Make sure we wait until the destructor has run.
102 ASSERT_TRUE(helper->Run()); 123 ASSERT_TRUE(helper->Run());
103 STLDeleteContainerPointers(certs.begin(), certs.end()); 124 STLDeleteContainerPointers(certs.begin(), certs.end());
104 certs.clear(); 125 certs.clear();
105 store_ = new SQLiteOriginBoundCertStore( 126 store_ = new SQLiteOriginBoundCertStore(
106 temp_dir_.path().Append(chrome::kOBCertFilename)); 127 temp_dir_.path().Append(chrome::kOBCertFilename));
107 128
108 // Reload and check if the cert has been removed. 129 // Reload and check if the cert has been removed.
109 ASSERT_TRUE(store_->Load(&certs)); 130 ASSERT_TRUE(store_->Load(&certs));
110 ASSERT_EQ(0U, certs.size()); 131 ASSERT_EQ(0U, certs.size());
111 } 132 }
112 133
134 TEST_F(SQLiteOriginBoundCertStoreTest, TestUpgrade) {
135 // Reset the store. We'll be using a different database for this test.
136 store_ = NULL;
137
138 FilePath v1_db_path(temp_dir_.path().AppendASCII("v1db"));
139
140 // Create a version 1 database.
141 {
142 sql::Connection db;
143 ASSERT_TRUE(db.Open(v1_db_path));
144 ASSERT_TRUE(db.Execute(
145 "CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,"
146 "value LONGVARCHAR);"
147 "INSERT INTO \"meta\" VALUES('version','1');"
148 "INSERT INTO \"meta\" VALUES('last_compatible_version','1');"
149 "CREATE TABLE origin_bound_certs ("
150 "origin TEXT NOT NULL UNIQUE PRIMARY KEY,"
151 "private_key BLOB NOT NULL,cert BLOB NOT NULL);"
152 "INSERT INTO \"origin_bound_certs\" VALUES("
153 "'https://google.com',X'AA',X'BB');"
154 "INSERT INTO \"origin_bound_certs\" VALUES("
155 "'https://foo.com',X'CC',X'DD');"
156 ));
157 }
158
159 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs;
160 store_ = new SQLiteOriginBoundCertStore(v1_db_path);
161
162 // Load the database and ensure the certs can be read and are marked as RSA.
163 ASSERT_TRUE(store_->Load(&certs));
164 ASSERT_EQ(2U, certs.size());
165 ASSERT_STREQ("https://google.com", certs[0]->origin().c_str());
166 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[0]->type());
167 ASSERT_STREQ("\xaa", certs[0]->private_key().c_str());
168 ASSERT_STREQ("\xbb", certs[0]->cert().c_str());
169 ASSERT_STREQ("https://foo.com", certs[1]->origin().c_str());
170 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[1]->type());
171 ASSERT_STREQ("\xcc", certs[1]->private_key().c_str());
172 ASSERT_STREQ("\xdd", certs[1]->cert().c_str());
173
174 STLDeleteContainerPointers(certs.begin(), certs.end());
175 certs.clear();
176
177 store_ = NULL;
178 // Make sure we wait until the destructor has run.
179 scoped_refptr<base::ThreadTestHelper> helper(
180 new base::ThreadTestHelper(
181 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)));
182 ASSERT_TRUE(helper->Run());
183
184 // Verify the database version is updated.
185 {
186 sql::Connection db;
187 ASSERT_TRUE(db.Open(v1_db_path));
188 sql::Statement smt(db.GetUniqueStatement(
189 "SELECT value FROM meta WHERE key = \"version\""));
190 ASSERT_TRUE(smt);
191 ASSERT_TRUE(smt.Step());
192 EXPECT_EQ(2, smt.ColumnInt(0));
193 EXPECT_FALSE(smt.Step());
194 }
195 }
196
113 // Test that we can force the database to be written by calling Flush(). 197 // Test that we can force the database to be written by calling Flush().
114 TEST_F(SQLiteOriginBoundCertStoreTest, TestFlush) { 198 TEST_F(SQLiteOriginBoundCertStoreTest, TestFlush) {
115 // File timestamps don't work well on all platforms, so we'll determine 199 // File timestamps don't work well on all platforms, so we'll determine
116 // whether the DB file has been modified by checking its size. 200 // whether the DB file has been modified by checking its size.
117 FilePath path = temp_dir_.path().Append(chrome::kOBCertFilename); 201 FilePath path = temp_dir_.path().Append(chrome::kOBCertFilename);
118 base::PlatformFileInfo info; 202 base::PlatformFileInfo info;
119 ASSERT_TRUE(file_util::GetFileInfo(path, &info)); 203 ASSERT_TRUE(file_util::GetFileInfo(path, &info));
120 int64 base_size = info.size; 204 int64 base_size = info.size;
121 205
122 // Write some certs, so the DB will have to expand by several KB. 206 // Write some certs, so the DB will have to expand by several KB.
123 for (char c = 'a'; c < 'z'; ++c) { 207 for (char c = 'a'; c < 'z'; ++c) {
124 std::string origin(1, c); 208 std::string origin(1, c);
125 std::string private_key(1000, c); 209 std::string private_key(1000, c);
126 std::string cert(1000, c); 210 std::string cert(1000, c);
127 store_->AddOriginBoundCert( 211 store_->AddOriginBoundCert(
128 net::DefaultOriginBoundCertStore::OriginBoundCert(origin, 212 net::DefaultOriginBoundCertStore::OriginBoundCert(
129 private_key, 213 origin,
130 cert)); 214 net::CLIENT_CERT_RSA_SIGN,
215 private_key,
216 cert));
131 } 217 }
132 218
133 // Call Flush() and wait until the DB thread is idle. 219 // Call Flush() and wait until the DB thread is idle.
134 store_->Flush(base::Closure()); 220 store_->Flush(base::Closure());
135 scoped_refptr<base::ThreadTestHelper> helper( 221 scoped_refptr<base::ThreadTestHelper> helper(
136 new base::ThreadTestHelper( 222 new base::ThreadTestHelper(
137 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); 223 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)));
138 ASSERT_TRUE(helper->Run()); 224 ASSERT_TRUE(helper->Run());
139 225
140 // We forced a write, so now the file will be bigger. 226 // We forced a write, so now the file will be bigger.
(...skipping 28 matching lines...) Expand all
169 255
170 store_->Flush(base::Bind(&CallbackCounter::Callback, counter.get())); 256 store_->Flush(base::Bind(&CallbackCounter::Callback, counter.get()));
171 257
172 scoped_refptr<base::ThreadTestHelper> helper( 258 scoped_refptr<base::ThreadTestHelper> helper(
173 new base::ThreadTestHelper( 259 new base::ThreadTestHelper(
174 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); 260 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)));
175 ASSERT_TRUE(helper->Run()); 261 ASSERT_TRUE(helper->Run());
176 262
177 ASSERT_EQ(1, counter->callback_count()); 263 ASSERT_EQ(1, counter->callback_count());
178 } 264 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698