| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/net/sqlite_origin_bound_cert_store.h" | 5 #include "chrome/browser/net/sqlite_origin_bound_cert_store.h" |
| 6 | 6 |
| 7 #include <list> | 7 #include <list> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/file_path.h" | 11 #include "base/file_path.h" |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
| 16 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
| 17 #include "base/threading/thread_restrictions.h" | 17 #include "base/threading/thread_restrictions.h" |
| 18 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" | 18 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" |
| 19 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 20 #include "net/base/ssl_client_cert_type.h" | 20 #include "net/base/ssl_client_cert_type.h" |
| 21 #include "net/base/x509_certificate.h" | 21 #include "net/base/x509_certificate.h" |
| 22 #include "sql/meta_table.h" | 22 #include "sql/meta_table.h" |
| 23 #include "sql/statement.h" | 23 #include "sql/statement.h" |
| 24 #include "sql/transaction.h" | 24 #include "sql/transaction.h" |
| 25 | 25 |
| 26 using content::BrowserThread; | 26 using content::BrowserThread; |
| 27 | 27 |
| 28 // This class is designed to be shared between any calling threads and the | 28 // This class is designed to be shared between any calling threads and the |
| 29 // database thread. It batches operations and commits them on a timer. | 29 // database thread. It batches operations and commits them on a timer. |
| 30 class SQLiteOriginBoundCertStore::Backend | 30 class SQLiteServerBoundCertStore::Backend |
| 31 : public base::RefCountedThreadSafe<SQLiteOriginBoundCertStore::Backend> { | 31 : public base::RefCountedThreadSafe<SQLiteServerBoundCertStore::Backend> { |
| 32 public: | 32 public: |
| 33 explicit Backend(const FilePath& path) | 33 explicit Backend(const FilePath& path) |
| 34 : path_(path), | 34 : path_(path), |
| 35 db_(NULL), | 35 db_(NULL), |
| 36 num_pending_(0), | 36 num_pending_(0), |
| 37 clear_local_state_on_exit_(false) { | 37 clear_local_state_on_exit_(false) { |
| 38 } | 38 } |
| 39 | 39 |
| 40 // Creates or load the SQLite database. | 40 // Creates or load the SQLite database. |
| 41 bool Load( | 41 bool Load( |
| 42 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*>* certs); | 42 std::vector<net::DefaultServerBoundCertStore::ServerBoundCert*>* certs); |
| 43 | 43 |
| 44 // Batch an origin bound cert addition. | 44 // Batch a server bound cert addition. |
| 45 void AddOriginBoundCert( | 45 void AddServerBoundCert( |
| 46 const net::DefaultOriginBoundCertStore::OriginBoundCert& cert); | 46 const net::DefaultServerBoundCertStore::ServerBoundCert& cert); |
| 47 | 47 |
| 48 // Batch an origin bound cert deletion. | 48 // Batch a server bound cert deletion. |
| 49 void DeleteOriginBoundCert( | 49 void DeleteServerBoundCert( |
| 50 const net::DefaultOriginBoundCertStore::OriginBoundCert& cert); | 50 const net::DefaultServerBoundCertStore::ServerBoundCert& cert); |
| 51 | 51 |
| 52 // Commit pending operations as soon as possible. | 52 // Commit pending operations as soon as possible. |
| 53 void Flush(const base::Closure& completion_task); | 53 void Flush(const base::Closure& completion_task); |
| 54 | 54 |
| 55 // Commit any pending operations and close the database. This must be called | 55 // Commit any pending operations and close the database. This must be called |
| 56 // before the object is destructed. | 56 // before the object is destructed. |
| 57 void Close(); | 57 void Close(); |
| 58 | 58 |
| 59 void SetClearLocalStateOnExit(bool clear_local_state); | 59 void SetClearLocalStateOnExit(bool clear_local_state); |
| 60 | 60 |
| 61 private: | 61 private: |
| 62 friend class base::RefCountedThreadSafe<SQLiteOriginBoundCertStore::Backend>; | 62 friend class base::RefCountedThreadSafe<SQLiteServerBoundCertStore::Backend>; |
| 63 | 63 |
| 64 // You should call Close() before destructing this object. | 64 // You should call Close() before destructing this object. |
| 65 ~Backend() { | 65 ~Backend() { |
| 66 DCHECK(!db_.get()) << "Close should have already been called."; | 66 DCHECK(!db_.get()) << "Close should have already been called."; |
| 67 DCHECK(num_pending_ == 0 && pending_.empty()); | 67 DCHECK(num_pending_ == 0 && pending_.empty()); |
| 68 } | 68 } |
| 69 | 69 |
| 70 // Database upgrade statements. | 70 // Database upgrade statements. |
| 71 bool EnsureDatabaseVersion(); | 71 bool EnsureDatabaseVersion(); |
| 72 | 72 |
| 73 class PendingOperation { | 73 class PendingOperation { |
| 74 public: | 74 public: |
| 75 typedef enum { | 75 typedef enum { |
| 76 CERT_ADD, | 76 CERT_ADD, |
| 77 CERT_DELETE | 77 CERT_DELETE |
| 78 } OperationType; | 78 } OperationType; |
| 79 | 79 |
| 80 PendingOperation( | 80 PendingOperation( |
| 81 OperationType op, | 81 OperationType op, |
| 82 const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) | 82 const net::DefaultServerBoundCertStore::ServerBoundCert& cert) |
| 83 : op_(op), cert_(cert) {} | 83 : op_(op), cert_(cert) {} |
| 84 | 84 |
| 85 OperationType op() const { return op_; } | 85 OperationType op() const { return op_; } |
| 86 const net::DefaultOriginBoundCertStore::OriginBoundCert& cert() const { | 86 const net::DefaultServerBoundCertStore::ServerBoundCert& cert() const { |
| 87 return cert_; | 87 return cert_; |
| 88 } | 88 } |
| 89 | 89 |
| 90 private: | 90 private: |
| 91 OperationType op_; | 91 OperationType op_; |
| 92 net::DefaultOriginBoundCertStore::OriginBoundCert cert_; | 92 net::DefaultServerBoundCertStore::ServerBoundCert cert_; |
| 93 }; | 93 }; |
| 94 | 94 |
| 95 private: | 95 private: |
| 96 // Batch an origin bound cert operation (add or delete) | 96 // Batch a server bound cert operation (add or delete) |
| 97 void BatchOperation( | 97 void BatchOperation( |
| 98 PendingOperation::OperationType op, | 98 PendingOperation::OperationType op, |
| 99 const net::DefaultOriginBoundCertStore::OriginBoundCert& cert); | 99 const net::DefaultServerBoundCertStore::ServerBoundCert& cert); |
| 100 // Commit our pending operations to the database. | 100 // Commit our pending operations to the database. |
| 101 void Commit(); | 101 void Commit(); |
| 102 // Close() executed on the background thread. | 102 // Close() executed on the background thread. |
| 103 void InternalBackgroundClose(); | 103 void InternalBackgroundClose(); |
| 104 | 104 |
| 105 FilePath path_; | 105 FilePath path_; |
| 106 scoped_ptr<sql::Connection> db_; | 106 scoped_ptr<sql::Connection> db_; |
| 107 sql::MetaTable meta_table_; | 107 sql::MetaTable meta_table_; |
| 108 | 108 |
| 109 typedef std::list<PendingOperation*> PendingOperationsList; | 109 typedef std::list<PendingOperation*> PendingOperationsList; |
| 110 PendingOperationsList pending_; | 110 PendingOperationsList pending_; |
| 111 PendingOperationsList::size_type num_pending_; | 111 PendingOperationsList::size_type num_pending_; |
| 112 // True if the persistent store should be deleted upon destruction. | 112 // True if the persistent store should be deleted upon destruction. |
| 113 bool clear_local_state_on_exit_; | 113 bool clear_local_state_on_exit_; |
| 114 // Guard |pending_|, |num_pending_| and |clear_local_state_on_exit_|. | 114 // Guard |pending_|, |num_pending_| and |clear_local_state_on_exit_|. |
| 115 base::Lock lock_; | 115 base::Lock lock_; |
| 116 | 116 |
| 117 DISALLOW_COPY_AND_ASSIGN(Backend); | 117 DISALLOW_COPY_AND_ASSIGN(Backend); |
| 118 }; | 118 }; |
| 119 | 119 |
| 120 // Version number of the database. | 120 // Version number of the database. |
| 121 static const int kCurrentVersionNumber = 4; | 121 static const int kCurrentVersionNumber = 4; |
| 122 static const int kCompatibleVersionNumber = 1; | 122 static const int kCompatibleVersionNumber = 1; |
| 123 | 123 |
| 124 namespace { | 124 namespace { |
| 125 | 125 |
| 126 // Initializes the certs table, returning true on success. | 126 // Initializes the certs table, returning true on success. |
| 127 bool InitTable(sql::Connection* db) { | 127 bool InitTable(sql::Connection* db) { |
| 128 // The table is named "origin_bound_certs" for backwards compatability before |
| 129 // we renamed this class to SQLiteServerBoundCertStore. Likewise, the primary |
| 130 // key is "origin", but now can be other things like a plain domain. |
| 128 if (!db->DoesTableExist("origin_bound_certs")) { | 131 if (!db->DoesTableExist("origin_bound_certs")) { |
| 129 if (!db->Execute("CREATE TABLE origin_bound_certs (" | 132 if (!db->Execute("CREATE TABLE origin_bound_certs (" |
| 130 "origin TEXT NOT NULL UNIQUE PRIMARY KEY," | 133 "origin TEXT NOT NULL UNIQUE PRIMARY KEY," |
| 131 "private_key BLOB NOT NULL," | 134 "private_key BLOB NOT NULL," |
| 132 "cert BLOB NOT NULL," | 135 "cert BLOB NOT NULL," |
| 133 "cert_type INTEGER," | 136 "cert_type INTEGER," |
| 134 "expiration_time INTEGER," | 137 "expiration_time INTEGER," |
| 135 "creation_time INTEGER)")) | 138 "creation_time INTEGER)")) |
| 136 return false; | 139 return false; |
| 137 } | 140 } |
| 138 | 141 |
| 139 return true; | 142 return true; |
| 140 } | 143 } |
| 141 | 144 |
| 142 } // namespace | 145 } // namespace |
| 143 | 146 |
| 144 bool SQLiteOriginBoundCertStore::Backend::Load( | 147 bool SQLiteServerBoundCertStore::Backend::Load( |
| 145 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*>* certs) { | 148 std::vector<net::DefaultServerBoundCertStore::ServerBoundCert*>* certs) { |
| 146 // This function should be called only once per instance. | 149 // This function should be called only once per instance. |
| 147 DCHECK(!db_.get()); | 150 DCHECK(!db_.get()); |
| 148 | 151 |
| 149 // Ensure the parent directory for storing certs is created before reading | 152 // Ensure the parent directory for storing certs is created before reading |
| 150 // from it. We make an exception to allow IO on the UI thread here because | 153 // from it. We make an exception to allow IO on the UI thread here because |
| 151 // we are going to disk anyway in db_->Open. (This code will be moved to the | 154 // we are going to disk anyway in db_->Open. (This code will be moved to the |
| 152 // DB thread as part of http://crbug.com/52909.) | 155 // DB thread as part of http://crbug.com/52909.) |
| 153 { | 156 { |
| 154 base::ThreadRestrictions::ScopedAllowIO allow_io; | 157 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 155 const FilePath dir = path_.DirName(); | 158 const FilePath dir = path_.DirName(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 178 "creation_time FROM origin_bound_certs")); | 181 "creation_time FROM origin_bound_certs")); |
| 179 if (!smt.is_valid()) { | 182 if (!smt.is_valid()) { |
| 180 db_.reset(); | 183 db_.reset(); |
| 181 return false; | 184 return false; |
| 182 } | 185 } |
| 183 | 186 |
| 184 while (smt.Step()) { | 187 while (smt.Step()) { |
| 185 std::string private_key_from_db, cert_from_db; | 188 std::string private_key_from_db, cert_from_db; |
| 186 smt.ColumnBlobAsString(1, &private_key_from_db); | 189 smt.ColumnBlobAsString(1, &private_key_from_db); |
| 187 smt.ColumnBlobAsString(2, &cert_from_db); | 190 smt.ColumnBlobAsString(2, &cert_from_db); |
| 188 scoped_ptr<net::DefaultOriginBoundCertStore::OriginBoundCert> cert( | 191 scoped_ptr<net::DefaultServerBoundCertStore::ServerBoundCert> cert( |
| 189 new net::DefaultOriginBoundCertStore::OriginBoundCert( | 192 new net::DefaultServerBoundCertStore::ServerBoundCert( |
| 190 smt.ColumnString(0), // origin | 193 smt.ColumnString(0), // origin |
| 191 static_cast<net::SSLClientCertType>(smt.ColumnInt(3)), | 194 static_cast<net::SSLClientCertType>(smt.ColumnInt(3)), |
| 192 base::Time::FromInternalValue(smt.ColumnInt64(5)), | 195 base::Time::FromInternalValue(smt.ColumnInt64(5)), |
| 193 base::Time::FromInternalValue(smt.ColumnInt64(4)), | 196 base::Time::FromInternalValue(smt.ColumnInt64(4)), |
| 194 private_key_from_db, | 197 private_key_from_db, |
| 195 cert_from_db)); | 198 cert_from_db)); |
| 196 certs->push_back(cert.release()); | 199 certs->push_back(cert.release()); |
| 197 } | 200 } |
| 198 | 201 |
| 199 return true; | 202 return true; |
| 200 } | 203 } |
| 201 | 204 |
| 202 bool SQLiteOriginBoundCertStore::Backend::EnsureDatabaseVersion() { | 205 bool SQLiteServerBoundCertStore::Backend::EnsureDatabaseVersion() { |
| 203 // Version check. | 206 // Version check. |
| 204 if (!meta_table_.Init( | 207 if (!meta_table_.Init( |
| 205 db_.get(), kCurrentVersionNumber, kCompatibleVersionNumber)) { | 208 db_.get(), kCurrentVersionNumber, kCompatibleVersionNumber)) { |
| 206 return false; | 209 return false; |
| 207 } | 210 } |
| 208 | 211 |
| 209 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { | 212 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { |
| 210 LOG(WARNING) << "Origin bound cert database is too new."; | 213 LOG(WARNING) << "Server bound cert database is too new."; |
| 211 return false; | 214 return false; |
| 212 } | 215 } |
| 213 | 216 |
| 214 int cur_version = meta_table_.GetVersionNumber(); | 217 int cur_version = meta_table_.GetVersionNumber(); |
| 215 if (cur_version == 1) { | 218 if (cur_version == 1) { |
| 216 sql::Transaction transaction(db_.get()); | 219 sql::Transaction transaction(db_.get()); |
| 217 if (!transaction.Begin()) | 220 if (!transaction.Begin()) |
| 218 return false; | 221 return false; |
| 219 if (!db_->Execute("ALTER TABLE origin_bound_certs ADD COLUMN cert_type " | 222 if (!db_->Execute("ALTER TABLE origin_bound_certs ADD COLUMN cert_type " |
| 220 "INTEGER")) { | 223 "INTEGER")) { |
| 221 LOG(WARNING) << "Unable to update origin bound cert database to " | 224 LOG(WARNING) << "Unable to update server bound cert database to " |
| 222 << "version 2."; | 225 << "version 2."; |
| 223 return false; | 226 return false; |
| 224 } | 227 } |
| 225 // All certs in version 1 database are rsa_sign, which has a value of 1. | 228 // All certs in version 1 database are rsa_sign, which has a value of 1. |
| 226 if (!db_->Execute("UPDATE origin_bound_certs SET cert_type = 1")) { | 229 if (!db_->Execute("UPDATE origin_bound_certs SET cert_type = 1")) { |
| 227 LOG(WARNING) << "Unable to update origin bound cert database to " | 230 LOG(WARNING) << "Unable to update server bound cert database to " |
| 228 << "version 2."; | 231 << "version 2."; |
| 229 return false; | 232 return false; |
| 230 } | 233 } |
| 231 ++cur_version; | 234 ++cur_version; |
| 232 meta_table_.SetVersionNumber(cur_version); | 235 meta_table_.SetVersionNumber(cur_version); |
| 233 meta_table_.SetCompatibleVersionNumber( | 236 meta_table_.SetCompatibleVersionNumber( |
| 234 std::min(cur_version, kCompatibleVersionNumber)); | 237 std::min(cur_version, kCompatibleVersionNumber)); |
| 235 transaction.Commit(); | 238 transaction.Commit(); |
| 236 } | 239 } |
| 237 | 240 |
| 238 if (cur_version <= 3) { | 241 if (cur_version <= 3) { |
| 239 sql::Transaction transaction(db_.get()); | 242 sql::Transaction transaction(db_.get()); |
| 240 if (!transaction.Begin()) | 243 if (!transaction.Begin()) |
| 241 return false; | 244 return false; |
| 242 | 245 |
| 243 if (cur_version == 2) { | 246 if (cur_version == 2) { |
| 244 if (!db_->Execute("ALTER TABLE origin_bound_certs ADD COLUMN " | 247 if (!db_->Execute("ALTER TABLE origin_bound_certs ADD COLUMN " |
| 245 "expiration_time INTEGER")) { | 248 "expiration_time INTEGER")) { |
| 246 LOG(WARNING) << "Unable to update origin bound cert database to " | 249 LOG(WARNING) << "Unable to update server bound cert database to " |
| 247 << "version 4."; | 250 << "version 4."; |
| 248 return false; | 251 return false; |
| 249 } | 252 } |
| 250 } | 253 } |
| 251 | 254 |
| 252 if (!db_->Execute("ALTER TABLE origin_bound_certs ADD COLUMN " | 255 if (!db_->Execute("ALTER TABLE origin_bound_certs ADD COLUMN " |
| 253 "creation_time INTEGER")) { | 256 "creation_time INTEGER")) { |
| 254 LOG(WARNING) << "Unable to update origin bound cert database to " | 257 LOG(WARNING) << "Unable to update server bound cert database to " |
| 255 << "version 4."; | 258 << "version 4."; |
| 256 return false; | 259 return false; |
| 257 } | 260 } |
| 258 | 261 |
| 259 sql::Statement smt(db_->GetUniqueStatement( | 262 sql::Statement smt(db_->GetUniqueStatement( |
| 260 "SELECT origin, cert FROM origin_bound_certs")); | 263 "SELECT origin, cert FROM origin_bound_certs")); |
| 261 sql::Statement update_expires_smt(db_->GetUniqueStatement( | 264 sql::Statement update_expires_smt(db_->GetUniqueStatement( |
| 262 "UPDATE origin_bound_certs SET expiration_time = ? WHERE origin = ?")); | 265 "UPDATE origin_bound_certs SET expiration_time = ? WHERE origin = ?")); |
| 263 sql::Statement update_creation_smt(db_->GetUniqueStatement( | 266 sql::Statement update_creation_smt(db_->GetUniqueStatement( |
| 264 "UPDATE origin_bound_certs SET creation_time = ? WHERE origin = ?")); | 267 "UPDATE origin_bound_certs SET creation_time = ? WHERE origin = ?")); |
| 265 if (!smt.is_valid() || | 268 if (!smt.is_valid() || |
| 266 !update_expires_smt.is_valid() || | 269 !update_expires_smt.is_valid() || |
| 267 !update_creation_smt.is_valid()) { | 270 !update_creation_smt.is_valid()) { |
| 268 LOG(WARNING) << "Unable to update origin bound cert database to " | 271 LOG(WARNING) << "Unable to update server bound cert database to " |
| 269 << "version 4."; | 272 << "version 4."; |
| 270 return false; | 273 return false; |
| 271 } | 274 } |
| 272 | 275 |
| 273 while (smt.Step()) { | 276 while (smt.Step()) { |
| 274 std::string origin = smt.ColumnString(0); | 277 std::string origin = smt.ColumnString(0); |
| 275 std::string cert_from_db; | 278 std::string cert_from_db; |
| 276 smt.ColumnBlobAsString(1, &cert_from_db); | 279 smt.ColumnBlobAsString(1, &cert_from_db); |
| 277 // Parse the cert and extract the real value and then update the DB. | 280 // Parse the cert and extract the real value and then update the DB. |
| 278 scoped_refptr<net::X509Certificate> cert( | 281 scoped_refptr<net::X509Certificate> cert( |
| 279 net::X509Certificate::CreateFromBytes( | 282 net::X509Certificate::CreateFromBytes( |
| 280 cert_from_db.data(), cert_from_db.size())); | 283 cert_from_db.data(), cert_from_db.size())); |
| 281 if (cert) { | 284 if (cert) { |
| 282 if (cur_version == 2) { | 285 if (cur_version == 2) { |
| 283 update_expires_smt.Reset(); | 286 update_expires_smt.Reset(); |
| 284 update_expires_smt.BindInt64(0, | 287 update_expires_smt.BindInt64(0, |
| 285 cert->valid_expiry().ToInternalValue()); | 288 cert->valid_expiry().ToInternalValue()); |
| 286 update_expires_smt.BindString(1, origin); | 289 update_expires_smt.BindString(1, origin); |
| 287 if (!update_expires_smt.Run()) { | 290 if (!update_expires_smt.Run()) { |
| 288 LOG(WARNING) << "Unable to update origin bound cert database to " | 291 LOG(WARNING) << "Unable to update server bound cert database to " |
| 289 << "version 4."; | 292 << "version 4."; |
| 290 return false; | 293 return false; |
| 291 } | 294 } |
| 292 } | 295 } |
| 293 | 296 |
| 294 update_creation_smt.Reset(); | 297 update_creation_smt.Reset(); |
| 295 update_creation_smt.BindInt64(0, cert->valid_start().ToInternalValue()); | 298 update_creation_smt.BindInt64(0, cert->valid_start().ToInternalValue()); |
| 296 update_creation_smt.BindString(1, origin); | 299 update_creation_smt.BindString(1, origin); |
| 297 if (!update_creation_smt.Run()) { | 300 if (!update_creation_smt.Run()) { |
| 298 LOG(WARNING) << "Unable to update origin bound cert database to " | 301 LOG(WARNING) << "Unable to update server bound cert database to " |
| 299 << "version 4."; | 302 << "version 4."; |
| 300 return false; | 303 return false; |
| 301 } | 304 } |
| 302 } else { | 305 } else { |
| 303 // If there's a cert we can't parse, just leave it. It'll get replaced | 306 // If there's a cert we can't parse, just leave it. It'll get replaced |
| 304 // with a new one if we ever try to use it. | 307 // with a new one if we ever try to use it. |
| 305 LOG(WARNING) << "Error parsing cert for database upgrade for origin " | 308 LOG(WARNING) << "Error parsing cert for database upgrade for origin " |
| 306 << smt.ColumnString(0); | 309 << smt.ColumnString(0); |
| 307 } | 310 } |
| 308 } | 311 } |
| 309 | 312 |
| 310 cur_version = 4; | 313 cur_version = 4; |
| 311 meta_table_.SetVersionNumber(cur_version); | 314 meta_table_.SetVersionNumber(cur_version); |
| 312 meta_table_.SetCompatibleVersionNumber( | 315 meta_table_.SetCompatibleVersionNumber( |
| 313 std::min(cur_version, kCompatibleVersionNumber)); | 316 std::min(cur_version, kCompatibleVersionNumber)); |
| 314 transaction.Commit(); | 317 transaction.Commit(); |
| 315 } | 318 } |
| 316 | 319 |
| 317 // Put future migration cases here. | 320 // Put future migration cases here. |
| 318 | 321 |
| 319 // When the version is too old, we just try to continue anyway, there should | 322 // When the version is too old, we just try to continue anyway, there should |
| 320 // not be a released product that makes a database too old for us to handle. | 323 // not be a released product that makes a database too old for us to handle. |
| 321 LOG_IF(WARNING, cur_version < kCurrentVersionNumber) << | 324 LOG_IF(WARNING, cur_version < kCurrentVersionNumber) << |
| 322 "Origin bound cert database version " << cur_version << | 325 "Server bound cert database version " << cur_version << |
| 323 " is too old to handle."; | 326 " is too old to handle."; |
| 324 | 327 |
| 325 return true; | 328 return true; |
| 326 } | 329 } |
| 327 | 330 |
| 328 void SQLiteOriginBoundCertStore::Backend::AddOriginBoundCert( | 331 void SQLiteServerBoundCertStore::Backend::AddServerBoundCert( |
| 329 const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) { | 332 const net::DefaultServerBoundCertStore::ServerBoundCert& cert) { |
| 330 BatchOperation(PendingOperation::CERT_ADD, cert); | 333 BatchOperation(PendingOperation::CERT_ADD, cert); |
| 331 } | 334 } |
| 332 | 335 |
| 333 void SQLiteOriginBoundCertStore::Backend::DeleteOriginBoundCert( | 336 void SQLiteServerBoundCertStore::Backend::DeleteServerBoundCert( |
| 334 const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) { | 337 const net::DefaultServerBoundCertStore::ServerBoundCert& cert) { |
| 335 BatchOperation(PendingOperation::CERT_DELETE, cert); | 338 BatchOperation(PendingOperation::CERT_DELETE, cert); |
| 336 } | 339 } |
| 337 | 340 |
| 338 void SQLiteOriginBoundCertStore::Backend::BatchOperation( | 341 void SQLiteServerBoundCertStore::Backend::BatchOperation( |
| 339 PendingOperation::OperationType op, | 342 PendingOperation::OperationType op, |
| 340 const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) { | 343 const net::DefaultServerBoundCertStore::ServerBoundCert& cert) { |
| 341 // Commit every 30 seconds. | 344 // Commit every 30 seconds. |
| 342 static const int kCommitIntervalMs = 30 * 1000; | 345 static const int kCommitIntervalMs = 30 * 1000; |
| 343 // Commit right away if we have more than 512 outstanding operations. | 346 // Commit right away if we have more than 512 outstanding operations. |
| 344 static const size_t kCommitAfterBatchSize = 512; | 347 static const size_t kCommitAfterBatchSize = 512; |
| 345 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); | 348 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 346 | 349 |
| 347 // We do a full copy of the cert here, and hopefully just here. | 350 // We do a full copy of the cert here, and hopefully just here. |
| 348 scoped_ptr<PendingOperation> po(new PendingOperation(op, cert)); | 351 scoped_ptr<PendingOperation> po(new PendingOperation(op, cert)); |
| 349 | 352 |
| 350 PendingOperationsList::size_type num_pending; | 353 PendingOperationsList::size_type num_pending; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 361 base::Bind(&Backend::Commit, this), | 364 base::Bind(&Backend::Commit, this), |
| 362 base::TimeDelta::FromMilliseconds(kCommitIntervalMs)); | 365 base::TimeDelta::FromMilliseconds(kCommitIntervalMs)); |
| 363 } else if (num_pending == kCommitAfterBatchSize) { | 366 } else if (num_pending == kCommitAfterBatchSize) { |
| 364 // We've reached a big enough batch, fire off a commit now. | 367 // We've reached a big enough batch, fire off a commit now. |
| 365 BrowserThread::PostTask( | 368 BrowserThread::PostTask( |
| 366 BrowserThread::DB, FROM_HERE, | 369 BrowserThread::DB, FROM_HERE, |
| 367 base::Bind(&Backend::Commit, this)); | 370 base::Bind(&Backend::Commit, this)); |
| 368 } | 371 } |
| 369 } | 372 } |
| 370 | 373 |
| 371 void SQLiteOriginBoundCertStore::Backend::Commit() { | 374 void SQLiteServerBoundCertStore::Backend::Commit() { |
| 372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 375 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 373 | 376 |
| 374 PendingOperationsList ops; | 377 PendingOperationsList ops; |
| 375 { | 378 { |
| 376 base::AutoLock locked(lock_); | 379 base::AutoLock locked(lock_); |
| 377 pending_.swap(ops); | 380 pending_.swap(ops); |
| 378 num_pending_ = 0; | 381 num_pending_ = 0; |
| 379 } | 382 } |
| 380 | 383 |
| 381 // Maybe an old timer fired or we are already Close()'ed. | 384 // Maybe an old timer fired or we are already Close()'ed. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 397 if (!transaction.Begin()) | 400 if (!transaction.Begin()) |
| 398 return; | 401 return; |
| 399 | 402 |
| 400 for (PendingOperationsList::iterator it = ops.begin(); | 403 for (PendingOperationsList::iterator it = ops.begin(); |
| 401 it != ops.end(); ++it) { | 404 it != ops.end(); ++it) { |
| 402 // Free the certs as we commit them to the database. | 405 // Free the certs as we commit them to the database. |
| 403 scoped_ptr<PendingOperation> po(*it); | 406 scoped_ptr<PendingOperation> po(*it); |
| 404 switch (po->op()) { | 407 switch (po->op()) { |
| 405 case PendingOperation::CERT_ADD: { | 408 case PendingOperation::CERT_ADD: { |
| 406 add_smt.Reset(); | 409 add_smt.Reset(); |
| 407 add_smt.BindString(0, po->cert().origin()); | 410 add_smt.BindString(0, po->cert().server_identifier()); |
| 408 const std::string& private_key = po->cert().private_key(); | 411 const std::string& private_key = po->cert().private_key(); |
| 409 add_smt.BindBlob(1, private_key.data(), private_key.size()); | 412 add_smt.BindBlob(1, private_key.data(), private_key.size()); |
| 410 const std::string& cert = po->cert().cert(); | 413 const std::string& cert = po->cert().cert(); |
| 411 add_smt.BindBlob(2, cert.data(), cert.size()); | 414 add_smt.BindBlob(2, cert.data(), cert.size()); |
| 412 add_smt.BindInt(3, po->cert().type()); | 415 add_smt.BindInt(3, po->cert().type()); |
| 413 add_smt.BindInt64(4, po->cert().expiration_time().ToInternalValue()); | 416 add_smt.BindInt64(4, po->cert().expiration_time().ToInternalValue()); |
| 414 add_smt.BindInt64(5, po->cert().creation_time().ToInternalValue()); | 417 add_smt.BindInt64(5, po->cert().creation_time().ToInternalValue()); |
| 415 if (!add_smt.Run()) | 418 if (!add_smt.Run()) |
| 416 NOTREACHED() << "Could not add an origin bound cert to the DB."; | 419 NOTREACHED() << "Could not add a server bound cert to the DB."; |
| 417 break; | 420 break; |
| 418 } | 421 } |
| 419 case PendingOperation::CERT_DELETE: | 422 case PendingOperation::CERT_DELETE: |
| 420 del_smt.Reset(); | 423 del_smt.Reset(); |
| 421 del_smt.BindString(0, po->cert().origin()); | 424 del_smt.BindString(0, po->cert().server_identifier()); |
| 422 if (!del_smt.Run()) | 425 if (!del_smt.Run()) |
| 423 NOTREACHED() << "Could not delete an origin bound cert from the DB."; | 426 NOTREACHED() << "Could not delete a server bound cert from the DB."; |
| 424 break; | 427 break; |
| 425 | 428 |
| 426 default: | 429 default: |
| 427 NOTREACHED(); | 430 NOTREACHED(); |
| 428 break; | 431 break; |
| 429 } | 432 } |
| 430 } | 433 } |
| 431 transaction.Commit(); | 434 transaction.Commit(); |
| 432 } | 435 } |
| 433 | 436 |
| 434 void SQLiteOriginBoundCertStore::Backend::Flush( | 437 void SQLiteServerBoundCertStore::Backend::Flush( |
| 435 const base::Closure& completion_task) { | 438 const base::Closure& completion_task) { |
| 436 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); | 439 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 437 BrowserThread::PostTask( | 440 BrowserThread::PostTask( |
| 438 BrowserThread::DB, FROM_HERE, base::Bind(&Backend::Commit, this)); | 441 BrowserThread::DB, FROM_HERE, base::Bind(&Backend::Commit, this)); |
| 439 if (!completion_task.is_null()) { | 442 if (!completion_task.is_null()) { |
| 440 // We want the completion task to run immediately after Commit() returns. | 443 // We want the completion task to run immediately after Commit() returns. |
| 441 // Posting it from here means there is less chance of another task getting | 444 // Posting it from here means there is less chance of another task getting |
| 442 // onto the message queue first, than if we posted it from Commit() itself. | 445 // onto the message queue first, than if we posted it from Commit() itself. |
| 443 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, completion_task); | 446 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, completion_task); |
| 444 } | 447 } |
| 445 } | 448 } |
| 446 | 449 |
| 447 // Fire off a close message to the background thread. We could still have a | 450 // Fire off a close message to the background thread. We could still have a |
| 448 // pending commit timer that will be holding a reference on us, but if/when | 451 // pending commit timer that will be holding a reference on us, but if/when |
| 449 // this fires we will already have been cleaned up and it will be ignored. | 452 // this fires we will already have been cleaned up and it will be ignored. |
| 450 void SQLiteOriginBoundCertStore::Backend::Close() { | 453 void SQLiteServerBoundCertStore::Backend::Close() { |
| 451 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); | 454 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 452 // Must close the backend on the background thread. | 455 // Must close the backend on the background thread. |
| 453 BrowserThread::PostTask( | 456 BrowserThread::PostTask( |
| 454 BrowserThread::DB, FROM_HERE, | 457 BrowserThread::DB, FROM_HERE, |
| 455 base::Bind(&Backend::InternalBackgroundClose, this)); | 458 base::Bind(&Backend::InternalBackgroundClose, this)); |
| 456 } | 459 } |
| 457 | 460 |
| 458 void SQLiteOriginBoundCertStore::Backend::InternalBackgroundClose() { | 461 void SQLiteServerBoundCertStore::Backend::InternalBackgroundClose() { |
| 459 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 462 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 460 // Commit any pending operations | 463 // Commit any pending operations |
| 461 Commit(); | 464 Commit(); |
| 462 | 465 |
| 463 db_.reset(); | 466 db_.reset(); |
| 464 | 467 |
| 465 if (clear_local_state_on_exit_) | 468 if (clear_local_state_on_exit_) |
| 466 file_util::Delete(path_, false); | 469 file_util::Delete(path_, false); |
| 467 } | 470 } |
| 468 | 471 |
| 469 void SQLiteOriginBoundCertStore::Backend::SetClearLocalStateOnExit( | 472 void SQLiteServerBoundCertStore::Backend::SetClearLocalStateOnExit( |
| 470 bool clear_local_state) { | 473 bool clear_local_state) { |
| 471 base::AutoLock locked(lock_); | 474 base::AutoLock locked(lock_); |
| 472 clear_local_state_on_exit_ = clear_local_state; | 475 clear_local_state_on_exit_ = clear_local_state; |
| 473 } | 476 } |
| 474 | 477 |
| 475 SQLiteOriginBoundCertStore::SQLiteOriginBoundCertStore(const FilePath& path) | 478 SQLiteServerBoundCertStore::SQLiteServerBoundCertStore(const FilePath& path) |
| 476 : backend_(new Backend(path)) { | 479 : backend_(new Backend(path)) { |
| 477 } | 480 } |
| 478 | 481 |
| 479 SQLiteOriginBoundCertStore::~SQLiteOriginBoundCertStore() { | 482 SQLiteServerBoundCertStore::~SQLiteServerBoundCertStore() { |
| 480 if (backend_.get()) { | 483 if (backend_.get()) { |
| 481 backend_->Close(); | 484 backend_->Close(); |
| 482 // Release our reference, it will probably still have a reference if the | 485 // Release our reference, it will probably still have a reference if the |
| 483 // background thread has not run Close() yet. | 486 // background thread has not run Close() yet. |
| 484 backend_ = NULL; | 487 backend_ = NULL; |
| 485 } | 488 } |
| 486 } | 489 } |
| 487 | 490 |
| 488 bool SQLiteOriginBoundCertStore::Load( | 491 bool SQLiteServerBoundCertStore::Load( |
| 489 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*>* certs) { | 492 std::vector<net::DefaultServerBoundCertStore::ServerBoundCert*>* certs) { |
| 490 return backend_->Load(certs); | 493 return backend_->Load(certs); |
| 491 } | 494 } |
| 492 | 495 |
| 493 void SQLiteOriginBoundCertStore::AddOriginBoundCert( | 496 void SQLiteServerBoundCertStore::AddServerBoundCert( |
| 494 const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) { | 497 const net::DefaultServerBoundCertStore::ServerBoundCert& cert) { |
| 495 if (backend_.get()) | 498 if (backend_.get()) |
| 496 backend_->AddOriginBoundCert(cert); | 499 backend_->AddServerBoundCert(cert); |
| 497 } | 500 } |
| 498 | 501 |
| 499 void SQLiteOriginBoundCertStore::DeleteOriginBoundCert( | 502 void SQLiteServerBoundCertStore::DeleteServerBoundCert( |
| 500 const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) { | 503 const net::DefaultServerBoundCertStore::ServerBoundCert& cert) { |
| 501 if (backend_.get()) | 504 if (backend_.get()) |
| 502 backend_->DeleteOriginBoundCert(cert); | 505 backend_->DeleteServerBoundCert(cert); |
| 503 } | 506 } |
| 504 | 507 |
| 505 void SQLiteOriginBoundCertStore::SetClearLocalStateOnExit( | 508 void SQLiteServerBoundCertStore::SetClearLocalStateOnExit( |
| 506 bool clear_local_state) { | 509 bool clear_local_state) { |
| 507 if (backend_.get()) | 510 if (backend_.get()) |
| 508 backend_->SetClearLocalStateOnExit(clear_local_state); | 511 backend_->SetClearLocalStateOnExit(clear_local_state); |
| 509 } | 512 } |
| 510 | 513 |
| 511 void SQLiteOriginBoundCertStore::Flush(const base::Closure& completion_task) { | 514 void SQLiteServerBoundCertStore::Flush(const base::Closure& completion_task) { |
| 512 if (backend_.get()) | 515 if (backend_.get()) |
| 513 backend_->Flush(completion_task); | 516 backend_->Flush(completion_task); |
| 514 else if (!completion_task.is_null()) | 517 else if (!completion_task.is_null()) |
| 515 MessageLoop::current()->PostTask(FROM_HERE, completion_task); | 518 MessageLoop::current()->PostTask(FROM_HERE, completion_task); |
| 516 } | 519 } |
| OLD | NEW |