summaryrefslogtreecommitdiffstats
path: root/net/ssl/default_channel_id_store.h
blob: 9b986373226ebe3aa5f6554ffb7c560c810c796b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_SSL_DEFAULT_CHANNEL_ID_STORE_H_
#define NET_SSL_DEFAULT_CHANNEL_ID_STORE_H_

#include <map>
#include <string>
#include <vector>

#include "base/callback_forward.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "net/base/net_export.h"
#include "net/ssl/channel_id_store.h"

namespace net {

// This class is the system for storing and retrieving server bound certs.
// Modeled after the CookieMonster class, it has an in-memory cert store,
// and synchronizes server bound certs to an optional permanent storage that
// implements the PersistentStore interface. The use case is described in
// http://balfanz.github.com/tls-obc-spec/draft-balfanz-tls-obc-00.html
// TODO(wtc): Update this comment.
class NET_EXPORT DefaultChannelIDStore : public ChannelIDStore {
 public:
  class PersistentStore;

  // The key for each ChannelID* in ChannelIDMap is the
  // corresponding server.
  typedef std::map<std::string, ChannelID*> ChannelIDMap;

  // The store passed in should not have had Init() called on it yet. This
  // class will take care of initializing it. The backing store is NOT owned by
  // this class, but it must remain valid for the duration of the
  // DefaultChannelIDStore's existence. If |store| is NULL, then no
  // backing store will be updated.
  explicit DefaultChannelIDStore(PersistentStore* store);

  ~DefaultChannelIDStore() override;

  // ChannelIDStore implementation.
  int GetChannelID(const std::string& server_identifier,
                   base::Time* expiration_time,
                   std::string* private_key_result,
                   std::string* cert_result,
                   const GetChannelIDCallback& callback) override;
  void SetChannelID(const std::string& server_identifier,
                    base::Time creation_time,
                    base::Time expiration_time,
                    const std::string& private_key,
                    const std::string& cert) override;
  void DeleteChannelID(const std::string& server_identifier,
                       const base::Closure& callback) override;
  void DeleteAllCreatedBetween(base::Time delete_begin,
                               base::Time delete_end,
                               const base::Closure& callback) override;
  void DeleteAll(const base::Closure& callback) override;
  void GetAllChannelIDs(const GetChannelIDListCallback& callback) override;
  int GetChannelIDCount() override;
  void SetForceKeepSessionState() override;

 private:
  class Task;
  class GetChannelIDTask;
  class SetChannelIDTask;
  class DeleteChannelIDTask;
  class DeleteAllCreatedBetweenTask;
  class GetAllChannelIDsTask;

  // Deletes all of the certs. Does not delete them from |store_|.
  void DeleteAllInMemory();

  // Called by all non-static functions to ensure that the cert store has
  // been initialized.
  // TODO(mattm): since we load asynchronously now, maybe we should start
  // loading immediately on construction, or provide some method to initiate
  // loading?
  void InitIfNecessary() {
    if (!initialized_) {
      if (store_.get()) {
        InitStore();
      } else {
        loaded_ = true;
      }
      initialized_ = true;
    }
  }

  // Initializes the backing store and reads existing certs from it.
  // Should only be called by InitIfNecessary().
  void InitStore();

  // Callback for backing store loading completion.
  void OnLoaded(scoped_ptr<ScopedVector<ChannelID> > certs);

  // Syncronous methods which do the actual work. Can only be called after
  // initialization is complete.
  void SyncSetChannelID(
      const std::string& server_identifier,
      base::Time creation_time,
      base::Time expiration_time,
      const std::string& private_key,
      const std::string& cert);
  void SyncDeleteChannelID(const std::string& server_identifier);
  void SyncDeleteAllCreatedBetween(base::Time delete_begin,
                                   base::Time delete_end);
  void SyncGetAllChannelIDs(ChannelIDList* channel_id_list);

  // Add |task| to |waiting_tasks_|.
  void EnqueueTask(scoped_ptr<Task> task);
  // If already initialized, run |task| immediately. Otherwise add it to
  // |waiting_tasks_|.
  void RunOrEnqueueTask(scoped_ptr<Task> task);

  // Deletes the channel id for the specified server, if such a channel id
  // exists, from the in-memory store. Deletes it from |store_| if |store_|
  // is not NULL.
  void InternalDeleteChannelID(const std::string& server);

  // Takes ownership of *channel_id.
  // Adds the channel id for the specified server to the in-memory store.
  // Deletes it from |store_| if |store_| is not NULL.
  void InternalInsertChannelID(const std::string& server_identifier,
                               ChannelID* channel_id);

  // Indicates whether the channel id store has been initialized. This happens
  // lazily in InitIfNecessary().
  bool initialized_;

  // Indicates whether loading from the backend store is completed and
  // calls may be immediately processed.
  bool loaded_;

  // Tasks that are waiting to be run once we finish loading.
  ScopedVector<Task> waiting_tasks_;
  base::TimeTicks waiting_tasks_start_time_;

  scoped_refptr<PersistentStore> store_;

  ChannelIDMap channel_ids_;

  base::WeakPtrFactory<DefaultChannelIDStore> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(DefaultChannelIDStore);
};

typedef base::RefCountedThreadSafe<DefaultChannelIDStore::PersistentStore>
    RefcountedPersistentStore;

class NET_EXPORT DefaultChannelIDStore::PersistentStore
    : public RefcountedPersistentStore {
 public:
  typedef base::Callback<void(scoped_ptr<ScopedVector<ChannelID> >)>
      LoadedCallback;

  // Initializes the store and retrieves the existing channel_ids. This will be
  // called only once at startup. Note that the channel_ids are individually
  // allocated and that ownership is transferred to the caller upon return.
  // The |loaded_callback| must not be called synchronously.
  virtual void Load(const LoadedCallback& loaded_callback) = 0;

  virtual void AddChannelID(const ChannelID& channel_id) = 0;

  virtual void DeleteChannelID(const ChannelID& channel_id) = 0;

  // When invoked, instructs the store to keep session related data on
  // destruction.
  virtual void SetForceKeepSessionState() = 0;

 protected:
  friend class base::RefCountedThreadSafe<PersistentStore>;

  PersistentStore();
  virtual ~PersistentStore();

 private:
  DISALLOW_COPY_AND_ASSIGN(PersistentStore);
};

}  // namespace net

#endif  // NET_SSL_DEFAULT_CHANNEL_ID_STORE_H_