- add sources.
[platform/framework/web/crosswalk.git] / src / net / ssl / default_server_bound_cert_store.cc
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.
4
5 #include "net/ssl/default_server_bound_cert_store.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/metrics/histogram.h"
10 #include "net/base/net_errors.h"
11
12 namespace net {
13
14 // --------------------------------------------------------------------------
15 // Task
16 class DefaultServerBoundCertStore::Task {
17  public:
18   virtual ~Task();
19
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;
23
24  protected:
25   void InvokeCallback(base::Closure callback) const;
26 };
27
28 DefaultServerBoundCertStore::Task::~Task() {
29 }
30
31 void DefaultServerBoundCertStore::Task::InvokeCallback(
32     base::Closure callback) const {
33   if (!callback.is_null())
34     callback.Run();
35 }
36
37 // --------------------------------------------------------------------------
38 // GetServerBoundCertTask
39 class DefaultServerBoundCertStore::GetServerBoundCertTask
40     : public DefaultServerBoundCertStore::Task {
41  public:
42   GetServerBoundCertTask(const std::string& server_identifier,
43                          const GetCertCallback& callback);
44   virtual ~GetServerBoundCertTask();
45   virtual void Run(DefaultServerBoundCertStore* store) OVERRIDE;
46
47  private:
48   std::string server_identifier_;
49   GetCertCallback callback_;
50 };
51
52 DefaultServerBoundCertStore::GetServerBoundCertTask::GetServerBoundCertTask(
53     const std::string& server_identifier,
54     const GetCertCallback& callback)
55     : server_identifier_(server_identifier),
56       callback_(callback) {
57 }
58
59 DefaultServerBoundCertStore::GetServerBoundCertTask::~GetServerBoundCertTask() {
60 }
61
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);
71
72   InvokeCallback(base::Bind(callback_, err, server_identifier_,
73                             expiration_time, private_key_result, cert_result));
74 }
75
76 // --------------------------------------------------------------------------
77 // SetServerBoundCertTask
78 class DefaultServerBoundCertStore::SetServerBoundCertTask
79     : public DefaultServerBoundCertStore::Task {
80  public:
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;
88
89  private:
90   std::string server_identifier_;
91   base::Time creation_time_;
92   base::Time expiration_time_;
93   std::string private_key_;
94   std::string cert_;
95 };
96
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),
107       cert_(cert) {
108 }
109
110 DefaultServerBoundCertStore::SetServerBoundCertTask::~SetServerBoundCertTask() {
111 }
112
113 void DefaultServerBoundCertStore::SetServerBoundCertTask::Run(
114     DefaultServerBoundCertStore* store) {
115   store->SyncSetServerBoundCert(server_identifier_, creation_time_,
116                                 expiration_time_, private_key_, cert_);
117 }
118
119 // --------------------------------------------------------------------------
120 // DeleteServerBoundCertTask
121 class DefaultServerBoundCertStore::DeleteServerBoundCertTask
122     : public DefaultServerBoundCertStore::Task {
123  public:
124   DeleteServerBoundCertTask(const std::string& server_identifier,
125                             const base::Closure& callback);
126   virtual ~DeleteServerBoundCertTask();
127   virtual void Run(DefaultServerBoundCertStore* store) OVERRIDE;
128
129  private:
130   std::string server_identifier_;
131   base::Closure callback_;
132 };
133
134 DefaultServerBoundCertStore::DeleteServerBoundCertTask::
135     DeleteServerBoundCertTask(
136         const std::string& server_identifier,
137         const base::Closure& callback)
138         : server_identifier_(server_identifier),
139           callback_(callback) {
140 }
141
142 DefaultServerBoundCertStore::DeleteServerBoundCertTask::
143     ~DeleteServerBoundCertTask() {
144 }
145
146 void DefaultServerBoundCertStore::DeleteServerBoundCertTask::Run(
147     DefaultServerBoundCertStore* store) {
148   store->SyncDeleteServerBoundCert(server_identifier_);
149
150   InvokeCallback(callback_);
151 }
152
153 // --------------------------------------------------------------------------
154 // DeleteAllCreatedBetweenTask
155 class DefaultServerBoundCertStore::DeleteAllCreatedBetweenTask
156     : public DefaultServerBoundCertStore::Task {
157  public:
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;
163
164  private:
165   base::Time delete_begin_;
166   base::Time delete_end_;
167   base::Closure callback_;
168 };
169
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) {
178 }
179
180 DefaultServerBoundCertStore::DeleteAllCreatedBetweenTask::
181     ~DeleteAllCreatedBetweenTask() {
182 }
183
184 void DefaultServerBoundCertStore::DeleteAllCreatedBetweenTask::Run(
185     DefaultServerBoundCertStore* store) {
186   store->SyncDeleteAllCreatedBetween(delete_begin_, delete_end_);
187
188   InvokeCallback(callback_);
189 }
190
191 // --------------------------------------------------------------------------
192 // GetAllServerBoundCertsTask
193 class DefaultServerBoundCertStore::GetAllServerBoundCertsTask
194     : public DefaultServerBoundCertStore::Task {
195  public:
196   explicit GetAllServerBoundCertsTask(const GetCertListCallback& callback);
197   virtual ~GetAllServerBoundCertsTask();
198   virtual void Run(DefaultServerBoundCertStore* store) OVERRIDE;
199
200  private:
201   std::string server_identifier_;
202   GetCertListCallback callback_;
203 };
204
205 DefaultServerBoundCertStore::GetAllServerBoundCertsTask::
206     GetAllServerBoundCertsTask(const GetCertListCallback& callback)
207         : callback_(callback) {
208 }
209
210 DefaultServerBoundCertStore::GetAllServerBoundCertsTask::
211     ~GetAllServerBoundCertsTask() {
212 }
213
214 void DefaultServerBoundCertStore::GetAllServerBoundCertsTask::Run(
215     DefaultServerBoundCertStore* store) {
216   ServerBoundCertList cert_list;
217   store->SyncGetAllServerBoundCerts(&cert_list);
218
219   InvokeCallback(base::Bind(callback_, cert_list));
220 }
221
222 // --------------------------------------------------------------------------
223 // DefaultServerBoundCertStore
224
225 // static
226 const size_t DefaultServerBoundCertStore::kMaxCerts = 3300;
227
228 DefaultServerBoundCertStore::DefaultServerBoundCertStore(
229     PersistentStore* store)
230     : initialized_(false),
231       loaded_(false),
232       store_(store),
233       weak_ptr_factory_(this) {}
234
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());
242   InitIfNecessary();
243
244   if (!loaded_) {
245     EnqueueTask(scoped_ptr<Task>(
246         new GetServerBoundCertTask(server_identifier, callback)));
247     return ERR_IO_PENDING;
248   }
249
250   ServerBoundCertMap::iterator it = server_bound_certs_.find(server_identifier);
251
252   if (it == server_bound_certs_.end())
253     return ERR_FILE_NOT_FOUND;
254
255   ServerBoundCert* cert = it->second;
256   *expiration_time = cert->expiration_time();
257   *private_key_result = cert->private_key();
258   *cert_result = cert->cert();
259
260   return OK;
261 }
262
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,
271       cert)));
272 }
273
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)));
279 }
280
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)));
287 }
288
289 void DefaultServerBoundCertStore::DeleteAll(
290     const base::Closure& callback) {
291   DeleteAllCreatedBetween(base::Time(), base::Time(), callback);
292 }
293
294 void DefaultServerBoundCertStore::GetAllServerBoundCerts(
295     const GetCertListCallback& callback) {
296   RunOrEnqueueTask(scoped_ptr<Task>(new GetAllServerBoundCertsTask(callback)));
297 }
298
299 int DefaultServerBoundCertStore::GetCertCount() {
300   DCHECK(CalledOnValidThread());
301
302   return server_bound_certs_.size();
303 }
304
305 void DefaultServerBoundCertStore::SetForceKeepSessionState() {
306   DCHECK(CalledOnValidThread());
307   InitIfNecessary();
308
309   if (store_.get())
310     store_->SetForceKeepSessionState();
311 }
312
313 DefaultServerBoundCertStore::~DefaultServerBoundCertStore() {
314   DeleteAllInMemory();
315 }
316
317 void DefaultServerBoundCertStore::DeleteAllInMemory() {
318   DCHECK(CalledOnValidThread());
319
320   for (ServerBoundCertMap::iterator it = server_bound_certs_.begin();
321        it != server_bound_certs_.end(); ++it) {
322     delete it->second;
323   }
324   server_bound_certs_.clear();
325 }
326
327 void DefaultServerBoundCertStore::InitStore() {
328   DCHECK(CalledOnValidThread());
329   DCHECK(store_.get()) << "Store must exist to initialize";
330   DCHECK(!loaded_);
331
332   store_->Load(base::Bind(&DefaultServerBoundCertStore::OnLoaded,
333                           weak_ptr_factory_.GetWeakPtr()));
334 }
335
336 void DefaultServerBoundCertStore::OnLoaded(
337     scoped_ptr<ScopedVector<ServerBoundCert> > certs) {
338   DCHECK(CalledOnValidThread());
339
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;
345   }
346   certs->weak_clear();
347
348   loaded_ = true;
349
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",
355                              wait_time,
356                              base::TimeDelta::FromMilliseconds(1),
357                              base::TimeDelta::FromMinutes(1),
358                              50);
359   UMA_HISTOGRAM_COUNTS_100("DomainBoundCerts.TaskWaitCount",
360                            waiting_tasks_.size());
361
362
363   for (ScopedVector<Task>::iterator i = waiting_tasks_.begin();
364        i != waiting_tasks_.end(); ++i)
365     (*i)->Run(this);
366   waiting_tasks_.clear();
367 }
368
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());
376   DCHECK(loaded_);
377
378   InternalDeleteServerBoundCert(server_identifier);
379   InternalInsertServerBoundCert(
380       server_identifier,
381       new ServerBoundCert(
382           server_identifier, creation_time, expiration_time, private_key,
383           cert));
384 }
385
386 void DefaultServerBoundCertStore::SyncDeleteServerBoundCert(
387     const std::string& server_identifier) {
388   DCHECK(CalledOnValidThread());
389   DCHECK(loaded_);
390   InternalDeleteServerBoundCert(server_identifier);
391 }
392
393 void DefaultServerBoundCertStore::SyncDeleteAllCreatedBetween(
394     base::Time delete_begin,
395     base::Time delete_end) {
396   DCHECK(CalledOnValidThread());
397   DCHECK(loaded_);
398   for (ServerBoundCertMap::iterator it = server_bound_certs_.begin();
399        it != server_bound_certs_.end();) {
400     ServerBoundCertMap::iterator cur = it;
401     ++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)) {
405       if (store_.get())
406         store_->DeleteServerBoundCert(*cert);
407       delete cert;
408       server_bound_certs_.erase(cur);
409     }
410   }
411 }
412
413 void DefaultServerBoundCertStore::SyncGetAllServerBoundCerts(
414     ServerBoundCertList* cert_list) {
415   DCHECK(CalledOnValidThread());
416   DCHECK(loaded_);
417   for (ServerBoundCertMap::iterator it = server_bound_certs_.begin();
418        it != server_bound_certs_.end(); ++it)
419     cert_list->push_back(*it->second);
420 }
421
422 void DefaultServerBoundCertStore::EnqueueTask(scoped_ptr<Task> task) {
423   DCHECK(CalledOnValidThread());
424   DCHECK(!loaded_);
425   if (waiting_tasks_.empty())
426     waiting_tasks_start_time_ = base::TimeTicks::Now();
427   waiting_tasks_.push_back(task.release());
428 }
429
430 void DefaultServerBoundCertStore::RunOrEnqueueTask(scoped_ptr<Task> task) {
431   DCHECK(CalledOnValidThread());
432   InitIfNecessary();
433
434   if (!loaded_) {
435     EnqueueTask(task.Pass());
436     return;
437   }
438
439   task->Run(this);
440 }
441
442 void DefaultServerBoundCertStore::InternalDeleteServerBoundCert(
443     const std::string& server_identifier) {
444   DCHECK(CalledOnValidThread());
445   DCHECK(loaded_);
446
447   ServerBoundCertMap::iterator it = server_bound_certs_.find(server_identifier);
448   if (it == server_bound_certs_.end())
449     return;  // There is nothing to delete.
450
451   ServerBoundCert* cert = it->second;
452   if (store_.get())
453     store_->DeleteServerBoundCert(*cert);
454   server_bound_certs_.erase(it);
455   delete cert;
456 }
457
458 void DefaultServerBoundCertStore::InternalInsertServerBoundCert(
459     const std::string& server_identifier,
460     ServerBoundCert* cert) {
461   DCHECK(CalledOnValidThread());
462   DCHECK(loaded_);
463
464   if (store_.get())
465     store_->AddServerBoundCert(*cert);
466   server_bound_certs_[server_identifier] = cert;
467 }
468
469 DefaultServerBoundCertStore::PersistentStore::PersistentStore() {}
470
471 DefaultServerBoundCertStore::PersistentStore::~PersistentStore() {}
472
473 }  // namespace net