Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2014 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. | |
| 4 | |
| 5 #include "net/http/disk_based_cert_cache.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/callback_helpers.h" | |
| 9 #include "net/base/completion_callback.h" | |
| 10 #include "net/base/net_errors.h" | |
| 11 #include "net/base/test_completion_callback.h" | |
| 12 #include "net/base/test_data_directory.h" | |
| 13 #include "net/disk_cache/memory/mem_backend_impl.h" | |
| 14 #include "net/http/mock_http_cache.h" | |
| 15 #include "net/test/cert_test_util.h" | |
| 16 #include "testing/gtest/include/gtest/gtest.h" | |
| 17 | |
| 18 namespace net { | |
| 19 | |
| 20 namespace { | |
| 21 | |
| 22 const char kCertTransaction1Key[] = | |
| 23 "cert:4C005EF1CF45F80D4A5A2BCFB00D4F198121E8D4"; | |
| 24 const char kCertTransaction2Key[] = | |
| 25 "cert:9174C7CB9E4919604E7B1BFC430E4929DA45F65F"; | |
| 26 | |
| 27 // MockTransactions are required to use the MockDiskCache backend. | |
| 28 // This transaction corresponds to "root_ca_cert.pem" in | |
| 29 // GetTestCertsDirectory(). | |
| 30 const MockTransaction kCertTransaction1 = { | |
| 31 kCertTransaction1Key, "", base::Time(), "", LOAD_NORMAL, "", "", | |
| 32 base::Time(), "", TEST_MODE_NORMAL, NULL, 0, OK}; | |
| 33 | |
| 34 // This transaction corresponds to "ok_cert.pem" in GetTestCertsDirectory(). | |
| 35 const MockTransaction kCertTransaction2 = { | |
| 36 kCertTransaction2Key, "", base::Time(), "", LOAD_NORMAL, "", "", | |
| 37 base::Time(), "", TEST_MODE_NORMAL, NULL, 0, OK}; | |
| 38 | |
| 39 // MockCertCache is used so that results from the DiskBasedCertCache can be | |
| 40 // received using TestCompletionCallback::GetResult. | |
| 41 class MockCertCache { | |
| 42 public: | |
| 43 MockCertCache() | |
| 44 : backend(new MockDiskCache()), | |
| 45 cert_cache_(new DiskBasedCertCache(backend.get())) {} | |
| 46 | |
| 47 int Set(X509Certificate::OSCertHandle cert_handle, | |
| 48 std::string* key, | |
| 49 const CompletionCallback& callback) { | |
| 50 cert_cache_->Set(cert_handle, | |
| 51 base::Bind(&MockCertCache::OnSetComplete, | |
| 52 base::Unretained(this), | |
| 53 key, | |
| 54 callback)); | |
| 55 return ERR_IO_PENDING; | |
| 56 } | |
| 57 | |
| 58 int Get(const std::string& key, | |
| 59 X509Certificate::OSCertHandle* cert_handle, | |
| 60 const CompletionCallback& callback) { | |
| 61 cert_cache_->Get(key, | |
| 62 base::Bind(&MockCertCache::OnGetComplete, | |
| 63 base::Unretained(this), | |
| 64 cert_handle, | |
| 65 callback)); | |
| 66 return ERR_IO_PENDING; | |
| 67 } | |
| 68 | |
| 69 void OnSetComplete(std::string* key_return, | |
| 70 CompletionCallback callback, | |
| 71 const std::string& key_retrieved) { | |
| 72 *key_return = key_retrieved; | |
| 73 callback.Run(OK); | |
| 74 } | |
| 75 | |
| 76 void OnGetComplete(X509Certificate::OSCertHandle* handle_return, | |
| 77 CompletionCallback callback, | |
| 78 const X509Certificate::OSCertHandle handle_retrieved) { | |
| 79 *handle_return = handle_retrieved; | |
| 80 callback.Run(OK); | |
| 81 } | |
| 82 | |
| 83 void DeleteCertCache() { cert_cache_.reset(); } | |
| 84 | |
| 85 private: | |
| 86 scoped_ptr<disk_cache::Backend> backend; | |
| 87 scoped_ptr<DiskBasedCertCache> cert_cache_; | |
| 88 }; | |
| 89 | |
| 90 } // namespace | |
| 91 | |
| 92 // ---------------------------------------------------------------------------- | |
| 93 | |
| 94 // Tests that a certificate can be stored in the cache. | |
| 95 TEST(DiskBasedCertCache, SetCert) { | |
| 96 AddMockTransaction(&kCertTransaction1); | |
|
Ryan Sleevi
2014/06/24 22:01:00
Notes from discussion/review: You want to use Scop
| |
| 97 MockCertCache user; | |
| 98 scoped_refptr<X509Certificate> cert( | |
| 99 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
| 100 ASSERT_TRUE(cert.get()); | |
| 101 | |
| 102 TestCompletionCallback set_callback; | |
| 103 std::string key; | |
| 104 | |
| 105 int rv = | |
| 106 user.Set(cert.get()->os_cert_handle(), &key, set_callback.callback()); | |
| 107 rv = set_callback.GetResult(rv); | |
| 108 EXPECT_EQ(OK, rv); | |
| 109 EXPECT_FALSE(key.empty()); | |
|
Ryan Sleevi
2014/06/24 22:00:59
Notes from discussion/review:
You should also ver
| |
| 110 } | |
| 111 | |
| 112 // Tests that attempting to retrieve a cert that is not in the cache will | |
| 113 // return NULL. | |
| 114 TEST(DiskBasedCertCache, GetUncachedCert) { | |
| 115 AddMockTransaction(&kCertTransaction1); | |
| 116 MockCertCache user; | |
| 117 TestCompletionCallback get_callback; | |
| 118 X509Certificate::OSCertHandle cert_handle = NULL; | |
| 119 | |
| 120 int rv = | |
| 121 user.Get(kCertTransaction1Key, &cert_handle, get_callback.callback()); | |
| 122 rv = get_callback.GetResult(rv); | |
| 123 EXPECT_EQ(OK, rv); | |
| 124 EXPECT_EQ(NULL, cert_handle); | |
|
Ryan Sleevi
2014/06/24 22:01:00
Notes from discussion/review:
BUG: cert_handle ha
| |
| 125 } | |
| 126 | |
| 127 // Issues two requests to store a certificate in the cache | |
| 128 // (simultaneously), and checks that the DiskBasedCertCache stores the | |
| 129 // certificate to the cache (in one write rather than two). | |
| 130 TEST(DiskBasedCertCache, SetMultiple) { | |
| 131 AddMockTransaction(&kCertTransaction1); | |
| 132 MockCertCache user; | |
| 133 | |
| 134 scoped_refptr<X509Certificate> cert( | |
| 135 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
| 136 ASSERT_TRUE(cert.get()); | |
| 137 | |
| 138 TestCompletionCallback set_callback1; | |
| 139 TestCompletionCallback set_callback2; | |
| 140 | |
| 141 std::string key1, key2; | |
| 142 | |
| 143 int rv1 = | |
| 144 user.Set(cert.get()->os_cert_handle(), &key1, set_callback1.callback()); | |
|
Ryan Sleevi
2014/06/24 22:01:00
Notes from discussion/review:
No need to use "cer
| |
| 145 int rv2 = | |
| 146 user.Set(cert.get()->os_cert_handle(), &key2, set_callback2.callback()); | |
|
Ryan Sleevi
2014/06/24 22:01:00
Notes from discussion/review:
This isn't matching
| |
| 147 | |
| 148 rv1 = set_callback1.GetResult(rv1); | |
| 149 EXPECT_EQ(OK, rv1); | |
| 150 rv2 = set_callback2.GetResult(rv2); | |
| 151 EXPECT_EQ(OK, rv2); | |
| 152 EXPECT_EQ(key1, key2); | |
| 153 } | |
| 154 | |
| 155 // Stores a certificate in the DiskBasedCertCache, then retrieves it | |
| 156 // and makes sure it was retrieved successfully. | |
| 157 TEST(DiskBasedCertCache, SimpleSetAndGet) { | |
| 158 AddMockTransaction(&kCertTransaction1); | |
| 159 MockCertCache user; | |
| 160 | |
| 161 scoped_refptr<X509Certificate> cert( | |
| 162 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
| 163 ASSERT_TRUE(cert.get()); | |
| 164 | |
| 165 TestCompletionCallback set_callback; | |
| 166 TestCompletionCallback get_callback; | |
| 167 std::string key; | |
| 168 | |
| 169 X509Certificate::OSCertHandle retrieved_cert_handle = NULL; | |
| 170 int rv = | |
| 171 user.Set(cert.get()->os_cert_handle(), &key, set_callback.callback()); | |
| 172 rv = set_callback.GetResult(rv); | |
| 173 EXPECT_EQ(OK, rv); | |
| 174 rv = user.Get(key, &retrieved_cert_handle, get_callback.callback()); | |
| 175 rv = get_callback.GetResult(rv); | |
| 176 EXPECT_EQ(OK, rv); | |
| 177 EXPECT_TRUE(X509Certificate::IsSameOSCert(retrieved_cert_handle, | |
| 178 cert.get()->os_cert_handle())); | |
|
Ryan Sleevi
2014/06/24 22:01:00
Notes from discussion/review:
BUG: As noted, |ret
| |
| 179 } | |
| 180 | |
|
Ryan Sleevi
2014/06/24 22:00:59
TEST: You want to have a test where a Get() from a
Ryan Sleevi
2014/06/24 22:01:00
TEST: You want to have a test where a Get() from a
| |
| 181 // Tests some basic functionality of the DiskBasedCertCache, with multiple | |
| 182 // set and get operations. | |
| 183 TEST(DiskBasedCertCache, BasicUsage) { | |
| 184 AddMockTransaction(&kCertTransaction1); | |
| 185 AddMockTransaction(&kCertTransaction2); | |
| 186 MockCertCache user; | |
| 187 | |
| 188 scoped_refptr<X509Certificate> cert1( | |
| 189 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
| 190 scoped_refptr<X509Certificate> cert2( | |
| 191 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); | |
| 192 ASSERT_TRUE(cert1.get()); | |
| 193 ASSERT_TRUE(cert2.get()); | |
| 194 ASSERT_FALSE(X509Certificate::IsSameOSCert(cert1->os_cert_handle(), | |
| 195 cert2->os_cert_handle())); | |
| 196 TestCompletionCallback set_callback1, set_callback2; | |
| 197 std::string key1, key2; | |
| 198 | |
| 199 int rv1 = | |
| 200 user.Set(cert1.get()->os_cert_handle(), &key1, set_callback1.callback()); | |
| 201 int rv2 = | |
| 202 user.Set(cert2.get()->os_cert_handle(), &key2, set_callback2.callback()); | |
| 203 | |
| 204 rv1 = set_callback1.GetResult(rv1); | |
| 205 EXPECT_EQ(OK, rv1); | |
| 206 rv2 = set_callback2.GetResult(rv2); | |
| 207 EXPECT_EQ(OK, rv2); | |
| 208 | |
| 209 TestCompletionCallback get_callback1, get_callback2; | |
| 210 X509Certificate::OSCertHandle cert_handle1, cert_handle2; | |
| 211 | |
| 212 rv1 = user.Get(key1, &cert_handle1, get_callback1.callback()); | |
| 213 rv2 = user.Get(key2, &cert_handle2, get_callback2.callback()); | |
| 214 | |
| 215 rv1 = get_callback1.GetResult(rv1); | |
| 216 EXPECT_EQ(OK, rv1); | |
| 217 rv2 = get_callback2.GetResult(rv2); | |
| 218 EXPECT_EQ(OK, rv2); | |
| 219 | |
| 220 EXPECT_TRUE( | |
| 221 X509Certificate::IsSameOSCert(cert1->os_cert_handle(), cert_handle1)); | |
| 222 EXPECT_TRUE( | |
| 223 X509Certificate::IsSameOSCert(cert2->os_cert_handle(), cert_handle2)); | |
| 224 } | |
| 225 | |
| 226 // Test the result of simultaneous requests to store and retrieve a | |
| 227 // certificate from the cache. Since it is unknown whether the set or get | |
| 228 // operation will complete first, this test is just to make sure that it | |
| 229 // does not crash. | |
|
Ryan Sleevi
2014/06/24 22:01:00
Notes from discussion:
You'll want your test harn
| |
| 230 TEST(DiskBasedCertCache, SimultaneousSetGet) { | |
| 231 AddMockTransaction(&kCertTransaction1); | |
| 232 MockCertCache user; | |
| 233 TestCompletionCallback set_callback, get_callback; | |
| 234 X509Certificate::OSCertHandle cert_handle; | |
| 235 std::string key("cert:4C005EF1CF45F80D4A5A2BCFB00D4F198121E8D4"); | |
|
Ryan Sleevi
2014/06/24 22:00:59
Reuse transaction key?
| |
| 236 | |
| 237 scoped_refptr<X509Certificate> cert( | |
| 238 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
| 239 ASSERT_TRUE(cert.get()); | |
| 240 | |
| 241 int rv1 = | |
| 242 user.Set(cert.get()->os_cert_handle(), &key, set_callback.callback()); | |
| 243 int rv2 = user.Get(key, &cert_handle, get_callback.callback()); | |
| 244 rv1 = get_callback.GetResult(rv1); | |
| 245 EXPECT_EQ(OK, rv1); | |
| 246 rv2 = set_callback.GetResult(rv2); | |
| 247 EXPECT_EQ(OK, rv2); | |
| 248 } | |
| 249 | |
|
Ryan Sleevi
2014/06/24 22:01:00
TEST: Use the MockTransactions to alter the sync/a
| |
| 250 // Tests that the DiskBasedCertCache can be deleted without issues when | |
| 251 // there are pending operations in the disk cache. | |
| 252 TEST(DiskBasedCertCache, DeletedCertCache) { | |
| 253 AddMockTransaction(&kCertTransaction1); | |
| 254 MockCertCache user; | |
| 255 std::string key; | |
| 256 scoped_refptr<X509Certificate> cert( | |
| 257 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
| 258 ASSERT_TRUE(cert.get()); | |
| 259 | |
| 260 TestCompletionCallback set_callback; | |
| 261 int rv = | |
| 262 user.Set(cert.get()->os_cert_handle(), &key, set_callback.callback()); | |
| 263 | |
| 264 user.DeleteCertCache(); | |
| 265 rv = set_callback.GetResult(rv); | |
| 266 EXPECT_EQ(OK, rv); | |
| 267 EXPECT_EQ(std::string(), key); | |
| 268 } | |
| 269 | |
| 270 } // namespace net | |
| OLD | NEW |