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

Unified Diff: net/extras/sqlite/sqlite_channel_id_store.cc

Issue 1076063002: Remove certificates from Channel ID (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Udpate KeysEqual to fail if preconditions fail Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/extras/sqlite/sqlite_channel_id_store.cc
diff --git a/net/extras/sqlite/sqlite_channel_id_store.cc b/net/extras/sqlite/sqlite_channel_id_store.cc
index daf0eeac23d9f24c24d931a3cf1bba575f168f45..d6828a7c18d8545953039379ce917dbcfd048d70 100644
--- a/net/extras/sqlite/sqlite_channel_id_store.cc
+++ b/net/extras/sqlite/sqlite_channel_id_store.cc
@@ -17,8 +17,11 @@
#include "base/metrics/histogram.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_util.h"
+#include "crypto/ec_private_key.h"
+#include "net/cert/asn1_util.h"
#include "net/cert/x509_certificate.h"
#include "net/cookies/cookie_util.h"
+#include "net/ssl/channel_id_service.h"
#include "net/ssl/ssl_client_cert_type.h"
#include "sql/error_delegate_util.h"
#include "sql/meta_table.h"
@@ -29,29 +32,8 @@
namespace {
// Version number of the database.
-const int kCurrentVersionNumber = 4;
-const int kCompatibleVersionNumber = 1;
-
-// Initializes the certs table, returning true on success.
-bool InitTable(sql::Connection* db) {
- // The table is named "origin_bound_certs" for backwards compatability before
- // we renamed this class to SQLiteChannelIDStore. Likewise, the primary
- // key is "origin", but now can be other things like a plain domain.
- if (!db->DoesTableExist("origin_bound_certs")) {
- if (!db->Execute(
- "CREATE TABLE origin_bound_certs ("
- "origin TEXT NOT NULL UNIQUE PRIMARY KEY,"
- "private_key BLOB NOT NULL,"
- "cert BLOB NOT NULL,"
- "cert_type INTEGER,"
- "expiration_time INTEGER,"
- "creation_time INTEGER)")) {
- return false;
- }
- }
-
- return true;
-}
+const int kCurrentVersionNumber = 5;
+const int kCompatibleVersionNumber = 5;
} // namespace
@@ -212,7 +194,7 @@ void SQLiteChannelIDStore::Backend::LoadInBackground(
return;
}
- if (!EnsureDatabaseVersion() || !InitTable(db_.get())) {
+ if (!EnsureDatabaseVersion()) {
NOTREACHED() << "Unable to open cert DB.";
if (corruption_detected_)
KillDatabase();
@@ -225,8 +207,7 @@ void SQLiteChannelIDStore::Backend::LoadInBackground(
// Slurp all the certs into the out-vector.
sql::Statement smt(db_->GetUniqueStatement(
- "SELECT origin, private_key, cert, cert_type, expiration_time, "
- "creation_time FROM origin_bound_certs"));
+ "SELECT host, private_key, public_key, creation_time FROM channel_id"));
if (!smt.is_valid()) {
if (corruption_detected_)
KillDatabase();
@@ -236,19 +217,19 @@ void SQLiteChannelIDStore::Backend::LoadInBackground(
}
while (smt.Step()) {
- SSLClientCertType type = static_cast<SSLClientCertType>(smt.ColumnInt(3));
- if (type != CLIENT_CERT_ECDSA_SIGN)
+ std::vector<uint8> private_key_from_db, public_key_from_db;
+ smt.ColumnBlobAsVector(1, &private_key_from_db);
+ smt.ColumnBlobAsVector(2, &public_key_from_db);
+ scoped_ptr<crypto::ECPrivateKey> key(
+ crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
+ ChannelIDService::kEPKIPassword, private_key_from_db,
+ public_key_from_db));
+ if (!key)
continue;
- std::string private_key_from_db, cert_from_db;
- smt.ColumnBlobAsString(1, &private_key_from_db);
- smt.ColumnBlobAsString(2, &cert_from_db);
scoped_ptr<DefaultChannelIDStore::ChannelID> channel_id(
new DefaultChannelIDStore::ChannelID(
- smt.ColumnString(0), // origin
- base::Time::FromInternalValue(smt.ColumnInt64(5)),
- base::Time::FromInternalValue(smt.ColumnInt64(4)),
- private_key_from_db,
- cert_from_db));
+ smt.ColumnString(0), // host
+ base::Time::FromInternalValue(smt.ColumnInt64(3)), key.Pass()));
channel_ids->push_back(channel_id.release());
}
@@ -278,94 +259,64 @@ bool SQLiteChannelIDStore::Backend::EnsureDatabaseVersion() {
}
int cur_version = meta_table_.GetVersionNumber();
- if (cur_version == 1) {
- sql::Transaction transaction(db_.get());
- if (!transaction.Begin())
- return false;
- if (!db_->Execute(
- "ALTER TABLE origin_bound_certs ADD COLUMN cert_type "
- "INTEGER")) {
- LOG(WARNING) << "Unable to update server bound cert database to "
- << "version 2.";
- return false;
- }
- // All certs in version 1 database are rsa_sign, which are unsupported.
- // Just discard them all.
- if (!db_->Execute("DELETE from origin_bound_certs")) {
- LOG(WARNING) << "Unable to update server bound cert database to "
- << "version 2.";
- return false;
- }
- ++cur_version;
- meta_table_.SetVersionNumber(cur_version);
- meta_table_.SetCompatibleVersionNumber(
- std::min(cur_version, kCompatibleVersionNumber));
- transaction.Commit();
- }
-
- if (cur_version <= 3) {
- sql::Transaction transaction(db_.get());
- if (!transaction.Begin())
- return false;
- if (cur_version == 2) {
- if (!db_->Execute(
- "ALTER TABLE origin_bound_certs ADD COLUMN "
- "expiration_time INTEGER")) {
- LOG(WARNING) << "Unable to update server bound cert database to "
- << "version 4.";
- return false;
- }
- }
+ sql::Transaction transaction(db_.get());
+ if (!transaction.Begin())
+ return false;
+ // Create new table if it doesn't already exist
+ if (!db_->DoesTableExist("channel_id")) {
if (!db_->Execute(
- "ALTER TABLE origin_bound_certs ADD COLUMN "
- "creation_time INTEGER")) {
- LOG(WARNING) << "Unable to update server bound cert database to "
- << "version 4.";
+ "CREATE TABLE channel_id ("
+ "host TEXT NOT NULL UNIQUE PRIMARY KEY,"
+ "private_key BLOB NOT NULL,"
+ "public_key BLOB NOT NULL,"
+ "creation_time INTEGER)")) {
return false;
}
+ }
- sql::Statement statement(
- db_->GetUniqueStatement("SELECT origin, cert FROM origin_bound_certs"));
- sql::Statement update_expires_statement(db_->GetUniqueStatement(
- "UPDATE origin_bound_certs SET expiration_time = ? WHERE origin = ?"));
- sql::Statement update_creation_statement(db_->GetUniqueStatement(
- "UPDATE origin_bound_certs SET creation_time = ? WHERE origin = ?"));
- if (!statement.is_valid() || !update_expires_statement.is_valid() ||
- !update_creation_statement.is_valid()) {
+ // Migrate from previous versions to new version if possible
+ if (cur_version >= 2 && cur_version <= 4) {
+ sql::Statement statement(db_->GetUniqueStatement(
+ "SELECT origin, cert, private_key, cert_type FROM origin_bound_certs"));
+ sql::Statement insert_statement(db_->GetUniqueStatement(
+ "INSERT INTO channel_id (host, private_key, public_key, creation_time) "
+ "VALUES (?, ?, ?, ?)"));
+ if (!statement.is_valid() || !insert_statement.is_valid()) {
LOG(WARNING) << "Unable to update server bound cert database to "
- << "version 4.";
+ << "version 5.";
return false;
}
while (statement.Step()) {
+ if (statement.ColumnInt64(3) != CLIENT_CERT_ECDSA_SIGN)
+ continue;
std::string origin = statement.ColumnString(0);
std::string cert_from_db;
statement.ColumnBlobAsString(1, &cert_from_db);
+ std::string private_key;
+ statement.ColumnBlobAsString(2, &private_key);
// Parse the cert and extract the real value and then update the DB.
scoped_refptr<X509Certificate> cert(X509Certificate::CreateFromBytes(
cert_from_db.data(), static_cast<int>(cert_from_db.size())));
if (cert.get()) {
- if (cur_version == 2) {
- update_expires_statement.Reset(true);
- update_expires_statement.BindInt64(
- 0, cert->valid_expiry().ToInternalValue());
- update_expires_statement.BindString(1, origin);
- if (!update_expires_statement.Run()) {
- LOG(WARNING) << "Unable to update server bound cert database to "
- << "version 4.";
- return false;
- }
+ insert_statement.Reset(true);
+ insert_statement.BindString(0, origin);
+ insert_statement.BindBlob(1, private_key.data(),
+ static_cast<int>(private_key.size()));
+ base::StringPiece spki;
+ if (!asn1::ExtractSPKIFromDERCert(cert_from_db, &spki)) {
+ LOG(WARNING) << "Unable to extract SPKI from cert when migrating "
+ "channel id database to version 5.";
+ return false;
}
-
- update_creation_statement.Reset(true);
- update_creation_statement.BindInt64(
- 0, cert->valid_start().ToInternalValue());
- update_creation_statement.BindString(1, origin);
- if (!update_creation_statement.Run()) {
- LOG(WARNING) << "Unable to update server bound cert database to "
- << "version 4.";
+ insert_statement.BindBlob(2, spki.data(),
+ static_cast<int>(spki.size()));
+ insert_statement.BindInt64(3, cert->valid_start().ToInternalValue());
+ if (!insert_statement.Run()) {
+ LOG(WARNING) << "Unable to update channel id database to "
+ << "version 5.";
return false;
}
} else {
@@ -375,22 +326,22 @@ bool SQLiteChannelIDStore::Backend::EnsureDatabaseVersion() {
<< statement.ColumnString(0);
}
}
+ }
- cur_version = 4;
- meta_table_.SetVersionNumber(cur_version);
- meta_table_.SetCompatibleVersionNumber(
- std::min(cur_version, kCompatibleVersionNumber));
- transaction.Commit();
+ if (cur_version < kCurrentVersionNumber) {
+ sql::Statement statement(
+ db_->GetUniqueStatement("DROP TABLE origin_bound_certs"));
+ if (!statement.Run()) {
+ LOG(WARNING) << "Error dropping old origin_bound_certs table";
+ return false;
+ }
+ meta_table_.SetVersionNumber(kCurrentVersionNumber);
+ meta_table_.SetCompatibleVersionNumber(kCompatibleVersionNumber);
}
+ transaction.Commit();
// Put future migration cases here.
- // When the version is too old, we just try to continue anyway, there should
- // not be a released product that makes a database too old for us to handle.
- LOG_IF(WARNING, cur_version < kCurrentVersionNumber)
- << "Server bound cert database version " << cur_version
- << " is too old to handle.";
-
return true;
}
@@ -519,13 +470,13 @@ void SQLiteChannelIDStore::Backend::Commit() {
sql::Statement add_statement(db_->GetCachedStatement(
SQL_FROM_HERE,
- "INSERT INTO origin_bound_certs (origin, private_key, cert, cert_type, "
- "expiration_time, creation_time) VALUES (?,?,?,?,?,?)"));
+ "INSERT INTO channel_id (host, private_key, public_key, "
+ "creation_time) VALUES (?,?,?,?)"));
if (!add_statement.is_valid())
return;
sql::Statement del_statement(db_->GetCachedStatement(
- SQL_FROM_HERE, "DELETE FROM origin_bound_certs WHERE origin=?"));
+ SQL_FROM_HERE, "DELETE FROM channel_id WHERE host=?"));
if (!del_statement.is_valid())
return;
@@ -541,16 +492,18 @@ void SQLiteChannelIDStore::Backend::Commit() {
case PendingOperation::CHANNEL_ID_ADD: {
add_statement.Reset(true);
add_statement.BindString(0, po->channel_id().server_identifier());
- const std::string& private_key = po->channel_id().private_key();
+ std::vector<uint8> private_key, public_key;
+ if (!po->channel_id().key()->ExportEncryptedPrivateKey(
+ ChannelIDService::kEPKIPassword, 1, &private_key))
+ continue;
+ if (!po->channel_id().key()->ExportPublicKey(&public_key))
+ continue;
add_statement.BindBlob(
1, private_key.data(), static_cast<int>(private_key.size()));
- const std::string& cert = po->channel_id().cert();
- add_statement.BindBlob(2, cert.data(), static_cast<int>(cert.size()));
- add_statement.BindInt(3, CLIENT_CERT_ECDSA_SIGN);
- add_statement.BindInt64(
- 4, po->channel_id().expiration_time().ToInternalValue());
+ add_statement.BindBlob(2, public_key.data(),
+ static_cast<int>(public_key.size()));
add_statement.BindInt64(
- 5, po->channel_id().creation_time().ToInternalValue());
+ 3, po->channel_id().creation_time().ToInternalValue());
if (!add_statement.Run())
NOTREACHED() << "Could not add a server bound cert to the DB.";
break;
@@ -596,7 +549,7 @@ void SQLiteChannelIDStore::Backend::BackgroundDeleteAllInList(
PrunePendingOperationsForDeletes(server_identifiers);
sql::Statement del_smt(db_->GetCachedStatement(
- SQL_FROM_HERE, "DELETE FROM origin_bound_certs WHERE origin=?"));
+ SQL_FROM_HERE, "DELETE FROM channel_id WHERE host=?"));
if (!del_smt.is_valid()) {
LOG(WARNING) << "Unable to delete channel ids.";
return;
« no previous file with comments | « net/data/ssl/certificates/unittest.originbound.key.der ('k') | net/extras/sqlite/sqlite_channel_id_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698