Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Side by Side Diff: content/browser/media/webrtc/webrtc_identity_store.cc

Issue 2033353002: Remove PeerConnectionIdentityStore and related messaging/storage code. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Delayed deletion by 120s Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 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 "content/browser/media/webrtc/webrtc_identity_store.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <map>
11
12 #include "base/bind.h"
13 #include "base/callback_helpers.h"
14 #include "base/logging.h"
15 #include "base/macros.h"
16 #include "base/rand_util.h"
17 #include "base/threading/worker_pool.h"
18 #include "content/browser/media/webrtc/webrtc_identity_store_backend.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "crypto/rsa_private_key.h"
21 #include "net/base/net_errors.h"
22 #include "net/cert/x509_util.h"
23 #include "url/gurl.h"
24
25 namespace content {
26
27 struct WebRTCIdentityRequestResult {
28 WebRTCIdentityRequestResult(int error,
29 const std::string& certificate,
30 const std::string& private_key)
31 : error(error), certificate(certificate), private_key(private_key) {}
32
33 int error;
34 std::string certificate;
35 std::string private_key;
36 };
37
38 // Generates a new identity using |common_name| which expires after
39 // |validity_period| and returns the result in |result|.
40 static void GenerateIdentityWorker(const std::string& common_name,
41 base::TimeDelta validity_period,
42 WebRTCIdentityRequestResult* result) {
43 result->error = net::OK;
44 int serial_number = base::RandInt(0, std::numeric_limits<int>::max());
45
46 std::unique_ptr<crypto::RSAPrivateKey> key;
47 base::Time now = base::Time::Now();
48 bool success = net::x509_util::CreateKeyAndSelfSignedCert(
49 "CN=" + common_name,
50 serial_number,
51 now,
52 now + validity_period,
53 &key,
54 &result->certificate);
55
56 if (!success) {
57 DLOG(ERROR) << "Unable to create x509 cert for client";
58 result->error = net::ERR_SELF_SIGNED_CERT_GENERATION_FAILED;
59 return;
60 }
61
62 std::vector<uint8_t> private_key_info;
63 if (!key->ExportPrivateKey(&private_key_info)) {
64 DLOG(ERROR) << "Unable to export private key";
65 result->error = net::ERR_PRIVATE_KEY_EXPORT_FAILED;
66 return;
67 }
68
69 result->private_key =
70 std::string(private_key_info.begin(), private_key_info.end());
71 }
72
73 class WebRTCIdentityRequestHandle;
74
75 // The class represents an identity request internal to WebRTCIdentityStore.
76 // It has a one-to-many mapping to the external version of the request,
77 // WebRTCIdentityRequestHandle, i.e. multiple identical external requests are
78 // combined into one internal request.
79 // It's deleted automatically when the request is completed.
80 class WebRTCIdentityRequest {
81 public:
82 WebRTCIdentityRequest(const GURL& origin,
83 const std::string& identity_name,
84 const std::string& common_name,
85 bool enable_cache)
86 : origin_(origin),
87 identity_name_(identity_name),
88 common_name_(common_name),
89 enable_cache_(enable_cache) {}
90
91 void Cancel(WebRTCIdentityRequestHandle* handle) {
92 DCHECK_CURRENTLY_ON(BrowserThread::IO);
93 if (callbacks_.find(handle) == callbacks_.end())
94 return;
95 callbacks_.erase(handle);
96 }
97
98 bool enable_cache() const { return enable_cache_; }
99
100 private:
101 friend class WebRTCIdentityStore;
102
103 void AddCallback(WebRTCIdentityRequestHandle* handle,
104 const WebRTCIdentityStore::CompletionCallback& callback) {
105 DCHECK(callbacks_.find(handle) == callbacks_.end());
106 callbacks_[handle] = callback;
107 }
108
109 // This method deletes "this" and no one should access it after the request
110 // completes.
111 // We do not use base::Owned to tie its lifetime to the callback for
112 // WebRTCIdentityStoreBackend::FindIdentity, because it needs to live longer
113 // than that if the identity does not exist in DB.
114 void Post(const WebRTCIdentityRequestResult& result) {
115 DCHECK_CURRENTLY_ON(BrowserThread::IO);
116 for (CallbackMap::iterator it = callbacks_.begin(); it != callbacks_.end();
117 ++it)
118 it->second.Run(result.error, result.certificate, result.private_key);
119 delete this;
120 }
121
122 GURL origin_;
123 std::string identity_name_;
124 std::string common_name_;
125 typedef std::map<WebRTCIdentityRequestHandle*,
126 WebRTCIdentityStore::CompletionCallback> CallbackMap;
127 CallbackMap callbacks_;
128 bool enable_cache_;
129 };
130
131 // The class represents an identity request which calls back to the external
132 // client when the request completes.
133 // Its lifetime is tied with the Callback held by the corresponding
134 // WebRTCIdentityRequest.
135 class WebRTCIdentityRequestHandle {
136 public:
137 WebRTCIdentityRequestHandle(
138 WebRTCIdentityStore* store,
139 const WebRTCIdentityStore::CompletionCallback& callback)
140 : request_(NULL), callback_(callback) {}
141
142 private:
143 friend class WebRTCIdentityStore;
144
145 // Cancel the request. Does nothing if the request finished or was already
146 // cancelled.
147 void Cancel() {
148 DCHECK_CURRENTLY_ON(BrowserThread::IO);
149 if (!request_)
150 return;
151
152 callback_.Reset();
153 WebRTCIdentityRequest* request = request_;
154 request_ = NULL;
155 // "this" will be deleted after the following call, because "this" is
156 // owned by the Callback held by |request|.
157 request->Cancel(this);
158 }
159
160 void OnRequestStarted(WebRTCIdentityRequest* request) {
161 DCHECK_CURRENTLY_ON(BrowserThread::IO);
162 DCHECK(request);
163 request_ = request;
164 }
165
166 void OnRequestComplete(int error,
167 const std::string& certificate,
168 const std::string& private_key) {
169 DCHECK_CURRENTLY_ON(BrowserThread::IO);
170 DCHECK(request_);
171 request_ = NULL;
172 base::ResetAndReturn(&callback_).Run(error, certificate, private_key);
173 }
174
175 WebRTCIdentityRequest* request_;
176 WebRTCIdentityStore::CompletionCallback callback_;
177
178 DISALLOW_COPY_AND_ASSIGN(WebRTCIdentityRequestHandle);
179 };
180
181 WebRTCIdentityStore::WebRTCIdentityStore(const base::FilePath& path,
182 storage::SpecialStoragePolicy* policy)
183 : validity_period_(base::TimeDelta::FromDays(30)),
184 task_runner_(base::WorkerPool::GetTaskRunner(true)),
185 backend_(new WebRTCIdentityStoreBackend(path, policy, validity_period_)) {
186 }
187
188 WebRTCIdentityStore::~WebRTCIdentityStore() { backend_->Close(); }
189
190 base::Closure WebRTCIdentityStore::RequestIdentity(
191 const GURL& origin,
192 const std::string& identity_name,
193 const std::string& common_name,
194 const CompletionCallback& callback,
195 bool enable_cache) {
196 DCHECK_CURRENTLY_ON(BrowserThread::IO);
197 WebRTCIdentityRequest* request =
198 FindRequest(origin, identity_name, common_name);
199 // If there is no identical request in flight, create a new one, queue it,
200 // and make the backend request.
201 if (!request) {
202 request = new WebRTCIdentityRequest(origin, identity_name, common_name,
203 enable_cache);
204 // In either case, |request| will delete itself after the result is posted.
205 if (enable_cache) {
206 if (!backend_->FindIdentity(
207 origin, identity_name, common_name,
208 base::Bind(&WebRTCIdentityStore::BackendFindCallback, this,
209 request))) {
210 // Bail out if the backend failed to start the task.
211 delete request;
212 return base::Closure();
213 }
214 } else {
215 GenerateNewIdentity(request);
216 }
217 in_flight_requests_.push_back(request);
218 }
219
220 WebRTCIdentityRequestHandle* handle =
221 new WebRTCIdentityRequestHandle(this, callback);
222
223 request->AddCallback(
224 handle,
225 base::Bind(&WebRTCIdentityRequestHandle::OnRequestComplete,
226 base::Owned(handle)));
227 handle->OnRequestStarted(request);
228 return base::Bind(&WebRTCIdentityRequestHandle::Cancel,
229 base::Unretained(handle));
230 }
231
232 void WebRTCIdentityStore::DeleteBetween(base::Time delete_begin,
233 base::Time delete_end,
234 const base::Closure& callback) {
235 DCHECK_CURRENTLY_ON(BrowserThread::IO);
236 backend_->DeleteBetween(delete_begin, delete_end, callback);
237 }
238
239 void WebRTCIdentityStore::SetValidityPeriodForTesting(
240 base::TimeDelta validity_period) {
241 DCHECK_CURRENTLY_ON(BrowserThread::IO);
242 validity_period_ = validity_period;
243 backend_->SetValidityPeriodForTesting(validity_period);
244 }
245
246 void WebRTCIdentityStore::SetTaskRunnerForTesting(
247 const scoped_refptr<base::TaskRunner>& task_runner) {
248 DCHECK_CURRENTLY_ON(BrowserThread::IO);
249 task_runner_ = task_runner;
250 }
251
252 void WebRTCIdentityStore::BackendFindCallback(WebRTCIdentityRequest* request,
253 int error,
254 const std::string& certificate,
255 const std::string& private_key) {
256 DCHECK_CURRENTLY_ON(BrowserThread::IO);
257 if (error == net::OK) {
258 DVLOG(2) << "Identity found in DB.";
259 WebRTCIdentityRequestResult result(error, certificate, private_key);
260 PostRequestResult(request, result);
261 return;
262 }
263 GenerateNewIdentity(request);
264 }
265
266 void WebRTCIdentityStore::GenerateIdentityCallback(
267 WebRTCIdentityRequest* request,
268 WebRTCIdentityRequestResult* result) {
269 DCHECK_CURRENTLY_ON(BrowserThread::IO);
270 if (result->error == net::OK && request->enable_cache()) {
271 DVLOG(2) << "New identity generated and added to the backend.";
272 backend_->AddIdentity(request->origin_,
273 request->identity_name_,
274 request->common_name_,
275 result->certificate,
276 result->private_key);
277 }
278 PostRequestResult(request, *result);
279 }
280
281 void WebRTCIdentityStore::PostRequestResult(
282 WebRTCIdentityRequest* request,
283 const WebRTCIdentityRequestResult& result) {
284 DCHECK_CURRENTLY_ON(BrowserThread::IO);
285 // Removes the in flight request from the queue.
286 for (size_t i = 0; i < in_flight_requests_.size(); ++i) {
287 if (in_flight_requests_[i] == request) {
288 in_flight_requests_.erase(in_flight_requests_.begin() + i);
289 break;
290 }
291 }
292 // |request| will be deleted after this call.
293 request->Post(result);
294 }
295
296 // Find an identical request from the in flight requests.
297 WebRTCIdentityRequest* WebRTCIdentityStore::FindRequest(
298 const GURL& origin,
299 const std::string& identity_name,
300 const std::string& common_name) {
301 for (size_t i = 0; i < in_flight_requests_.size(); ++i) {
302 if (in_flight_requests_[i]->origin_ == origin &&
303 in_flight_requests_[i]->identity_name_ == identity_name &&
304 in_flight_requests_[i]->common_name_ == common_name) {
305 return in_flight_requests_[i];
306 }
307 }
308 return NULL;
309 }
310
311 void WebRTCIdentityStore::GenerateNewIdentity(WebRTCIdentityRequest* request) {
312 WebRTCIdentityRequestResult* result =
313 new WebRTCIdentityRequestResult(0, "", "");
314 if (!task_runner_->PostTaskAndReply(
315 FROM_HERE, base::Bind(&GenerateIdentityWorker, request->common_name_,
316 validity_period_, result),
317 base::Bind(&WebRTCIdentityStore::GenerateIdentityCallback, this,
318 request, base::Owned(result)))) {
319 // Completes the request with error if failed to post the task.
320 WebRTCIdentityRequestResult result(net::ERR_UNEXPECTED, "", "");
321 PostRequestResult(request, result);
322 }
323 }
324
325 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/media/webrtc/webrtc_identity_store.h ('k') | content/browser/media/webrtc/webrtc_identity_store_backend.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698