1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/browser/media/webrtc_identity_store.h" 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <map> 8ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/bind.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/callback_helpers.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/logging.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/rand_util.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/threading/worker_pool.h" 14ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "content/browser/media/webrtc_identity_store_backend.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/browser_thread.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "crypto/rsa_private_key.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/base/net_errors.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/cert/x509_util.h" 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace content { 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct WebRTCIdentityRequestResult { 24ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch WebRTCIdentityRequestResult(int error, 25ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& certificate, 26ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& private_key) 27ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : error(error), certificate(certificate), private_key(private_key) {} 28ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int error; 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string certificate; 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string private_key; 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Generates a new identity using |common_name| which expires after 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// |validity_period| and returns the result in |result|. 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic void GenerateIdentityWorker(const std::string& common_name, 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta validity_period, 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch WebRTCIdentityRequestResult* result) { 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch result->error = net::OK; 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int serial_number = base::RandInt(0, std::numeric_limits<int>::max()); 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_ptr<crypto::RSAPrivateKey> key; 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Time now = base::Time::Now(); 440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bool success = net::x509_util::CreateKeyAndSelfSignedCert( 450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) "CN=" + common_name, 460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) serial_number, 470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) now, 480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) now + validity_period, 490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &key, 500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &result->certificate); 510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!success) { 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DLOG(ERROR) << "Unable to create x509 cert for client"; 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch result->error = net::ERR_SELF_SIGNED_CERT_GENERATION_FAILED; 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<uint8> private_key_info; 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!key->ExportPrivateKey(&private_key_info)) { 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DLOG(ERROR) << "Unable to export private key"; 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch result->error = net::ERR_PRIVATE_KEY_EXPORT_FAILED; 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch result->private_key = 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string(private_key_info.begin(), private_key_info.end()); 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass WebRTCIdentityRequestHandle; 70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The class represents an identity request internal to WebRTCIdentityStore. 72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// It has a one-to-many mapping to the external version of the request, 73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// WebRTCIdentityRequestHandle, i.e. multiple identical external requests are 74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// combined into one internal request. 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// It's deleted automatically when the request is completed. 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass WebRTCIdentityRequest { 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch WebRTCIdentityRequest(const GURL& origin, 79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& identity_name, 80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& common_name) 81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : origin_(origin), 82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch identity_name_(identity_name), 83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch common_name_(common_name) {} 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void Cancel(WebRTCIdentityRequestHandle* handle) { 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 87ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (callbacks_.find(handle) == callbacks_.end()) 88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 89ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch callbacks_.erase(handle); 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch friend class WebRTCIdentityStore; 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void AddCallback(WebRTCIdentityRequestHandle* handle, 96ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const WebRTCIdentityStore::CompletionCallback& callback) { 97ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(callbacks_.find(handle) == callbacks_.end()); 98ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch callbacks_[handle] = callback; 99ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // This method deletes "this" and no one should access it after the request 102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // completes. 103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // We do not use base::Owned to tie its lifetime to the callback for 104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // WebRTCIdentityStoreBackend::FindIdentity, because it needs to live longer 105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // than that if the identity does not exist in DB. 106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void Post(const WebRTCIdentityRequestResult& result) { 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (CallbackMap::iterator it = callbacks_.begin(); it != callbacks_.end(); 109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ++it) 110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch it->second.Run(result.error, result.certificate, result.private_key); 111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch delete this; 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GURL origin_; 115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string identity_name_; 116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string common_name_; 117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch typedef std::map<WebRTCIdentityRequestHandle*, 118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch WebRTCIdentityStore::CompletionCallback> CallbackMap; 119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CallbackMap callbacks_; 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The class represents an identity request which calls back to the external 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// client when the request completes. 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Its lifetime is tied with the Callback held by the corresponding 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// WebRTCIdentityRequest. 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass WebRTCIdentityRequestHandle { 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch WebRTCIdentityRequestHandle( 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch WebRTCIdentityStore* store, 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const WebRTCIdentityStore::CompletionCallback& callback) 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : store_(store), request_(NULL), callback_(callback) {} 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch friend class WebRTCIdentityStore; 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Cancel the request. Does nothing if the request finished or was already 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // cancelled. 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void Cancel() { 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!request_) 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback_.Reset(); 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch WebRTCIdentityRequest* request = request_; 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request_ = NULL; 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // "this" will be deleted after the following call, because "this" is 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // owned by the Callback held by |request|. 148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch request->Cancel(this); 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void OnRequestStarted(WebRTCIdentityRequest* request) { 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(request); 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request_ = request; 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void OnRequestComplete(int error, 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& certificate, 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& private_key) { 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(request_); 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request_ = NULL; 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ResetAndReturn(&callback_).Run(error, certificate, private_key); 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch WebRTCIdentityStore* store_; 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch WebRTCIdentityRequest* request_; 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch WebRTCIdentityStore::CompletionCallback callback_; 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DISALLOW_COPY_AND_ASSIGN(WebRTCIdentityRequestHandle); 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 173ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochWebRTCIdentityStore::WebRTCIdentityStore(const base::FilePath& path, 17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::SpecialStoragePolicy* policy) 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : validity_period_(base::TimeDelta::FromDays(30)), 1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) task_runner_(base::WorkerPool::GetTaskRunner(true)), 1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) backend_(new WebRTCIdentityStoreBackend(path, policy, validity_period_)) { 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 180ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochWebRTCIdentityStore::~WebRTCIdentityStore() { backend_->Close(); } 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::Closure WebRTCIdentityStore::RequestIdentity( 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const GURL& origin, 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& identity_name, 185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& common_name, 186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const CompletionCallback& callback) { 187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 188ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch WebRTCIdentityRequest* request = 189ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FindRequest(origin, identity_name, common_name); 190ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If there is no identical request in flight, create a new one, queue it, 191ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // and make the backend request. 192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!request) { 193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch request = new WebRTCIdentityRequest(origin, identity_name, common_name); 194c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // |request| will delete itself after the result is posted. 195ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!backend_->FindIdentity( 196ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch origin, 197ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch identity_name, 198ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch common_name, 199ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Bind( 200ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch &WebRTCIdentityStore::BackendFindCallback, this, request))) { 201c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // Bail out if the backend failed to start the task. 202ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch delete request; 203ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return base::Closure(); 204ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 205ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch in_flight_requests_.push_back(request); 206ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 207ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 208c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch WebRTCIdentityRequestHandle* handle = 209c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch new WebRTCIdentityRequestHandle(this, callback); 210c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 211ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch request->AddCallback( 212ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch handle, 213ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Bind(&WebRTCIdentityRequestHandle::OnRequestComplete, 214ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Owned(handle))); 215ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch handle->OnRequestStarted(request); 216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return base::Bind(&WebRTCIdentityRequestHandle::Cancel, 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Unretained(handle)); 218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 220ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStore::DeleteBetween(base::Time delete_begin, 221ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Time delete_end, 222ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const base::Closure& callback) { 223ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 224ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch backend_->DeleteBetween(delete_begin, delete_end, callback); 225ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 226ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRTCIdentityStore::SetValidityPeriodForTesting( 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta validity_period) { 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) validity_period_ = validity_period; 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) backend_->SetValidityPeriodForTesting(validity_period); 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WebRTCIdentityStore::SetTaskRunnerForTesting( 235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const scoped_refptr<base::TaskRunner>& task_runner) { 236ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch task_runner_ = task_runner; 238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 240ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStore::BackendFindCallback(WebRTCIdentityRequest* request, 241ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int error, 242ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& certificate, 243ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& private_key) { 244ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 245ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (error == net::OK) { 246ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DVLOG(2) << "Identity found in DB."; 247ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch WebRTCIdentityRequestResult result(error, certificate, private_key); 248ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PostRequestResult(request, result); 249ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 250ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 251ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Generate a new identity if not found in the DB. 252ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch WebRTCIdentityRequestResult* result = 253ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch new WebRTCIdentityRequestResult(0, "", ""); 254ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!task_runner_->PostTaskAndReply( 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&GenerateIdentityWorker, 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) request->common_name_, 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) validity_period_, 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result), 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&WebRTCIdentityStore::GenerateIdentityCallback, 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this, 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) request, 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Owned(result)))) { 264ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Completes the request with error if failed to post the task. 265ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch WebRTCIdentityRequestResult result(net::ERR_UNEXPECTED, "", ""); 266ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PostRequestResult(request, result); 267ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 268ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 269ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 270ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStore::GenerateIdentityCallback( 271ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch WebRTCIdentityRequest* request, 272ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch WebRTCIdentityRequestResult* result) { 273ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 274ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (result->error == net::OK) { 275ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DVLOG(2) << "New identity generated and added to the backend."; 276ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch backend_->AddIdentity(request->origin_, 277ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch request->identity_name_, 278ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch request->common_name_, 279ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result->certificate, 280ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result->private_key); 281ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 282ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PostRequestResult(request, *result); 283ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 284ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 285ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStore::PostRequestResult( 286ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch WebRTCIdentityRequest* request, 287ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const WebRTCIdentityRequestResult& result) { 288ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 289ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Removes the in flight request from the queue. 290ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (size_t i = 0; i < in_flight_requests_.size(); ++i) { 291ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (in_flight_requests_[i] == request) { 292ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch in_flight_requests_.erase(in_flight_requests_.begin() + i); 293ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch break; 294ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 295ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 296ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // |request| will be deleted after this call. 297ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch request->Post(result); 298ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 299ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 300ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Find an identical request from the in flight requests. 301ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochWebRTCIdentityRequest* WebRTCIdentityStore::FindRequest( 302ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const GURL& origin, 303ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& identity_name, 304ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& common_name) { 305ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (size_t i = 0; i < in_flight_requests_.size(); ++i) { 306ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (in_flight_requests_[i]->origin_ == origin && 307ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch in_flight_requests_[i]->identity_name_ == identity_name && 308ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch in_flight_requests_[i]->common_name_ == common_name) { 309ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return in_flight_requests_[i]; 310ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 311ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 312ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return NULL; 313ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 314ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace content 316