Index: chrome/browser/net/sqlite_origin_bound_cert_store.cc |
diff --git a/chrome/browser/net/sqlite_origin_bound_cert_store.cc b/chrome/browser/net/sqlite_origin_bound_cert_store.cc |
index 2223394821b1533860d6520e490671a2b984ff8a..039530b20132aff75dc5b639e02d72bedd9ee432 100644 |
--- a/chrome/browser/net/sqlite_origin_bound_cert_store.cc |
+++ b/chrome/browser/net/sqlite_origin_bound_cert_store.cc |
@@ -18,6 +18,7 @@ |
#include "chrome/browser/diagnostics/sqlite_diagnostics.h" |
#include "content/public/browser/browser_thread.h" |
#include "net/base/ssl_client_cert_type.h" |
+#include "net/base/x509_certificate.h" |
#include "sql/meta_table.h" |
#include "sql/statement.h" |
#include "sql/transaction.h" |
@@ -117,7 +118,7 @@ class SQLiteOriginBoundCertStore::Backend |
}; |
// Version number of the database. |
-static const int kCurrentVersionNumber = 2; |
+static const int kCurrentVersionNumber = 3; |
static const int kCompatibleVersionNumber = 1; |
namespace { |
@@ -129,7 +130,8 @@ bool InitTable(sql::Connection* db) { |
"origin TEXT NOT NULL UNIQUE PRIMARY KEY," |
"private_key BLOB NOT NULL," |
"cert BLOB NOT NULL," |
- "cert_type INTEGER)")) |
+ "cert_type INTEGER," |
+ "expiration_time INTEGER)")) |
return false; |
} |
@@ -171,7 +173,8 @@ bool SQLiteOriginBoundCertStore::Backend::Load( |
// Slurp all the certs into the out-vector. |
sql::Statement smt(db_->GetUniqueStatement( |
- "SELECT origin, private_key, cert, cert_type FROM origin_bound_certs")); |
+ "SELECT origin, private_key, cert, cert_type, expiration_time " |
+ "FROM origin_bound_certs")); |
if (!smt) { |
NOTREACHED() << "select statement prep failed"; |
db_.reset(); |
@@ -186,6 +189,7 @@ bool SQLiteOriginBoundCertStore::Backend::Load( |
new net::DefaultOriginBoundCertStore::OriginBoundCert( |
smt.ColumnString(0), // origin |
static_cast<net::SSLClientCertType>(smt.ColumnInt(3)), |
+ base::Time::FromInternalValue(smt.ColumnInt64(4)), |
private_key_from_db, |
cert_from_db)); |
certs->push_back(cert.release()); |
@@ -230,6 +234,63 @@ bool SQLiteOriginBoundCertStore::Backend::EnsureDatabaseVersion() { |
transaction.Commit(); |
} |
+ if (cur_version == 2) { |
+ sql::Transaction transaction(db_.get()); |
+ if (!transaction.Begin()) |
+ return false; |
+ if (!db_->Execute("ALTER TABLE origin_bound_certs ADD COLUMN " |
+ "expiration_time INTEGER")) { |
+ LOG(WARNING) << "Unable to update origin bound cert database to " |
+ << "version 3."; |
+ return false; |
+ } |
+ |
+ sql::Statement smt(db_->GetUniqueStatement( |
+ "SELECT origin, cert FROM origin_bound_certs")); |
+ if (!smt) { |
+ LOG(WARNING) << "Unable to update origin bound cert database to " |
+ << "version 3."; |
+ return false; |
+ } |
+ sql::Statement update_expires_smt(db_->GetUniqueStatement( |
+ "UPDATE origin_bound_certs SET expiration_time = ? WHERE origin = ?")); |
+ if (!update_expires_smt) { |
+ LOG(WARNING) << "Unable to update origin bound cert database to " |
+ << "version 3."; |
+ return false; |
+ } |
+ while (smt.Step()) { |
+ std::string origin = smt.ColumnString(0); |
+ std::string cert_from_db; |
+ smt.ColumnBlobAsString(1, &cert_from_db); |
+ // Parse the cert and extract the real value and then update the DB. |
+ scoped_refptr<net::X509Certificate> cert( |
+ net::X509Certificate::CreateFromBytes( |
+ cert_from_db.data(), cert_from_db.size())); |
+ if (cert) { |
+ update_expires_smt.Reset(); |
+ update_expires_smt.BindInt64(0, cert->valid_expiry().ToInternalValue()); |
+ update_expires_smt.BindString(1, origin); |
+ if (!update_expires_smt.Run()) { |
+ LOG(WARNING) << "Unable to update origin bound cert database to " |
+ << "version 3."; |
+ return false; |
+ } |
+ } else { |
+ // If there's a cert we can't parse, just leave it. It'll get replaced |
+ // with a new one if we ever try to use it. |
+ LOG(WARNING) << "Error parsing cert for database upgrade for origin " |
+ << smt.ColumnString(0); |
+ } |
+ } |
+ |
+ ++cur_version; |
+ meta_table_.SetVersionNumber(cur_version); |
+ meta_table_.SetCompatibleVersionNumber( |
+ std::min(cur_version, kCompatibleVersionNumber)); |
+ transaction.Commit(); |
+ } |
+ |
// Put future migration cases here. |
// When the version is too old, we just try to continue anyway, there should |
@@ -298,8 +359,8 @@ void SQLiteOriginBoundCertStore::Backend::Commit() { |
return; |
sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE, |
- "INSERT INTO origin_bound_certs (origin, private_key, cert, cert_type) " |
- "VALUES (?,?,?,?)")); |
+ "INSERT INTO origin_bound_certs (origin, private_key, cert, cert_type, " |
+ "expiration_time) VALUES (?,?,?,?,?)")); |
if (!add_smt) { |
NOTREACHED(); |
return; |
@@ -330,6 +391,7 @@ void SQLiteOriginBoundCertStore::Backend::Commit() { |
const std::string& cert = po->cert().cert(); |
add_smt.BindBlob(2, cert.data(), cert.size()); |
add_smt.BindInt(3, po->cert().type()); |
+ add_smt.BindInt64(4, po->cert().expiration_time().ToInternalValue()); |
if (!add_smt.Run()) |
NOTREACHED() << "Could not add an origin bound cert to the DB."; |
break; |