• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 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 #ifndef NET_SSL_DEFAULT_CHANNEL_ID_STORE_H_
6 #define NET_SSL_DEFAULT_CHANNEL_ID_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/channel_id_store.h"
20 
21 namespace 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
28 // TODO(wtc): Update this comment.
29 class NET_EXPORT DefaultChannelIDStore : public ChannelIDStore {
30  public:
31   class PersistentStore;
32 
33   // The key for each ChannelID* in ChannelIDMap is the
34   // corresponding server.
35   typedef std::map<std::string, ChannelID*> ChannelIDMap;
36 
37   // The store passed in should not have had Init() called on it yet. This
38   // class will take care of initializing it. The backing store is NOT owned by
39   // this class, but it must remain valid for the duration of the
40   // DefaultChannelIDStore's existence. If |store| is NULL, then no
41   // backing store will be updated.
42   explicit DefaultChannelIDStore(PersistentStore* store);
43 
44   virtual ~DefaultChannelIDStore();
45 
46   // ChannelIDStore implementation.
47   virtual int GetChannelID(
48       const std::string& server_identifier,
49       base::Time* expiration_time,
50       std::string* private_key_result,
51       std::string* cert_result,
52       const GetChannelIDCallback& callback) OVERRIDE;
53   virtual void SetChannelID(
54       const std::string& server_identifier,
55       base::Time creation_time,
56       base::Time expiration_time,
57       const std::string& private_key,
58       const std::string& cert) OVERRIDE;
59   virtual void DeleteChannelID(
60       const std::string& server_identifier,
61       const base::Closure& callback) OVERRIDE;
62   virtual void DeleteAllCreatedBetween(
63       base::Time delete_begin,
64       base::Time delete_end,
65       const base::Closure& callback) OVERRIDE;
66   virtual void DeleteAll(const base::Closure& callback) OVERRIDE;
67   virtual void GetAllChannelIDs(
68       const GetChannelIDListCallback& callback) OVERRIDE;
69   virtual int GetChannelIDCount() OVERRIDE;
70   virtual void SetForceKeepSessionState() OVERRIDE;
71 
72  private:
73   class Task;
74   class GetChannelIDTask;
75   class SetChannelIDTask;
76   class DeleteChannelIDTask;
77   class DeleteAllCreatedBetweenTask;
78   class GetAllChannelIDsTask;
79 
80   // Deletes all of the certs. Does not delete them from |store_|.
81   void DeleteAllInMemory();
82 
83   // Called by all non-static functions to ensure that the cert store has
84   // been initialized.
85   // TODO(mattm): since we load asynchronously now, maybe we should start
86   // loading immediately on construction, or provide some method to initiate
87   // loading?
InitIfNecessary()88   void InitIfNecessary() {
89     if (!initialized_) {
90       if (store_.get()) {
91         InitStore();
92       } else {
93         loaded_ = true;
94       }
95       initialized_ = true;
96     }
97   }
98 
99   // Initializes the backing store and reads existing certs from it.
100   // Should only be called by InitIfNecessary().
101   void InitStore();
102 
103   // Callback for backing store loading completion.
104   void OnLoaded(scoped_ptr<ScopedVector<ChannelID> > certs);
105 
106   // Syncronous methods which do the actual work. Can only be called after
107   // initialization is complete.
108   void SyncSetChannelID(
109       const std::string& server_identifier,
110       base::Time creation_time,
111       base::Time expiration_time,
112       const std::string& private_key,
113       const std::string& cert);
114   void SyncDeleteChannelID(const std::string& server_identifier);
115   void SyncDeleteAllCreatedBetween(base::Time delete_begin,
116                                    base::Time delete_end);
117   void SyncGetAllChannelIDs(ChannelIDList* channel_id_list);
118 
119   // Add |task| to |waiting_tasks_|.
120   void EnqueueTask(scoped_ptr<Task> task);
121   // If already initialized, run |task| immediately. Otherwise add it to
122   // |waiting_tasks_|.
123   void RunOrEnqueueTask(scoped_ptr<Task> task);
124 
125   // Deletes the channel id for the specified server, if such a channel id
126   // exists, from the in-memory store. Deletes it from |store_| if |store_|
127   // is not NULL.
128   void InternalDeleteChannelID(const std::string& server);
129 
130   // Takes ownership of *channel_id.
131   // Adds the channel id for the specified server to the in-memory store.
132   // Deletes it from |store_| if |store_| is not NULL.
133   void InternalInsertChannelID(const std::string& server_identifier,
134                                ChannelID* channel_id);
135 
136   // Indicates whether the channel id 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   ChannelIDMap channel_ids_;
151 
152   base::WeakPtrFactory<DefaultChannelIDStore> weak_ptr_factory_;
153 
154   DISALLOW_COPY_AND_ASSIGN(DefaultChannelIDStore);
155 };
156 
157 typedef base::RefCountedThreadSafe<DefaultChannelIDStore::PersistentStore>
158     RefcountedPersistentStore;
159 
160 class NET_EXPORT DefaultChannelIDStore::PersistentStore
161     : public RefcountedPersistentStore {
162  public:
163   typedef base::Callback<void(scoped_ptr<ScopedVector<ChannelID> >)>
164       LoadedCallback;
165 
166   // Initializes the store and retrieves the existing channel_ids. This will be
167   // called only once at startup. Note that the channel_ids are individually
168   // allocated 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 AddChannelID(const ChannelID& channel_id) = 0;
173 
174   virtual void DeleteChannelID(const ChannelID& channel_id) = 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_CHANNEL_ID_STORE_H_
193