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"
8 #include "base/message_loop/message_loop.h"
9 #include "base/metrics/histogram.h"
10 #include "net/base/net_errors.h"
14 // --------------------------------------------------------------------------
16 class DefaultServerBoundCertStore::Task
{
20 // Runs the task and invokes the client callback on the thread that
21 // originally constructed the task.
22 virtual void Run(DefaultServerBoundCertStore
* store
) = 0;
25 void InvokeCallback(base::Closure callback
) const;
28 DefaultServerBoundCertStore::Task::~Task() {
31 void DefaultServerBoundCertStore::Task::InvokeCallback(
32 base::Closure callback
) const {
33 if (!callback
.is_null())
37 // --------------------------------------------------------------------------
38 // GetServerBoundCertTask
39 class DefaultServerBoundCertStore::GetServerBoundCertTask
40 : public DefaultServerBoundCertStore::Task
{
42 GetServerBoundCertTask(const std::string
& server_identifier
,
43 const GetCertCallback
& callback
);
44 virtual ~GetServerBoundCertTask();
45 virtual void Run(DefaultServerBoundCertStore
* store
) OVERRIDE
;
48 std::string server_identifier_
;
49 GetCertCallback callback_
;
52 DefaultServerBoundCertStore::GetServerBoundCertTask::GetServerBoundCertTask(
53 const std::string
& server_identifier
,
54 const GetCertCallback
& callback
)
55 : server_identifier_(server_identifier
),
59 DefaultServerBoundCertStore::GetServerBoundCertTask::~GetServerBoundCertTask() {
62 void DefaultServerBoundCertStore::GetServerBoundCertTask::Run(
63 DefaultServerBoundCertStore
* store
) {
64 base::Time expiration_time
;
65 std::string private_key_result
;
66 std::string cert_result
;
67 int err
= store
->GetServerBoundCert(
68 server_identifier_
, &expiration_time
, &private_key_result
,
69 &cert_result
, GetCertCallback());
70 DCHECK(err
!= ERR_IO_PENDING
);
72 InvokeCallback(base::Bind(callback_
, err
, server_identifier_
,
73 expiration_time
, private_key_result
, cert_result
));
76 // --------------------------------------------------------------------------
77 // SetServerBoundCertTask
78 class DefaultServerBoundCertStore::SetServerBoundCertTask
79 : public DefaultServerBoundCertStore::Task
{
81 SetServerBoundCertTask(const std::string
& server_identifier
,
82 base::Time creation_time
,
83 base::Time expiration_time
,
84 const std::string
& private_key
,
85 const std::string
& cert
);
86 virtual ~SetServerBoundCertTask();
87 virtual void Run(DefaultServerBoundCertStore
* store
) OVERRIDE
;
90 std::string server_identifier_
;
91 base::Time creation_time_
;
92 base::Time expiration_time_
;
93 std::string private_key_
;
97 DefaultServerBoundCertStore::SetServerBoundCertTask::SetServerBoundCertTask(
98 const std::string
& server_identifier
,
99 base::Time creation_time
,
100 base::Time expiration_time
,
101 const std::string
& private_key
,
102 const std::string
& cert
)
103 : server_identifier_(server_identifier
),
104 creation_time_(creation_time
),
105 expiration_time_(expiration_time
),
106 private_key_(private_key
),
110 DefaultServerBoundCertStore::SetServerBoundCertTask::~SetServerBoundCertTask() {
113 void DefaultServerBoundCertStore::SetServerBoundCertTask::Run(
114 DefaultServerBoundCertStore
* store
) {
115 store
->SyncSetServerBoundCert(server_identifier_
, creation_time_
,
116 expiration_time_
, private_key_
, cert_
);
119 // --------------------------------------------------------------------------
120 // DeleteServerBoundCertTask
121 class DefaultServerBoundCertStore::DeleteServerBoundCertTask
122 : public DefaultServerBoundCertStore::Task
{
124 DeleteServerBoundCertTask(const std::string
& server_identifier
,
125 const base::Closure
& callback
);
126 virtual ~DeleteServerBoundCertTask();
127 virtual void Run(DefaultServerBoundCertStore
* store
) OVERRIDE
;
130 std::string server_identifier_
;
131 base::Closure callback_
;
134 DefaultServerBoundCertStore::DeleteServerBoundCertTask::
135 DeleteServerBoundCertTask(
136 const std::string
& server_identifier
,
137 const base::Closure
& callback
)
138 : server_identifier_(server_identifier
),
139 callback_(callback
) {
142 DefaultServerBoundCertStore::DeleteServerBoundCertTask::
143 ~DeleteServerBoundCertTask() {
146 void DefaultServerBoundCertStore::DeleteServerBoundCertTask::Run(
147 DefaultServerBoundCertStore
* store
) {
148 store
->SyncDeleteServerBoundCert(server_identifier_
);
150 InvokeCallback(callback_
);
153 // --------------------------------------------------------------------------
154 // DeleteAllCreatedBetweenTask
155 class DefaultServerBoundCertStore::DeleteAllCreatedBetweenTask
156 : public DefaultServerBoundCertStore::Task
{
158 DeleteAllCreatedBetweenTask(base::Time delete_begin
,
159 base::Time delete_end
,
160 const base::Closure
& callback
);
161 virtual ~DeleteAllCreatedBetweenTask();
162 virtual void Run(DefaultServerBoundCertStore
* store
) OVERRIDE
;
165 base::Time delete_begin_
;
166 base::Time delete_end_
;
167 base::Closure callback_
;
170 DefaultServerBoundCertStore::DeleteAllCreatedBetweenTask::
171 DeleteAllCreatedBetweenTask(
172 base::Time delete_begin
,
173 base::Time delete_end
,
174 const base::Closure
& callback
)
175 : delete_begin_(delete_begin
),
176 delete_end_(delete_end
),
177 callback_(callback
) {
180 DefaultServerBoundCertStore::DeleteAllCreatedBetweenTask::
181 ~DeleteAllCreatedBetweenTask() {
184 void DefaultServerBoundCertStore::DeleteAllCreatedBetweenTask::Run(
185 DefaultServerBoundCertStore
* store
) {
186 store
->SyncDeleteAllCreatedBetween(delete_begin_
, delete_end_
);
188 InvokeCallback(callback_
);
191 // --------------------------------------------------------------------------
192 // GetAllServerBoundCertsTask
193 class DefaultServerBoundCertStore::GetAllServerBoundCertsTask
194 : public DefaultServerBoundCertStore::Task
{
196 explicit GetAllServerBoundCertsTask(const GetCertListCallback
& callback
);
197 virtual ~GetAllServerBoundCertsTask();
198 virtual void Run(DefaultServerBoundCertStore
* store
) OVERRIDE
;
201 std::string server_identifier_
;
202 GetCertListCallback callback_
;
205 DefaultServerBoundCertStore::GetAllServerBoundCertsTask::
206 GetAllServerBoundCertsTask(const GetCertListCallback
& callback
)
207 : callback_(callback
) {
210 DefaultServerBoundCertStore::GetAllServerBoundCertsTask::
211 ~GetAllServerBoundCertsTask() {
214 void DefaultServerBoundCertStore::GetAllServerBoundCertsTask::Run(
215 DefaultServerBoundCertStore
* store
) {
216 ServerBoundCertList cert_list
;
217 store
->SyncGetAllServerBoundCerts(&cert_list
);
219 InvokeCallback(base::Bind(callback_
, cert_list
));
222 // --------------------------------------------------------------------------
223 // DefaultServerBoundCertStore
226 const size_t DefaultServerBoundCertStore::kMaxCerts
= 3300;
228 DefaultServerBoundCertStore::DefaultServerBoundCertStore(
229 PersistentStore
* store
)
230 : initialized_(false),
233 weak_ptr_factory_(this) {}
235 int DefaultServerBoundCertStore::GetServerBoundCert(
236 const std::string
& server_identifier
,
237 base::Time
* expiration_time
,
238 std::string
* private_key_result
,
239 std::string
* cert_result
,
240 const GetCertCallback
& callback
) {
241 DCHECK(CalledOnValidThread());
245 EnqueueTask(scoped_ptr
<Task
>(
246 new GetServerBoundCertTask(server_identifier
, callback
)));
247 return ERR_IO_PENDING
;
250 ServerBoundCertMap::iterator it
= server_bound_certs_
.find(server_identifier
);
252 if (it
== server_bound_certs_
.end())
253 return ERR_FILE_NOT_FOUND
;
255 ServerBoundCert
* cert
= it
->second
;
256 *expiration_time
= cert
->expiration_time();
257 *private_key_result
= cert
->private_key();
258 *cert_result
= cert
->cert();
263 void DefaultServerBoundCertStore::SetServerBoundCert(
264 const std::string
& server_identifier
,
265 base::Time creation_time
,
266 base::Time expiration_time
,
267 const std::string
& private_key
,
268 const std::string
& cert
) {
269 RunOrEnqueueTask(scoped_ptr
<Task
>(new SetServerBoundCertTask(
270 server_identifier
, creation_time
, expiration_time
, private_key
,
274 void DefaultServerBoundCertStore::DeleteServerBoundCert(
275 const std::string
& server_identifier
,
276 const base::Closure
& callback
) {
277 RunOrEnqueueTask(scoped_ptr
<Task
>(
278 new DeleteServerBoundCertTask(server_identifier
, callback
)));
281 void DefaultServerBoundCertStore::DeleteAllCreatedBetween(
282 base::Time delete_begin
,
283 base::Time delete_end
,
284 const base::Closure
& callback
) {
285 RunOrEnqueueTask(scoped_ptr
<Task
>(
286 new DeleteAllCreatedBetweenTask(delete_begin
, delete_end
, callback
)));
289 void DefaultServerBoundCertStore::DeleteAll(
290 const base::Closure
& callback
) {
291 DeleteAllCreatedBetween(base::Time(), base::Time(), callback
);
294 void DefaultServerBoundCertStore::GetAllServerBoundCerts(
295 const GetCertListCallback
& callback
) {
296 RunOrEnqueueTask(scoped_ptr
<Task
>(new GetAllServerBoundCertsTask(callback
)));
299 int DefaultServerBoundCertStore::GetCertCount() {
300 DCHECK(CalledOnValidThread());
302 return server_bound_certs_
.size();
305 void DefaultServerBoundCertStore::SetForceKeepSessionState() {
306 DCHECK(CalledOnValidThread());
310 store_
->SetForceKeepSessionState();
313 DefaultServerBoundCertStore::~DefaultServerBoundCertStore() {
317 void DefaultServerBoundCertStore::DeleteAllInMemory() {
318 DCHECK(CalledOnValidThread());
320 for (ServerBoundCertMap::iterator it
= server_bound_certs_
.begin();
321 it
!= server_bound_certs_
.end(); ++it
) {
324 server_bound_certs_
.clear();
327 void DefaultServerBoundCertStore::InitStore() {
328 DCHECK(CalledOnValidThread());
329 DCHECK(store_
.get()) << "Store must exist to initialize";
332 store_
->Load(base::Bind(&DefaultServerBoundCertStore::OnLoaded
,
333 weak_ptr_factory_
.GetWeakPtr()));
336 void DefaultServerBoundCertStore::OnLoaded(
337 scoped_ptr
<ScopedVector
<ServerBoundCert
> > certs
) {
338 DCHECK(CalledOnValidThread());
340 for (std::vector
<ServerBoundCert
*>::const_iterator it
= certs
->begin();
341 it
!= certs
->end(); ++it
) {
342 DCHECK(server_bound_certs_
.find((*it
)->server_identifier()) ==
343 server_bound_certs_
.end());
344 server_bound_certs_
[(*it
)->server_identifier()] = *it
;
350 base::TimeDelta wait_time
;
351 if (!waiting_tasks_
.empty())
352 wait_time
= base::TimeTicks::Now() - waiting_tasks_start_time_
;
353 DVLOG(1) << "Task delay " << wait_time
.InMilliseconds();
354 UMA_HISTOGRAM_CUSTOM_TIMES("DomainBoundCerts.TaskMaxWaitTime",
356 base::TimeDelta::FromMilliseconds(1),
357 base::TimeDelta::FromMinutes(1),
359 UMA_HISTOGRAM_COUNTS_100("DomainBoundCerts.TaskWaitCount",
360 waiting_tasks_
.size());
363 for (ScopedVector
<Task
>::iterator i
= waiting_tasks_
.begin();
364 i
!= waiting_tasks_
.end(); ++i
)
366 waiting_tasks_
.clear();
369 void DefaultServerBoundCertStore::SyncSetServerBoundCert(
370 const std::string
& server_identifier
,
371 base::Time creation_time
,
372 base::Time expiration_time
,
373 const std::string
& private_key
,
374 const std::string
& cert
) {
375 DCHECK(CalledOnValidThread());
378 InternalDeleteServerBoundCert(server_identifier
);
379 InternalInsertServerBoundCert(
382 server_identifier
, creation_time
, expiration_time
, private_key
,
386 void DefaultServerBoundCertStore::SyncDeleteServerBoundCert(
387 const std::string
& server_identifier
) {
388 DCHECK(CalledOnValidThread());
390 InternalDeleteServerBoundCert(server_identifier
);
393 void DefaultServerBoundCertStore::SyncDeleteAllCreatedBetween(
394 base::Time delete_begin
,
395 base::Time delete_end
) {
396 DCHECK(CalledOnValidThread());
398 for (ServerBoundCertMap::iterator it
= server_bound_certs_
.begin();
399 it
!= server_bound_certs_
.end();) {
400 ServerBoundCertMap::iterator cur
= it
;
402 ServerBoundCert
* cert
= cur
->second
;
403 if ((delete_begin
.is_null() || cert
->creation_time() >= delete_begin
) &&
404 (delete_end
.is_null() || cert
->creation_time() < delete_end
)) {
406 store_
->DeleteServerBoundCert(*cert
);
408 server_bound_certs_
.erase(cur
);
413 void DefaultServerBoundCertStore::SyncGetAllServerBoundCerts(
414 ServerBoundCertList
* cert_list
) {
415 DCHECK(CalledOnValidThread());
417 for (ServerBoundCertMap::iterator it
= server_bound_certs_
.begin();
418 it
!= server_bound_certs_
.end(); ++it
)
419 cert_list
->push_back(*it
->second
);
422 void DefaultServerBoundCertStore::EnqueueTask(scoped_ptr
<Task
> task
) {
423 DCHECK(CalledOnValidThread());
425 if (waiting_tasks_
.empty())
426 waiting_tasks_start_time_
= base::TimeTicks::Now();
427 waiting_tasks_
.push_back(task
.release());
430 void DefaultServerBoundCertStore::RunOrEnqueueTask(scoped_ptr
<Task
> task
) {
431 DCHECK(CalledOnValidThread());
435 EnqueueTask(task
.Pass());
442 void DefaultServerBoundCertStore::InternalDeleteServerBoundCert(
443 const std::string
& server_identifier
) {
444 DCHECK(CalledOnValidThread());
447 ServerBoundCertMap::iterator it
= server_bound_certs_
.find(server_identifier
);
448 if (it
== server_bound_certs_
.end())
449 return; // There is nothing to delete.
451 ServerBoundCert
* cert
= it
->second
;
453 store_
->DeleteServerBoundCert(*cert
);
454 server_bound_certs_
.erase(it
);
458 void DefaultServerBoundCertStore::InternalInsertServerBoundCert(
459 const std::string
& server_identifier
,
460 ServerBoundCert
* cert
) {
461 DCHECK(CalledOnValidThread());
465 store_
->AddServerBoundCert(*cert
);
466 server_bound_certs_
[server_identifier
] = cert
;
469 DefaultServerBoundCertStore::PersistentStore::PersistentStore() {}
471 DefaultServerBoundCertStore::PersistentStore::~PersistentStore() {}