webrtc_identity_store_backend.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
1ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// found in the LICENSE file. 4ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 5ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "content/browser/media/webrtc_identity_store_backend.h" 6ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 7ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/file_util.h" 8ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/files/file_path.h" 9ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "content/public/browser/browser_thread.h" 10ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "net/base/net_errors.h" 11ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "sql/error_delegate_util.h" 12ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "sql/statement.h" 13ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "sql/transaction.h" 14ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "url/gurl.h" 15ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "webkit/browser/quota/special_storage_policy.h" 16ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 17ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace content { 18ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 19ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstatic const char* kWebRTCIdentityStoreDBName = "webrtc_identity_store"; 20ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 21ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstatic const base::FilePath::CharType kWebRTCIdentityStoreDirectory[] = 22ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FILE_PATH_LITERAL("WebRTCIdentityStore"); 23ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 24ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Initializes the identity table, returning true on success. 25ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstatic bool InitDB(sql::Connection* db) { 26ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (db->DoesTableExist(kWebRTCIdentityStoreDBName)) { 27ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (db->DoesColumnExist(kWebRTCIdentityStoreDBName, "origin") && 28ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch db->DoesColumnExist(kWebRTCIdentityStoreDBName, "identity_name") && 29ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch db->DoesColumnExist(kWebRTCIdentityStoreDBName, "common_name") && 30ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch db->DoesColumnExist(kWebRTCIdentityStoreDBName, "certificate") && 31ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch db->DoesColumnExist(kWebRTCIdentityStoreDBName, "private_key") && 32ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch db->DoesColumnExist(kWebRTCIdentityStoreDBName, "creation_time")) 33ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 34ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!db->Execute("DROP TABLE webrtc_identity_store")) 35ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return false; 36ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 37ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 38ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return db->Execute( 39ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "CREATE TABLE webrtc_identity_store" 40ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch " (" 41ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "origin TEXT NOT NULL," 42ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "identity_name TEXT NOT NULL," 43ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "common_name TEXT NOT NULL," 44ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "certificate BLOB NOT NULL," 45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "private_key BLOB NOT NULL," 46ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "creation_time INTEGER)"); 47ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 48ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstruct WebRTCIdentityStoreBackend::IdentityKey { 50ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IdentityKey(const GURL& origin, const std::string& identity_name) 51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : origin(origin), identity_name(identity_name) {} 52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool operator<(const IdentityKey& other) const { 54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return origin < other.origin || 55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch (origin == other.origin && identity_name < other.identity_name); 56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GURL origin; 59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string identity_name; 60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 62ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstruct WebRTCIdentityStoreBackend::Identity { 63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Identity(const std::string& common_name, 64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& certificate, 65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& private_key) 66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : common_name(common_name), 67ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch certificate(certificate), 68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private_key(private_key), 69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch creation_time(base::Time::Now().ToInternalValue()) {} 70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Identity(const std::string& common_name, 72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& certificate, 73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& private_key, 74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int64 creation_time) 75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : common_name(common_name), 76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch certificate(certificate), 77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private_key(private_key), 78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch creation_time(creation_time) {} 79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string common_name; 81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string certificate; 82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string private_key; 83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int64 creation_time; 84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 86ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstruct WebRTCIdentityStoreBackend::PendingFindRequest { 87ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PendingFindRequest(const GURL& origin, 88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& identity_name, 89ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& common_name, 90ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const FindIdentityCallback& callback) 91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : origin(origin), 92ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch identity_name(identity_name), 93ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch common_name(common_name), 94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch callback(callback) {} 95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 96ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ~PendingFindRequest() {} 97ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 98ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GURL origin; 99ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string identity_name; 100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string common_name; 101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FindIdentityCallback callback; 102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// The class encapsulates the database operations. All members except ctor and 105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// dtor should be accessed on the DB thread. 106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// It can be created/destroyed on any thread. 107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass WebRTCIdentityStoreBackend::SqlLiteStorage 108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : public base::RefCountedThreadSafe<SqlLiteStorage> { 109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public: 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SqlLiteStorage(base::TimeDelta validity_period, 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::FilePath& path, 112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch quota::SpecialStoragePolicy* policy) 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : validity_period_(validity_period), special_storage_policy_(policy) { 114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!path.empty()) 115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch path_ = path.Append(kWebRTCIdentityStoreDirectory); 116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void Load(IdentityMap* out_map); 119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void Close(); 120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void AddIdentity(const GURL& origin, 121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& identity_name, 122ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const Identity& identity); 123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void DeleteIdentity(const GURL& origin, 124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& identity_name, 125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const Identity& identity); 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void DeleteBetween(base::Time delete_begin, base::Time delete_end); 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void SetValidityPeriodForTesting(base::TimeDelta validity_period) { 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!db_.get()); 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) validity_period_ = validity_period; 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private: 135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch friend class base::RefCountedThreadSafe<SqlLiteStorage>; 136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch enum OperationType { 138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ADD_IDENTITY, 139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DELETE_IDENTITY 140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch }; 141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch struct PendingOperation { 142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PendingOperation(OperationType type, 143ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const GURL& origin, 144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& identity_name, 145ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const Identity& identity) 146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : type(type), 147ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch origin(origin), 148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch identity_name(identity_name), 149ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch identity(identity) {} 150ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch OperationType type; 152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GURL origin; 153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string identity_name; 154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Identity identity; 155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch }; 156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch typedef std::vector<PendingOperation*> PendingOperationList; 157ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 158ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual ~SqlLiteStorage() {} 159ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void OnDatabaseError(int error, sql::Statement* stmt); 160ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void BatchOperation(OperationType type, 161ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const GURL& origin, 162ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& identity_name, 163ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const Identity& identity); 164ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void Commit(); 165ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta validity_period_; 167ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // The file path of the DB. Empty if temporary. 168ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::FilePath path_; 169ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_; 170ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_ptr<sql::Connection> db_; 171ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Batched DB operations pending to commit. 172ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PendingOperationList pending_operations_; 173ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 174ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DISALLOW_COPY_AND_ASSIGN(SqlLiteStorage); 175ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 176ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 177ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochWebRTCIdentityStoreBackend::WebRTCIdentityStoreBackend( 178ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const base::FilePath& path, 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) quota::SpecialStoragePolicy* policy, 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta validity_period) 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : validity_period_(validity_period), 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) state_(NOT_STARTED), 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sql_lite_storage_(new SqlLiteStorage(validity_period, path, policy)) {} 184ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 185ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool WebRTCIdentityStoreBackend::FindIdentity( 186ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const GURL& origin, 187ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& identity_name, 188ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& common_name, 189ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const FindIdentityCallback& callback) { 190ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 191ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (state_ == CLOSED) 192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return false; 193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 194ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (state_ != LOADED) { 195ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Queues the request to wait for the DB to load. 196ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pending_find_requests_.push_back( 197ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch new PendingFindRequest(origin, identity_name, common_name, callback)); 198ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (state_ == LOADING) 199ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 200ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 201ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK_EQ(state_, NOT_STARTED); 202ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 203ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Kick off loading the DB. 204ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_ptr<IdentityMap> out_map(new IdentityMap()); 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Closure task( 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&SqlLiteStorage::Load, sql_lite_storage_, out_map.get())); 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |out_map| will be NULL after this call. 208ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (BrowserThread::PostTaskAndReply( 209ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch BrowserThread::DB, 210ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FROM_HERE, 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) task, 212ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Bind(&WebRTCIdentityStoreBackend::OnLoaded, 213ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch this, 214ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Passed(&out_map)))) { 215ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch state_ = LOADING; 216ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 217ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 218ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If it fails to post task, falls back to ERR_FILE_NOT_FOUND. 219ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 220ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 221ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IdentityKey key(origin, identity_name); 222ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IdentityMap::iterator iter = identities_.find(key); 223ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (iter != identities_.end() && iter->second.common_name == common_name) { 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta age = base::Time::Now() - base::Time::FromInternalValue( 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) iter->second.creation_time); 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (age < validity_period_) { 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Identity found. 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return BrowserThread::PostTask(BrowserThread::IO, 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(callback, 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) net::OK, 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) iter->second.certificate, 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) iter->second.private_key)); 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Removes the expired identity from the in-memory cache. The copy in the 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // database will be removed on the next load. 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) identities_.erase(iter); 238ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 239ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 240ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return BrowserThread::PostTask( 241ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch BrowserThread::IO, 242ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FROM_HERE, 243ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Bind(callback, net::ERR_FILE_NOT_FOUND, "", "")); 244ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 245ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 246ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStoreBackend::AddIdentity(const GURL& origin, 247ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& identity_name, 248ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& common_name, 249ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& certificate, 250ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& private_key) { 251ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 252ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (state_ == CLOSED) 253ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 254ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 255ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If there is an existing identity for the same origin and identity_name, 256ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // delete it. 257ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IdentityKey key(origin, identity_name); 258ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Identity identity(common_name, certificate, private_key); 259ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 260ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (identities_.find(key) != identities_.end()) { 261ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!BrowserThread::PostTask(BrowserThread::DB, 262ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FROM_HERE, 263ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Bind(&SqlLiteStorage::DeleteIdentity, 264ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch sql_lite_storage_, 265ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch origin, 266ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch identity_name, 267ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch identities_.find(key)->second))) 268ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 269ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 270ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch identities_.insert(std::pair<IdentityKey, Identity>(key, identity)); 271ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 272ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch BrowserThread::PostTask(BrowserThread::DB, 273ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FROM_HERE, 274ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Bind(&SqlLiteStorage::AddIdentity, 275ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch sql_lite_storage_, 276ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch origin, 277ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch identity_name, 278ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch identity)); 279ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 280ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 281ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStoreBackend::Close() { 282ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 283ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch BrowserThread::PostTask( 284ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch BrowserThread::IO, 285ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FROM_HERE, 286ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Bind(&WebRTCIdentityStoreBackend::Close, this)); 287ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 288ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 289ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 290ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (state_ == CLOSED) 291ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 292ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 293ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch state_ = CLOSED; 294ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch BrowserThread::PostTask( 295ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch BrowserThread::DB, 296ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FROM_HERE, 297ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Bind(&SqlLiteStorage::Close, sql_lite_storage_)); 298ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 299ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 300ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStoreBackend::DeleteBetween(base::Time delete_begin, 301ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Time delete_end, 302ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const base::Closure& callback) { 303ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (state_ == CLOSED) 3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 307ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Delete the in-memory cache. 308ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IdentityMap::iterator it = identities_.begin(); 309ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch while (it != identities_.end()) { 310ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (it->second.creation_time >= delete_begin.ToInternalValue() && 3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it->second.creation_time <= delete_end.ToInternalValue()) { 312ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch identities_.erase(it++); 3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ++it; 3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 316ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 317ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch BrowserThread::PostTaskAndReply(BrowserThread::DB, 318ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FROM_HERE, 319ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Bind(&SqlLiteStorage::DeleteBetween, 320ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch sql_lite_storage_, 321ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch delete_begin, 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) delete_end), 323ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch callback); 324ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 325ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRTCIdentityStoreBackend::SetValidityPeriodForTesting( 3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TimeDelta validity_period) { 3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) validity_period_ = validity_period; 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrowserThread::PostTask( 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BrowserThread::DB, 3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, 3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&SqlLiteStorage::SetValidityPeriodForTesting, 3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sql_lite_storage_, 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) validity_period)); 3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 338ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochWebRTCIdentityStoreBackend::~WebRTCIdentityStoreBackend() {} 339ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 340ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStoreBackend::OnLoaded(scoped_ptr<IdentityMap> out_map) { 341ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (state_ != LOADING) 3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DVLOG(2) << "WebRTC identity store has loaded."; 3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 348ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch state_ = LOADED; 349ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch identities_.swap(*out_map); 350ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 351ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (size_t i = 0; i < pending_find_requests_.size(); ++i) { 352ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FindIdentity(pending_find_requests_[i]->origin, 353ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pending_find_requests_[i]->identity_name, 354ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pending_find_requests_[i]->common_name, 355ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pending_find_requests_[i]->callback); 356ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch delete pending_find_requests_[i]; 357ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 358ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pending_find_requests_.clear(); 359ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 360ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 361ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// 362ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Implementation of SqlLiteStorage. 363ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// 364ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 365ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStoreBackend::SqlLiteStorage::Load(IdentityMap* out_map) { 366ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 367ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(!db_.get()); 368ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 369ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Ensure the parent directory for storing certs is created before reading 370ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // from it. 371ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const base::FilePath dir = path_.DirName(); 372ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!base::PathExists(dir) && !file_util::CreateDirectory(dir)) { 373ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DLOG(ERROR) << "Unable to open DB file path."; 374ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 375ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 376ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 377ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch db_.reset(new sql::Connection()); 378ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 379ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch db_->set_error_callback(base::Bind(&SqlLiteStorage::OnDatabaseError, this)); 380ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 381ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!db_->Open(path_)) { 382ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DLOG(ERROR) << "Unable to open DB."; 383ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch db_.reset(); 384ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 385ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 386ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 387ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!InitDB(db_.get())) { 388ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DLOG(ERROR) << "Unable to init DB."; 389ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch db_.reset(); 390ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 391ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 392ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 393ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch db_->Preload(); 394ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 3954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Delete expired identities. 3964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DeleteBetween(base::Time(), base::Time::Now() - validity_period_); 3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 398ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Slurp all the identities into the out_map. 399ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch sql::Statement stmt(db_->GetUniqueStatement( 400ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "SELECT origin, identity_name, common_name, " 401ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "certificate, private_key, creation_time " 402ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "FROM webrtc_identity_store")); 403ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CHECK(stmt.is_valid()); 404ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 405ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch while (stmt.Step()) { 406ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IdentityKey key(GURL(stmt.ColumnString(0)), stmt.ColumnString(1)); 407ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string common_name(stmt.ColumnString(2)); 408ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::string cert, private_key; 409ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch stmt.ColumnBlobAsString(3, &cert); 410ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch stmt.ColumnBlobAsString(4, &private_key); 411ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int64 creation_time = stmt.ColumnInt64(5); 412ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch std::pair<IdentityMap::iterator, bool> result = 413ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch out_map->insert(std::pair<IdentityKey, Identity>( 414ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch key, Identity(common_name, cert, private_key, creation_time))); 415ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(result.second); 416ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 417ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 418ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 419ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStoreBackend::SqlLiteStorage::Close() { 420ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 421ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Commit(); 422ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch db_.reset(); 423ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 424ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 425ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStoreBackend::SqlLiteStorage::AddIdentity( 426ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const GURL& origin, 427ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& identity_name, 428ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const Identity& identity) { 429ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 430ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!db_.get()) 431ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 432ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 433ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Do not add for session only origins. 434ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (special_storage_policy_.get() && 435ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch !special_storage_policy_->IsStorageProtected(origin) && 436ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch special_storage_policy_->IsStorageSessionOnly(origin)) { 437ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 438ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 439ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch BatchOperation(ADD_IDENTITY, origin, identity_name, identity); 440ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 441ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 442ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStoreBackend::SqlLiteStorage::DeleteIdentity( 443ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const GURL& origin, 444ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& identity_name, 445ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const Identity& identity) { 446ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 447ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!db_.get()) 448ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 449ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch BatchOperation(DELETE_IDENTITY, origin, identity_name, identity); 450ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 451ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 4524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebRTCIdentityStoreBackend::SqlLiteStorage::DeleteBetween( 4534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Time delete_begin, 4544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Time delete_end) { 4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 4564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!db_.get()) 4574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 4584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Commit pending operations first. 4604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Commit(); 4614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sql::Statement del_stmt(db_->GetCachedStatement( 4634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SQL_FROM_HERE, 4644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "DELETE FROM webrtc_identity_store" 4654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) " WHERE creation_time >= ? AND creation_time <= ?")); 4664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CHECK(del_stmt.is_valid()); 4674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) del_stmt.BindInt64(0, delete_begin.ToInternalValue()); 4694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) del_stmt.BindInt64(1, delete_end.ToInternalValue()); 4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sql::Transaction transaction(db_.get()); 4724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!transaction.Begin()) { 4734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DLOG(ERROR) << "Failed to begin the transaction."; 4744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 4754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CHECK(del_stmt.Run()); 4784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) transaction.Commit(); 4794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 4804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 481ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStoreBackend::SqlLiteStorage::OnDatabaseError( 482ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int error, 483ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch sql::Statement* stmt) { 484ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 485ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!sql::IsErrorCatastrophic(error)) 486ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 487ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch db_->RazeAndClose(); 488ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 489ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 490ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStoreBackend::SqlLiteStorage::BatchOperation( 491ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch OperationType type, 492ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const GURL& origin, 493ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& identity_name, 494ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const Identity& identity) { 495ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 496ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Commit every 30 seconds. 497ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch static const base::TimeDelta kCommitInterval( 498ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::TimeDelta::FromSeconds(30)); 499ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Commit right away if we have more than 512 outstanding operations. 500ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch static const size_t kCommitAfterBatchSize = 512; 501ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 502ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // We do a full copy of the cert here, and hopefully just here. 503ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_ptr<PendingOperation> operation( 504ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch new PendingOperation(type, origin, identity_name, identity)); 505ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 506ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pending_operations_.push_back(operation.release()); 507ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 508ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (pending_operations_.size() == 1) { 509ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // We've gotten our first entry for this batch, fire off the timer. 510ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch BrowserThread::PostDelayedTask(BrowserThread::DB, 511ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FROM_HERE, 512ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Bind(&SqlLiteStorage::Commit, this), 513ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch kCommitInterval); 514ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else if (pending_operations_.size() >= kCommitAfterBatchSize) { 515ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // We've reached a big enough batch, fire off a commit now. 516ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch BrowserThread::PostTask(BrowserThread::DB, 517ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FROM_HERE, 518ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Bind(&SqlLiteStorage::Commit, this)); 519ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 520ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 521ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 522ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid WebRTCIdentityStoreBackend::SqlLiteStorage::Commit() { 523ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 524ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Maybe an old timer fired or we are already Close()'ed. 525ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!db_.get() || pending_operations_.empty()) 526ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 527ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 528ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch sql::Statement add_stmt(db_->GetCachedStatement( 529ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch SQL_FROM_HERE, 530ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "INSERT INTO webrtc_identity_store " 531ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "(origin, identity_name, common_name, certificate," 532ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch " private_key, creation_time) VALUES" 533ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch " (?,?,?,?,?,?)")); 534ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 535ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CHECK(add_stmt.is_valid()); 536ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 537ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch sql::Statement del_stmt(db_->GetCachedStatement( 538ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch SQL_FROM_HERE, 539ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "DELETE FROM webrtc_identity_store WHERE origin=? AND identity_name=?")); 540ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 541ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CHECK(del_stmt.is_valid()); 542ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 543ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch sql::Transaction transaction(db_.get()); 544ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!transaction.Begin()) { 545ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DLOG(ERROR) << "Failed to begin the transaction."; 546ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 547ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 548ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 549ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (PendingOperationList::iterator it = pending_operations_.begin(); 550ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch it != pending_operations_.end(); 551ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ++it) { 552ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_ptr<PendingOperation> po(*it); 553ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch switch (po->type) { 554ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ADD_IDENTITY: { 555ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch add_stmt.Reset(true); 556ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch add_stmt.BindString(0, po->origin.spec()); 557ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch add_stmt.BindString(1, po->identity_name); 558ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch add_stmt.BindString(2, po->identity.common_name); 559ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& cert = po->identity.certificate; 560ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch add_stmt.BindBlob(3, cert.data(), cert.size()); 561ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const std::string& private_key = po->identity.private_key; 562ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch add_stmt.BindBlob(4, private_key.data(), private_key.size()); 563ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch add_stmt.BindInt64(5, po->identity.creation_time); 564ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CHECK(add_stmt.Run()); 565ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch break; 566ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 567ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case DELETE_IDENTITY: 568ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch del_stmt.Reset(true); 569ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch del_stmt.BindString(0, po->origin.spec()); 570ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch add_stmt.BindString(1, po->identity_name); 571ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CHECK(del_stmt.Run()); 572ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch break; 573ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 574ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch default: 575ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch NOTREACHED(); 576ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch break; 577ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 578ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 579ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch transaction.Commit(); 580ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pending_operations_.clear(); 581ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 582ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 583ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace content 584