blob: 61282182f8e584b9207be06418ee3f8e2e3d70ae [file] [log] [blame]
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001// 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#ifndef NET_SSL_DEFAULT_SERVER_BOUND_CERT_STORE_H_
6#define NET_SSL_DEFAULT_SERVER_BOUND_CERT_STORE_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/callback_forward.h"
13#include "base/compiler_specific.h"
14#include "base/memory/ref_counted.h"
15#include "base/memory/scoped_ptr.h"
16#include "base/memory/scoped_vector.h"
17#include "base/memory/weak_ptr.h"
18#include "net/base/net_export.h"
19#include "net/ssl/server_bound_cert_store.h"
20
21namespace net {
22
23// This class is the system for storing and retrieving server bound certs.
24// Modeled after the CookieMonster class, it has an in-memory cert store,
25// and synchronizes server bound certs to an optional permanent storage that
26// implements the PersistentStore interface. The use case is described in
27// http://balfanz.github.com/tls-obc-spec/draft-balfanz-tls-obc-00.html
28class NET_EXPORT DefaultServerBoundCertStore : public ServerBoundCertStore {
29 public:
30 class PersistentStore;
31
32 // The key for each ServerBoundCert* in ServerBoundCertMap is the
33 // corresponding server.
34 typedef std::map<std::string, ServerBoundCert*> ServerBoundCertMap;
35
36 // The store passed in should not have had Init() called on it yet. This
37 // class will take care of initializing it. The backing store is NOT owned by
38 // this class, but it must remain valid for the duration of the
39 // DefaultServerBoundCertStore's existence. If |store| is NULL, then no
40 // backing store will be updated.
41 explicit DefaultServerBoundCertStore(PersistentStore* store);
42
43 virtual ~DefaultServerBoundCertStore();
44
45 // ServerBoundCertStore implementation.
Ben Murdochbb1529c2013-08-08 10:24:53 +010046 virtual int GetServerBoundCert(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000047 const std::string& server_identifier,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000048 base::Time* expiration_time,
49 std::string* private_key_result,
50 std::string* cert_result,
51 const GetCertCallback& callback) OVERRIDE;
52 virtual void SetServerBoundCert(
53 const std::string& server_identifier,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000054 base::Time creation_time,
55 base::Time expiration_time,
56 const std::string& private_key,
57 const std::string& cert) OVERRIDE;
58 virtual void DeleteServerBoundCert(
59 const std::string& server_identifier,
60 const base::Closure& callback) OVERRIDE;
61 virtual void DeleteAllCreatedBetween(
62 base::Time delete_begin,
63 base::Time delete_end,
64 const base::Closure& callback) OVERRIDE;
65 virtual void DeleteAll(const base::Closure& callback) OVERRIDE;
66 virtual void GetAllServerBoundCerts(
67 const GetCertListCallback& callback) OVERRIDE;
68 virtual int GetCertCount() OVERRIDE;
69 virtual void SetForceKeepSessionState() OVERRIDE;
70
71 private:
72 class Task;
73 class GetServerBoundCertTask;
74 class SetServerBoundCertTask;
75 class DeleteServerBoundCertTask;
76 class DeleteAllCreatedBetweenTask;
77 class GetAllServerBoundCertsTask;
78
79 static const size_t kMaxCerts;
80
81 // Deletes all of the certs. Does not delete them from |store_|.
82 void DeleteAllInMemory();
83
84 // Called by all non-static functions to ensure that the cert store has
85 // been initialized.
86 // TODO(mattm): since we load asynchronously now, maybe we should start
87 // loading immediately on construction, or provide some method to initiate
88 // loading?
89 void InitIfNecessary() {
90 if (!initialized_) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010091 if (store_.get()) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000092 InitStore();
93 } else {
94 loaded_ = true;
95 }
96 initialized_ = true;
97 }
98 }
99
100 // Initializes the backing store and reads existing certs from it.
101 // Should only be called by InitIfNecessary().
102 void InitStore();
103
104 // Callback for backing store loading completion.
105 void OnLoaded(scoped_ptr<ScopedVector<ServerBoundCert> > certs);
106
107 // Syncronous methods which do the actual work. Can only be called after
108 // initialization is complete.
109 void SyncSetServerBoundCert(
110 const std::string& server_identifier,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000111 base::Time creation_time,
112 base::Time expiration_time,
113 const std::string& private_key,
114 const std::string& cert);
115 void SyncDeleteServerBoundCert(const std::string& server_identifier);
116 void SyncDeleteAllCreatedBetween(base::Time delete_begin,
117 base::Time delete_end);
118 void SyncGetAllServerBoundCerts(ServerBoundCertList* cert_list);
119
120 // Add |task| to |waiting_tasks_|.
121 void EnqueueTask(scoped_ptr<Task> task);
122 // If already initialized, run |task| immediately. Otherwise add it to
123 // |waiting_tasks_|.
124 void RunOrEnqueueTask(scoped_ptr<Task> task);
125
126 // Deletes the cert for the specified server, if such a cert exists, from the
127 // in-memory store. Deletes it from |store_| if |store_| is not NULL.
128 void InternalDeleteServerBoundCert(const std::string& server);
129
130 // Takes ownership of *cert.
131 // Adds the cert for the specified server to the in-memory store. Deletes it
132 // from |store_| if |store_| is not NULL.
133 void InternalInsertServerBoundCert(const std::string& server_identifier,
134 ServerBoundCert* cert);
135
136 // Indicates whether the cert store has been initialized. This happens
137 // lazily in InitIfNecessary().
138 bool initialized_;
139
140 // Indicates whether loading from the backend store is completed and
141 // calls may be immediately processed.
142 bool loaded_;
143
144 // Tasks that are waiting to be run once we finish loading.
145 ScopedVector<Task> waiting_tasks_;
146 base::TimeTicks waiting_tasks_start_time_;
147
148 scoped_refptr<PersistentStore> store_;
149
150 ServerBoundCertMap server_bound_certs_;
151
152 base::WeakPtrFactory<DefaultServerBoundCertStore> weak_ptr_factory_;
153
154 DISALLOW_COPY_AND_ASSIGN(DefaultServerBoundCertStore);
155};
156
157typedef base::RefCountedThreadSafe<DefaultServerBoundCertStore::PersistentStore>
158 RefcountedPersistentStore;
159
160class NET_EXPORT DefaultServerBoundCertStore::PersistentStore
161 : public RefcountedPersistentStore {
162 public:
163 typedef base::Callback<void(scoped_ptr<ScopedVector<ServerBoundCert> >)>
164 LoadedCallback;
165
166 // Initializes the store and retrieves the existing certs. This will be
167 // called only once at startup. Note that the certs are individually allocated
168 // and that ownership is transferred to the caller upon return.
169 // The |loaded_callback| must not be called synchronously.
170 virtual void Load(const LoadedCallback& loaded_callback) = 0;
171
172 virtual void AddServerBoundCert(const ServerBoundCert& cert) = 0;
173
174 virtual void DeleteServerBoundCert(const ServerBoundCert& cert) = 0;
175
176 // When invoked, instructs the store to keep session related data on
177 // destruction.
178 virtual void SetForceKeepSessionState() = 0;
179
180 protected:
181 friend class base::RefCountedThreadSafe<PersistentStore>;
182
183 PersistentStore();
184 virtual ~PersistentStore();
185
186 private:
187 DISALLOW_COPY_AND_ASSIGN(PersistentStore);
188};
189
190} // namespace net
191
192#endif // NET_SSL_DEFAULT_SERVER_BOUND_CERT_STORE_H_