Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / net / ssl / channel_id_service.h
blobabb22fa686223b43c9db59e08acab6c1a70e4470
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.
5 #ifndef NET_SSL_CHANNEL_ID_SERVICE_H_
6 #define NET_SSL_CHANNEL_ID_SERVICE_H_
8 #include <map>
9 #include <string>
10 #include <vector>
12 #include "base/basictypes.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/threading/non_thread_safe.h"
16 #include "base/time/time.h"
17 #include "net/base/completion_callback.h"
18 #include "net/base/net_export.h"
19 #include "net/ssl/channel_id_store.h"
21 namespace base {
22 class TaskRunner;
23 } // namespace base
25 namespace crypto {
26 class ECPrivateKey;
27 } // namespace crypto
29 namespace net {
31 class ChannelIDServiceJob;
32 class ChannelIDServiceWorker;
34 // A class for creating and fetching Channel IDs.
36 // Inherits from NonThreadSafe in order to use the function
37 // |CalledOnValidThread|.
38 class NET_EXPORT ChannelIDService
39 : NON_EXPORTED_BASE(public base::NonThreadSafe) {
40 public:
41 class NET_EXPORT Request {
42 public:
43 Request();
44 ~Request();
46 // Cancel the request. Does nothing if the request finished or was already
47 // cancelled.
48 void Cancel();
50 bool is_active() const { return !callback_.is_null(); }
52 private:
53 friend class ChannelIDService;
54 friend class ChannelIDServiceJob;
56 void RequestStarted(ChannelIDService* service,
57 base::TimeTicks request_start,
58 const CompletionCallback& callback,
59 scoped_ptr<crypto::ECPrivateKey>* key,
60 ChannelIDServiceJob* job);
62 void Post(int error, scoped_ptr<crypto::ECPrivateKey> key);
64 ChannelIDService* service_;
65 base::TimeTicks request_start_;
66 CompletionCallback callback_;
67 scoped_ptr<crypto::ECPrivateKey>* key_;
68 ChannelIDServiceJob* job_;
71 // Password used on EncryptedPrivateKeyInfo data stored in EC private_key
72 // values. (This is not used to provide any security, but to workaround NSS
73 // being unable to import unencrypted PrivateKeyInfo for EC keys.)
74 static const char kEPKIPassword[];
76 // This object owns |channel_id_store|. |task_runner| will
77 // be used to post channel ID generation worker tasks. The tasks are
78 // safe for use with WorkerPool and SequencedWorkerPool::CONTINUE_ON_SHUTDOWN.
79 ChannelIDService(
80 ChannelIDStore* channel_id_store,
81 const scoped_refptr<base::TaskRunner>& task_runner);
83 ~ChannelIDService();
85 // Returns the domain to be used for |host|. The domain is the
86 // "registry controlled domain", or the "ETLD + 1" where one exists, or
87 // the origin otherwise.
88 static std::string GetDomainForHost(const std::string& host);
90 // Fetches the channel ID for the specified host if one exists and
91 // creates one otherwise. Returns OK if successful or an error code upon
92 // failure.
94 // On successful completion, |key| holds the ECDSA keypair used for this
95 // channel ID.
97 // |callback| must not be null. ERR_IO_PENDING is returned if the operation
98 // could not be completed immediately, in which case the result code will
99 // be passed to the callback when available.
101 // |*out_req| will be initialized with a handle to the async request.
102 int GetOrCreateChannelID(const std::string& host,
103 scoped_ptr<crypto::ECPrivateKey>* key,
104 const CompletionCallback& callback,
105 Request* out_req);
107 // Fetches the channel ID for the specified host if one exists.
108 // Returns OK if successful, ERR_FILE_NOT_FOUND if none exists, or an error
109 // code upon failure.
111 // On successful completion, |key| holds the ECDSA keypair used for this
112 // channel ID.
114 // |callback| must not be null. ERR_IO_PENDING is returned if the operation
115 // could not be completed immediately, in which case the result code will
116 // be passed to the callback when available. If an in-flight
117 // GetChannelID is pending, and a new GetOrCreateChannelID
118 // request arrives for the same domain, the GetChannelID request will
119 // not complete until a new channel ID is created.
121 // |*out_req| will be initialized with a handle to the async request.
122 int GetChannelID(const std::string& host,
123 scoped_ptr<crypto::ECPrivateKey>* key,
124 const CompletionCallback& callback,
125 Request* out_req);
127 // Returns the backing ChannelIDStore.
128 ChannelIDStore* GetChannelIDStore();
130 // Public only for unit testing.
131 int channel_id_count();
132 uint64 requests() const { return requests_; }
133 uint64 key_store_hits() const { return key_store_hits_; }
134 uint64 inflight_joins() const { return inflight_joins_; }
135 uint64 workers_created() const { return workers_created_; }
137 private:
138 void GotChannelID(int err,
139 const std::string& server_identifier,
140 scoped_ptr<crypto::ECPrivateKey> key);
141 void GeneratedChannelID(
142 const std::string& server_identifier,
143 int error,
144 scoped_ptr<ChannelIDStore::ChannelID> channel_id);
145 void HandleResult(int error,
146 const std::string& server_identifier,
147 scoped_ptr<crypto::ECPrivateKey> key);
149 // Searches for an in-flight request for the same domain. If found,
150 // attaches to the request and returns true. Returns false if no in-flight
151 // request is found.
152 bool JoinToInFlightRequest(const base::TimeTicks& request_start,
153 const std::string& domain,
154 scoped_ptr<crypto::ECPrivateKey>* key,
155 bool create_if_missing,
156 const CompletionCallback& callback,
157 Request* out_req);
159 // Looks for the channel ID for |domain| in this service's store.
160 // Returns OK if it can be found synchronously, ERR_IO_PENDING if the
161 // result cannot be obtained synchronously, or a network error code on
162 // failure (including failure to find a channel ID of |domain|).
163 int LookupChannelID(const base::TimeTicks& request_start,
164 const std::string& domain,
165 scoped_ptr<crypto::ECPrivateKey>* key,
166 bool create_if_missing,
167 const CompletionCallback& callback,
168 Request* out_req);
170 scoped_ptr<ChannelIDStore> channel_id_store_;
171 scoped_refptr<base::TaskRunner> task_runner_;
173 // inflight_ maps from a server to an active generation which is taking
174 // place.
175 std::map<std::string, ChannelIDServiceJob*> inflight_;
177 uint64 requests_;
178 uint64 key_store_hits_;
179 uint64 inflight_joins_;
180 uint64 workers_created_;
182 base::WeakPtrFactory<ChannelIDService> weak_ptr_factory_;
184 DISALLOW_COPY_AND_ASSIGN(ChannelIDService);
187 } // namespace net
189 #endif // NET_SSL_CHANNEL_ID_SERVICE_H_