Add simple cache backend experiment hidden behind a command line option.
[chromium-blink-merge.git] / net / ssl / default_server_bound_cert_store.cc
blobeb4c0e3dd47e33049352714ca2972f407491165f
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/ssl/default_server_bound_cert_store.h"
7 #include "base/bind.h"
8 #include "base/message_loop.h"
9 #include "base/metrics/histogram.h"
11 namespace net {
13 // --------------------------------------------------------------------------
14 // Task
15 class DefaultServerBoundCertStore::Task {
16 public:
17 virtual ~Task();
19 // Runs the task and invokes the client callback on the thread that
20 // originally constructed the task.
21 virtual void Run(DefaultServerBoundCertStore* store) = 0;
23 protected:
24 void InvokeCallback(base::Closure callback) const;
27 DefaultServerBoundCertStore::Task::~Task() {
30 void DefaultServerBoundCertStore::Task::InvokeCallback(
31 base::Closure callback) const {
32 if (!callback.is_null())
33 callback.Run();
36 // --------------------------------------------------------------------------
37 // GetServerBoundCertTask
38 class DefaultServerBoundCertStore::GetServerBoundCertTask
39 : public DefaultServerBoundCertStore::Task {
40 public:
41 GetServerBoundCertTask(const std::string& server_identifier,
42 const GetCertCallback& callback);
43 virtual ~GetServerBoundCertTask();
44 virtual void Run(DefaultServerBoundCertStore* store) OVERRIDE;
46 private:
47 std::string server_identifier_;
48 GetCertCallback callback_;
51 DefaultServerBoundCertStore::GetServerBoundCertTask::GetServerBoundCertTask(
52 const std::string& server_identifier,
53 const GetCertCallback& callback)
54 : server_identifier_(server_identifier),
55 callback_(callback) {
58 DefaultServerBoundCertStore::GetServerBoundCertTask::~GetServerBoundCertTask() {
61 void DefaultServerBoundCertStore::GetServerBoundCertTask::Run(
62 DefaultServerBoundCertStore* store) {
63 SSLClientCertType type = CLIENT_CERT_INVALID_TYPE;
64 base::Time expiration_time;
65 std::string private_key_result;
66 std::string cert_result;
67 bool was_sync = store->GetServerBoundCert(
68 server_identifier_, &type, &expiration_time, &private_key_result,
69 &cert_result, GetCertCallback());
70 DCHECK(was_sync);
72 InvokeCallback(base::Bind(callback_, server_identifier_, type,
73 expiration_time, private_key_result, cert_result));
76 // --------------------------------------------------------------------------
77 // SetServerBoundCertTask
78 class DefaultServerBoundCertStore::SetServerBoundCertTask
79 : public DefaultServerBoundCertStore::Task {
80 public:
81 SetServerBoundCertTask(const std::string& server_identifier,
82 SSLClientCertType type,
83 base::Time creation_time,
84 base::Time expiration_time,
85 const std::string& private_key,
86 const std::string& cert);
87 virtual ~SetServerBoundCertTask();
88 virtual void Run(DefaultServerBoundCertStore* store) OVERRIDE;
90 private:
91 std::string server_identifier_;
92 SSLClientCertType type_;
93 base::Time creation_time_;
94 base::Time expiration_time_;
95 std::string private_key_;
96 std::string cert_;
99 DefaultServerBoundCertStore::SetServerBoundCertTask::SetServerBoundCertTask(
100 const std::string& server_identifier,
101 SSLClientCertType type,
102 base::Time creation_time,
103 base::Time expiration_time,
104 const std::string& private_key,
105 const std::string& cert)
106 : server_identifier_(server_identifier),
107 type_(type),
108 creation_time_(creation_time),
109 expiration_time_(expiration_time),
110 private_key_(private_key),
111 cert_(cert) {
114 DefaultServerBoundCertStore::SetServerBoundCertTask::~SetServerBoundCertTask() {
117 void DefaultServerBoundCertStore::SetServerBoundCertTask::Run(
118 DefaultServerBoundCertStore* store) {
119 store->SyncSetServerBoundCert(server_identifier_, type_, creation_time_,
120 expiration_time_, private_key_, cert_);
123 // --------------------------------------------------------------------------
124 // DeleteServerBoundCertTask
125 class DefaultServerBoundCertStore::DeleteServerBoundCertTask
126 : public DefaultServerBoundCertStore::Task {
127 public:
128 DeleteServerBoundCertTask(const std::string& server_identifier,
129 const base::Closure& callback);
130 virtual ~DeleteServerBoundCertTask();
131 virtual void Run(DefaultServerBoundCertStore* store) OVERRIDE;
133 private:
134 std::string server_identifier_;
135 base::Closure callback_;
138 DefaultServerBoundCertStore::DeleteServerBoundCertTask::
139 DeleteServerBoundCertTask(
140 const std::string& server_identifier,
141 const base::Closure& callback)
142 : server_identifier_(server_identifier),
143 callback_(callback) {
146 DefaultServerBoundCertStore::DeleteServerBoundCertTask::
147 ~DeleteServerBoundCertTask() {
150 void DefaultServerBoundCertStore::DeleteServerBoundCertTask::Run(
151 DefaultServerBoundCertStore* store) {
152 store->SyncDeleteServerBoundCert(server_identifier_);
154 InvokeCallback(callback_);
157 // --------------------------------------------------------------------------
158 // DeleteAllCreatedBetweenTask
159 class DefaultServerBoundCertStore::DeleteAllCreatedBetweenTask
160 : public DefaultServerBoundCertStore::Task {
161 public:
162 DeleteAllCreatedBetweenTask(base::Time delete_begin,
163 base::Time delete_end,
164 const base::Closure& callback);
165 virtual ~DeleteAllCreatedBetweenTask();
166 virtual void Run(DefaultServerBoundCertStore* store) OVERRIDE;
168 private:
169 base::Time delete_begin_;
170 base::Time delete_end_;
171 base::Closure callback_;
174 DefaultServerBoundCertStore::DeleteAllCreatedBetweenTask::
175 DeleteAllCreatedBetweenTask(
176 base::Time delete_begin,
177 base::Time delete_end,
178 const base::Closure& callback)
179 : delete_begin_(delete_begin),
180 delete_end_(delete_end),
181 callback_(callback) {
184 DefaultServerBoundCertStore::DeleteAllCreatedBetweenTask::
185 ~DeleteAllCreatedBetweenTask() {
188 void DefaultServerBoundCertStore::DeleteAllCreatedBetweenTask::Run(
189 DefaultServerBoundCertStore* store) {
190 store->SyncDeleteAllCreatedBetween(delete_begin_, delete_end_);
192 InvokeCallback(callback_);
195 // --------------------------------------------------------------------------
196 // GetAllServerBoundCertsTask
197 class DefaultServerBoundCertStore::GetAllServerBoundCertsTask
198 : public DefaultServerBoundCertStore::Task {
199 public:
200 explicit GetAllServerBoundCertsTask(const GetCertListCallback& callback);
201 virtual ~GetAllServerBoundCertsTask();
202 virtual void Run(DefaultServerBoundCertStore* store) OVERRIDE;
204 private:
205 std::string server_identifier_;
206 GetCertListCallback callback_;
209 DefaultServerBoundCertStore::GetAllServerBoundCertsTask::
210 GetAllServerBoundCertsTask(const GetCertListCallback& callback)
211 : callback_(callback) {
214 DefaultServerBoundCertStore::GetAllServerBoundCertsTask::
215 ~GetAllServerBoundCertsTask() {
218 void DefaultServerBoundCertStore::GetAllServerBoundCertsTask::Run(
219 DefaultServerBoundCertStore* store) {
220 ServerBoundCertList cert_list;
221 store->SyncGetAllServerBoundCerts(&cert_list);
223 InvokeCallback(base::Bind(callback_, cert_list));
226 // --------------------------------------------------------------------------
227 // DefaultServerBoundCertStore
229 // static
230 const size_t DefaultServerBoundCertStore::kMaxCerts = 3300;
232 DefaultServerBoundCertStore::DefaultServerBoundCertStore(
233 PersistentStore* store)
234 : initialized_(false),
235 loaded_(false),
236 store_(store),
237 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {}
239 bool DefaultServerBoundCertStore::GetServerBoundCert(
240 const std::string& server_identifier,
241 SSLClientCertType* type,
242 base::Time* expiration_time,
243 std::string* private_key_result,
244 std::string* cert_result,
245 const GetCertCallback& callback) {
246 DCHECK(CalledOnValidThread());
247 InitIfNecessary();
249 if (!loaded_) {
250 EnqueueTask(scoped_ptr<Task>(
251 new GetServerBoundCertTask(server_identifier, callback)));
252 return false;
255 ServerBoundCertMap::iterator it = server_bound_certs_.find(server_identifier);
257 if (it == server_bound_certs_.end()) {
258 *type = CLIENT_CERT_INVALID_TYPE;
259 return true;
262 ServerBoundCert* cert = it->second;
263 *type = cert->type();
264 *expiration_time = cert->expiration_time();
265 *private_key_result = cert->private_key();
266 *cert_result = cert->cert();
268 return true;
271 void DefaultServerBoundCertStore::SetServerBoundCert(
272 const std::string& server_identifier,
273 SSLClientCertType type,
274 base::Time creation_time,
275 base::Time expiration_time,
276 const std::string& private_key,
277 const std::string& cert) {
278 RunOrEnqueueTask(scoped_ptr<Task>(new SetServerBoundCertTask(
279 server_identifier, type, creation_time, expiration_time, private_key,
280 cert)));
283 void DefaultServerBoundCertStore::DeleteServerBoundCert(
284 const std::string& server_identifier,
285 const base::Closure& callback) {
286 RunOrEnqueueTask(scoped_ptr<Task>(
287 new DeleteServerBoundCertTask(server_identifier, callback)));
290 void DefaultServerBoundCertStore::DeleteAllCreatedBetween(
291 base::Time delete_begin,
292 base::Time delete_end,
293 const base::Closure& callback) {
294 RunOrEnqueueTask(scoped_ptr<Task>(
295 new DeleteAllCreatedBetweenTask(delete_begin, delete_end, callback)));
298 void DefaultServerBoundCertStore::DeleteAll(
299 const base::Closure& callback) {
300 DeleteAllCreatedBetween(base::Time(), base::Time(), callback);
303 void DefaultServerBoundCertStore::GetAllServerBoundCerts(
304 const GetCertListCallback& callback) {
305 RunOrEnqueueTask(scoped_ptr<Task>(new GetAllServerBoundCertsTask(callback)));
308 int DefaultServerBoundCertStore::GetCertCount() {
309 DCHECK(CalledOnValidThread());
311 return server_bound_certs_.size();
314 void DefaultServerBoundCertStore::SetForceKeepSessionState() {
315 DCHECK(CalledOnValidThread());
316 InitIfNecessary();
318 if (store_)
319 store_->SetForceKeepSessionState();
322 DefaultServerBoundCertStore::~DefaultServerBoundCertStore() {
323 DeleteAllInMemory();
326 void DefaultServerBoundCertStore::DeleteAllInMemory() {
327 DCHECK(CalledOnValidThread());
329 for (ServerBoundCertMap::iterator it = server_bound_certs_.begin();
330 it != server_bound_certs_.end(); ++it) {
331 delete it->second;
333 server_bound_certs_.clear();
336 void DefaultServerBoundCertStore::InitStore() {
337 DCHECK(CalledOnValidThread());
338 DCHECK(store_) << "Store must exist to initialize";
339 DCHECK(!loaded_);
341 store_->Load(base::Bind(&DefaultServerBoundCertStore::OnLoaded,
342 weak_ptr_factory_.GetWeakPtr()));
345 void DefaultServerBoundCertStore::OnLoaded(
346 scoped_ptr<ScopedVector<ServerBoundCert> > certs) {
347 DCHECK(CalledOnValidThread());
349 for (std::vector<ServerBoundCert*>::const_iterator it = certs->begin();
350 it != certs->end(); ++it) {
351 DCHECK(server_bound_certs_.find((*it)->server_identifier()) ==
352 server_bound_certs_.end());
353 server_bound_certs_[(*it)->server_identifier()] = *it;
355 certs->weak_clear();
357 loaded_ = true;
359 base::TimeDelta wait_time;
360 if (!waiting_tasks_.empty())
361 wait_time = base::TimeTicks::Now() - waiting_tasks_start_time_;
362 DVLOG(1) << "Task delay " << wait_time.InMilliseconds();
363 UMA_HISTOGRAM_CUSTOM_TIMES("DomainBoundCerts.TaskMaxWaitTime",
364 wait_time,
365 base::TimeDelta::FromMilliseconds(1),
366 base::TimeDelta::FromMinutes(1),
367 50);
368 UMA_HISTOGRAM_COUNTS_100("DomainBoundCerts.TaskWaitCount",
369 waiting_tasks_.size());
372 for (ScopedVector<Task>::iterator i = waiting_tasks_.begin();
373 i != waiting_tasks_.end(); ++i)
374 (*i)->Run(this);
375 waiting_tasks_.clear();
378 void DefaultServerBoundCertStore::SyncSetServerBoundCert(
379 const std::string& server_identifier,
380 SSLClientCertType type,
381 base::Time creation_time,
382 base::Time expiration_time,
383 const std::string& private_key,
384 const std::string& cert) {
385 DCHECK(CalledOnValidThread());
386 DCHECK(loaded_);
388 InternalDeleteServerBoundCert(server_identifier);
389 InternalInsertServerBoundCert(
390 server_identifier,
391 new ServerBoundCert(
392 server_identifier, type, creation_time, expiration_time, private_key,
393 cert));
396 void DefaultServerBoundCertStore::SyncDeleteServerBoundCert(
397 const std::string& server_identifier) {
398 DCHECK(CalledOnValidThread());
399 DCHECK(loaded_);
400 InternalDeleteServerBoundCert(server_identifier);
403 void DefaultServerBoundCertStore::SyncDeleteAllCreatedBetween(
404 base::Time delete_begin,
405 base::Time delete_end) {
406 DCHECK(CalledOnValidThread());
407 DCHECK(loaded_);
408 for (ServerBoundCertMap::iterator it = server_bound_certs_.begin();
409 it != server_bound_certs_.end();) {
410 ServerBoundCertMap::iterator cur = it;
411 ++it;
412 ServerBoundCert* cert = cur->second;
413 if ((delete_begin.is_null() || cert->creation_time() >= delete_begin) &&
414 (delete_end.is_null() || cert->creation_time() < delete_end)) {
415 if (store_)
416 store_->DeleteServerBoundCert(*cert);
417 delete cert;
418 server_bound_certs_.erase(cur);
423 void DefaultServerBoundCertStore::SyncGetAllServerBoundCerts(
424 ServerBoundCertList* cert_list) {
425 DCHECK(CalledOnValidThread());
426 DCHECK(loaded_);
427 for (ServerBoundCertMap::iterator it = server_bound_certs_.begin();
428 it != server_bound_certs_.end(); ++it)
429 cert_list->push_back(*it->second);
432 void DefaultServerBoundCertStore::EnqueueTask(scoped_ptr<Task> task) {
433 DCHECK(CalledOnValidThread());
434 DCHECK(!loaded_);
435 if (waiting_tasks_.empty())
436 waiting_tasks_start_time_ = base::TimeTicks::Now();
437 waiting_tasks_.push_back(task.release());
440 void DefaultServerBoundCertStore::RunOrEnqueueTask(scoped_ptr<Task> task) {
441 DCHECK(CalledOnValidThread());
442 InitIfNecessary();
444 if (!loaded_) {
445 EnqueueTask(task.Pass());
446 return;
449 task->Run(this);
452 void DefaultServerBoundCertStore::InternalDeleteServerBoundCert(
453 const std::string& server_identifier) {
454 DCHECK(CalledOnValidThread());
455 DCHECK(loaded_);
457 ServerBoundCertMap::iterator it = server_bound_certs_.find(server_identifier);
458 if (it == server_bound_certs_.end())
459 return; // There is nothing to delete.
461 ServerBoundCert* cert = it->second;
462 if (store_)
463 store_->DeleteServerBoundCert(*cert);
464 server_bound_certs_.erase(it);
465 delete cert;
468 void DefaultServerBoundCertStore::InternalInsertServerBoundCert(
469 const std::string& server_identifier,
470 ServerBoundCert* cert) {
471 DCHECK(CalledOnValidThread());
472 DCHECK(loaded_);
474 if (store_)
475 store_->AddServerBoundCert(*cert);
476 server_bound_certs_[server_identifier] = cert;
479 DefaultServerBoundCertStore::PersistentStore::PersistentStore() {}
481 DefaultServerBoundCertStore::PersistentStore::~PersistentStore() {}
483 } // namespace net