summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browsing_data_remover.cc49
-rw-r--r--chrome/browser/browsing_data_remover.h26
-rw-r--r--chrome/browser/browsing_data_remover_unittest.cc84
-rw-r--r--chrome/browser/extensions/extension_clear_api.cc8
-rw-r--r--chrome/browser/extensions/extension_clear_api.h14
-rw-r--r--chrome/browser/extensions/extension_clear_test.cc5
-rw-r--r--chrome/browser/net/sqlite_origin_bound_cert_store.cc63
-rw-r--r--chrome/browser/net/sqlite_origin_bound_cert_store_unittest.cc116
-rw-r--r--chrome/tools/chromeactions.txt11
-rw-r--r--net/base/default_origin_bound_cert_store.cc33
-rw-r--r--net/base/default_origin_bound_cert_store.h6
-rw-r--r--net/base/default_origin_bound_cert_store_unittest.cc35
-rw-r--r--net/base/origin_bound_cert_service.cc25
-rw-r--r--net/base/origin_bound_cert_service.h19
-rw-r--r--net/base/origin_bound_cert_service_unittest.cc9
-rw-r--r--net/base/origin_bound_cert_store.cc4
-rw-r--r--net/base/origin_bound_cert_store.h20
-rw-r--r--net/url_request/url_request_test_util.cc8
18 files changed, 460 insertions, 75 deletions
diff --git a/chrome/browser/browsing_data_remover.cc b/chrome/browser/browsing_data_remover.cc
index 25ef011..9273f01 100644
--- a/chrome/browser/browsing_data_remover.cc
+++ b/chrome/browser/browsing_data_remover.cc
@@ -49,6 +49,8 @@
#include "content/public/browser/user_metrics.h"
#include "net/base/cookie_store.h"
#include "net/base/net_errors.h"
+#include "net/base/origin_bound_cert_service.h"
+#include "net/base/origin_bound_cert_store.h"
#include "net/base/transport_security_state.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache.h"
@@ -95,12 +97,13 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
cache_(NULL),
main_context_getter_(profile->GetRequestContext()),
media_context_getter_(profile->GetRequestContextForMedia()),
+ waiting_for_clear_cache_(false),
+ waiting_for_clear_cookies_(false),
waiting_for_clear_history_(false),
- waiting_for_clear_quota_managed_data_(false),
waiting_for_clear_networking_history_(false),
- waiting_for_clear_cookies_(false),
- waiting_for_clear_cache_(false),
+ waiting_for_clear_origin_bound_certs_(false),
waiting_for_clear_plugin_data_(false),
+ waiting_for_clear_quota_managed_data_(false),
remove_mask_(0) {
DCHECK(profile);
}
@@ -117,12 +120,13 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
cache_(NULL),
main_context_getter_(profile->GetRequestContext()),
media_context_getter_(profile->GetRequestContextForMedia()),
+ waiting_for_clear_cache_(false),
+ waiting_for_clear_cookies_(false),
waiting_for_clear_history_(false),
- waiting_for_clear_quota_managed_data_(false),
waiting_for_clear_networking_history_(false),
- waiting_for_clear_cookies_(false),
- waiting_for_clear_cache_(false),
+ waiting_for_clear_origin_bound_certs_(false),
waiting_for_clear_plugin_data_(false),
+ waiting_for_clear_quota_managed_data_(false),
remove_mask_(0) {
DCHECK(profile);
}
@@ -225,6 +229,20 @@ void BrowsingDataRemover::Remove(int remove_mask) {
}
}
+ if (remove_mask & REMOVE_ORIGIN_BOUND_CERTS) {
+ content::RecordAction(
+ UserMetricsAction("ClearBrowsingData_OriginBoundCerts"));
+ // Since we are running on the UI thread don't call GetURLRequestContext().
+ net::URLRequestContextGetter* rq_context = profile_->GetRequestContext();
+ if (rq_context) {
+ waiting_for_clear_origin_bound_certs_ = true;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&BrowsingDataRemover::ClearOriginBoundCertsOnIOThread,
+ base::Unretained(this), base::Unretained(rq_context)));
+ }
+ }
+
if (remove_mask & REMOVE_LOCAL_STORAGE) {
// Remove data such as local databases, STS state, etc. These only can
// be removed if a WEBKIT thread exists, so check that first:
@@ -620,3 +638,22 @@ void BrowsingDataRemover::ClearCookiesOnIOThread(
base::Bind(&BrowsingDataRemover::OnClearedCookies,
base::Unretained(this)));
}
+
+void BrowsingDataRemover::ClearOriginBoundCertsOnIOThread(
+ net::URLRequestContextGetter* rq_context) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ net::OriginBoundCertService* origin_bound_cert_service =
+ rq_context->GetURLRequestContext()->origin_bound_cert_service();
+ origin_bound_cert_service->GetCertStore()->DeleteAllCreatedBetween(
+ delete_begin_, delete_end_);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&BrowsingDataRemover::OnClearedOriginBoundCerts,
+ base::Unretained(this)));
+}
+
+void BrowsingDataRemover::OnClearedOriginBoundCerts() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ waiting_for_clear_origin_bound_certs_ = false;
+ NotifyAndDeleteIfDone();
+}
diff --git a/chrome/browser/browsing_data_remover.h b/chrome/browser/browsing_data_remover.h
index 9bc68d9..7f47002 100644
--- a/chrome/browser/browsing_data_remover.h
+++ b/chrome/browser/browsing_data_remover.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -70,12 +70,14 @@ class BrowsingDataRemover : public content::NotificationObserver,
REMOVE_PLUGIN_DATA = 1 << 9,
REMOVE_PASSWORDS = 1 << 10,
REMOVE_WEBSQL = 1 << 11,
+ REMOVE_ORIGIN_BOUND_CERTS = 1 << 12,
// "Site data" includes cookies, appcache, file systems, indexedDBs, local
// storage, webSQL, and plugin data.
REMOVE_SITE_DATA = REMOVE_APPCACHE | REMOVE_COOKIES | REMOVE_FILE_SYSTEMS |
REMOVE_INDEXEDDB | REMOVE_LOCAL_STORAGE |
- REMOVE_PLUGIN_DATA | REMOVE_WEBSQL
+ REMOVE_PLUGIN_DATA | REMOVE_WEBSQL |
+ REMOVE_ORIGIN_BOUND_CERTS
};
// When BrowsingDataRemover successfully removes data, a notification of type
@@ -208,6 +210,14 @@ class BrowsingDataRemover : public content::NotificationObserver,
// Invoked on the IO thread to delete cookies.
void ClearCookiesOnIOThread(net::URLRequestContextGetter* rq_context);
+ // Invoked on the IO thread to delete origin bound certs.
+ void ClearOriginBoundCertsOnIOThread(
+ net::URLRequestContextGetter* rq_context);
+
+ // Callback when origin bound certs have been deleted. Invokes
+ // NotifyAndDeleteIfDone.
+ void OnClearedOriginBoundCerts();
+
// Calculate the begin time for the deletion range specified by |time_period|.
base::Time CalculateBeginDeleteTime(TimePeriod time_period);
@@ -216,9 +226,10 @@ class BrowsingDataRemover : public content::NotificationObserver,
return registrar_.IsEmpty() && !waiting_for_clear_cache_ &&
!waiting_for_clear_cookies_&&
!waiting_for_clear_history_ &&
- !waiting_for_clear_quota_managed_data_ &&
!waiting_for_clear_networking_history_ &&
- !waiting_for_clear_plugin_data_;
+ !waiting_for_clear_origin_bound_certs_ &&
+ !waiting_for_clear_plugin_data_ &&
+ !waiting_for_clear_quota_managed_data_;
}
// Setter for removing_; DCHECKs that we can only start removing if we're not
@@ -259,12 +270,13 @@ class BrowsingDataRemover : public content::NotificationObserver,
// True if we're waiting for various data to be deleted.
// These may only be accessed from UI thread in order to avoid races!
+ bool waiting_for_clear_cache_;
+ bool waiting_for_clear_cookies_;
bool waiting_for_clear_history_;
- bool waiting_for_clear_quota_managed_data_;
bool waiting_for_clear_networking_history_;
- bool waiting_for_clear_cookies_;
- bool waiting_for_clear_cache_;
+ bool waiting_for_clear_origin_bound_certs_;
bool waiting_for_clear_plugin_data_;
+ bool waiting_for_clear_quota_managed_data_;
// Tracking how many origins need to be deleted, and whether we're finished
// gathering origins.
diff --git a/chrome/browser/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data_remover_unittest.cc
index 97a5c8e..6c88aa3 100644
--- a/chrome/browser/browsing_data_remover_unittest.cc
+++ b/chrome/browser/browsing_data_remover_unittest.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/browsing_data_remover.h"
#include <set>
+#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -19,6 +20,9 @@
#include "content/public/browser/notification_service.h"
#include "content/test/test_browser_thread.h"
#include "net/base/cookie_monster.h"
+#include "net/base/origin_bound_cert_service.h"
+#include "net/base/origin_bound_cert_store.h"
+#include "net/base/ssl_client_cert_type.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -139,6 +143,51 @@ class RemoveCookieTester : public BrowsingDataRemoverTester {
DISALLOW_COPY_AND_ASSIGN(RemoveCookieTester);
};
+class RemoveOriginBoundCertTester : public BrowsingDataRemoverTester {
+ public:
+ explicit RemoveOriginBoundCertTester(TestingProfile* profile) {
+ profile->CreateRequestContext();
+ ob_cert_service_ = profile->GetRequestContext()->GetURLRequestContext()->
+ origin_bound_cert_service();
+ }
+
+ int OriginBoundCertCount() {
+ return ob_cert_service_->cert_count();
+ }
+
+ // Add an origin bound cert for |origin| with specific creation and expiry
+ // times. The cert and key data will be filled with dummy values.
+ void AddOriginBoundCertWithTimes(const std::string& origin,
+ base::Time creation_time,
+ base::Time expiration_time) {
+ GetCertStore()->SetOriginBoundCert(origin, net::CLIENT_CERT_RSA_SIGN,
+ creation_time, expiration_time,
+ "a", "b");
+ }
+
+ // Add an origin bound cert for |origin|, with the current time as the
+ // creation time. The cert and key data will be filled with dummy values.
+ void AddOriginBoundCert(const std::string& origin) {
+ base::Time now = base::Time::Now();
+ AddOriginBoundCertWithTimes(origin,
+ now,
+ now + base::TimeDelta::FromDays(1));
+ }
+
+ net::OriginBoundCertStore* GetCertStore() {
+ return ob_cert_service_->GetCertStore();
+ }
+
+ private:
+ net::OriginBoundCertService* ob_cert_service_;
+
+ net::SSLClientCertType type_;
+ std::string key_;
+ std::string cert_;
+
+ DISALLOW_COPY_AND_ASSIGN(RemoveOriginBoundCertTester);
+};
+
class RemoveHistoryTester : public BrowsingDataRemoverTester {
public:
explicit RemoveHistoryTester(TestingProfile* profile)
@@ -349,6 +398,41 @@ TEST_F(BrowsingDataRemoverTest, RemoveCookieForever) {
EXPECT_FALSE(tester->ContainsCookie());
}
+TEST_F(BrowsingDataRemoverTest, RemoveOriginBoundCertForever) {
+ scoped_ptr<RemoveOriginBoundCertTester> tester(
+ new RemoveOriginBoundCertTester(GetProfile()));
+
+ tester->AddOriginBoundCert(kTestkOrigin1);
+ EXPECT_EQ(1, tester->OriginBoundCertCount());
+
+ BlockUntilBrowsingDataRemoved(BrowsingDataRemover::EVERYTHING,
+ BrowsingDataRemover::REMOVE_ORIGIN_BOUND_CERTS, tester.get());
+
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_ORIGIN_BOUND_CERTS, GetRemovalMask());
+ EXPECT_EQ(0, tester->OriginBoundCertCount());
+}
+
+TEST_F(BrowsingDataRemoverTest, RemoveOriginBoundCertLastHour) {
+ scoped_ptr<RemoveOriginBoundCertTester> tester(
+ new RemoveOriginBoundCertTester(GetProfile()));
+
+ base::Time now = base::Time::Now();
+ tester->AddOriginBoundCert(kTestkOrigin1);
+ tester->AddOriginBoundCertWithTimes(kTestkOrigin2,
+ now - base::TimeDelta::FromHours(2),
+ now);
+ EXPECT_EQ(2, tester->OriginBoundCertCount());
+
+ BlockUntilBrowsingDataRemoved(BrowsingDataRemover::LAST_HOUR,
+ BrowsingDataRemover::REMOVE_ORIGIN_BOUND_CERTS, tester.get());
+
+ EXPECT_EQ(BrowsingDataRemover::REMOVE_ORIGIN_BOUND_CERTS, GetRemovalMask());
+ EXPECT_EQ(1, tester->OriginBoundCertCount());
+ std::vector<net::OriginBoundCertStore::OriginBoundCert> certs;
+ tester->GetCertStore()->GetAllOriginBoundCerts(&certs);
+ EXPECT_EQ(kTestkOrigin2, certs[0].origin());
+}
+
TEST_F(BrowsingDataRemoverTest, RemoveHistoryForever) {
scoped_ptr<RemoveHistoryTester> tester(
new RemoveHistoryTester(GetProfile()));
diff --git a/chrome/browser/extensions/extension_clear_api.cc b/chrome/browser/extensions/extension_clear_api.cc
index d1251cb..05d23e3 100644
--- a/chrome/browser/extensions/extension_clear_api.cc
+++ b/chrome/browser/extensions/extension_clear_api.cc
@@ -34,6 +34,7 @@ const char kFormDataKey[] = "formData";
const char kHistoryKey[] = "history";
const char kIndexedDBKey[] = "indexedDB";
const char kLocalStorageKey[] = "localStorage";
+const char kOriginBoundCertsKey[] = "originBoundCerts";
const char kPasswordsKey[] = "passwords";
const char kPluginDataKey[] = "pluginData";
const char kWebSQLKey[] = "webSQL";
@@ -84,6 +85,9 @@ int ParseRemovalMask(base::DictionaryValue* value) {
if (DataRemovalRequested(value,
extension_clear_api_constants::kLocalStorageKey))
GetRemovalMask |= BrowsingDataRemover::REMOVE_LOCAL_STORAGE;
+ if (DataRemovalRequested(value,
+ extension_clear_api_constants::kOriginBoundCertsKey))
+ GetRemovalMask |= BrowsingDataRemover::REMOVE_ORIGIN_BOUND_CERTS;
if (DataRemovalRequested(value, extension_clear_api_constants::kPasswordsKey))
GetRemovalMask |= BrowsingDataRemover::REMOVE_PASSWORDS;
if (DataRemovalRequested(value,
@@ -209,6 +213,10 @@ int ClearLocalStorageFunction::GetRemovalMask() const {
return BrowsingDataRemover::REMOVE_LOCAL_STORAGE;
}
+int ClearOriginBoundCertsFunction::GetRemovalMask() const {
+ return BrowsingDataRemover::REMOVE_ORIGIN_BOUND_CERTS;
+}
+
int ClearPluginDataFunction::GetRemovalMask() const {
return BrowsingDataRemover::REMOVE_PLUGIN_DATA;
}
diff --git a/chrome/browser/extensions/extension_clear_api.h b/chrome/browser/extensions/extension_clear_api.h
index bd58aae..387486b 100644
--- a/chrome/browser/extensions/extension_clear_api.h
+++ b/chrome/browser/extensions/extension_clear_api.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -192,6 +192,18 @@ class ClearLocalStorageFunction : public BrowsingDataExtensionFunction {
DECLARE_EXTENSION_FUNCTION_NAME("experimental.clear.localStorage")
};
+class ClearOriginBoundCertsFunction : public BrowsingDataExtensionFunction {
+ public:
+ ClearOriginBoundCertsFunction() {}
+ virtual ~ClearOriginBoundCertsFunction() {}
+
+ protected:
+ // BrowsingDataTypeExtensionFunction interface method.
+ virtual int GetRemovalMask() const OVERRIDE;
+
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.clear.originBoundCerts")
+};
+
class ClearPluginDataFunction : public BrowsingDataExtensionFunction {
public:
ClearPluginDataFunction() {}
diff --git a/chrome/browser/extensions/extension_clear_test.cc b/chrome/browser/extensions/extension_clear_test.cc
index ac038da..1f050f2 100644
--- a/chrome/browser/extensions/extension_clear_test.cc
+++ b/chrome/browser/extensions/extension_clear_test.cc
@@ -27,7 +27,8 @@ const char kClearEverythingArguments[] = "[1000, {"
"\"appcache\": true, \"cache\": true, \"cookies\": true, "
"\"downloads\": true, \"fileSystems\": true, \"formData\": true, "
"\"history\": true, \"indexedDB\": true, \"localStorage\": true, "
- "\"pluginData\": true, \"passwords\": true, \"webSQL\": true"
+ "\"originBoundCerts\": true, \"passwords\": true, \"pluginData\": true, "
+ "\"webSQL\": true"
"}]";
class ExtensionClearTest : public InProcessBrowserTest,
@@ -129,6 +130,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionClearTest, ClearBrowsingDataMask) {
RunClearBrowsingDataFunctionAndCompareMask(
"localStorage", BrowsingDataRemover::REMOVE_LOCAL_STORAGE);
RunClearBrowsingDataFunctionAndCompareMask(
+ "originBoundCerts", BrowsingDataRemover::REMOVE_ORIGIN_BOUND_CERTS);
+ RunClearBrowsingDataFunctionAndCompareMask(
"passwords", BrowsingDataRemover::REMOVE_PASSWORDS);
// We can't remove plugin data inside a test profile.
RunClearBrowsingDataFunctionAndCompareMask(
diff --git a/chrome/browser/net/sqlite_origin_bound_cert_store.cc b/chrome/browser/net/sqlite_origin_bound_cert_store.cc
index 90a9ddd..9c6538e 100644
--- a/chrome/browser/net/sqlite_origin_bound_cert_store.cc
+++ b/chrome/browser/net/sqlite_origin_bound_cert_store.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -118,7 +118,7 @@ class SQLiteOriginBoundCertStore::Backend
};
// Version number of the database.
-static const int kCurrentVersionNumber = 3;
+static const int kCurrentVersionNumber = 4;
static const int kCompatibleVersionNumber = 1;
namespace {
@@ -131,7 +131,8 @@ bool InitTable(sql::Connection* db) {
"private_key BLOB NOT NULL,"
"cert BLOB NOT NULL,"
"cert_type INTEGER,"
- "expiration_time INTEGER)"))
+ "expiration_time INTEGER,"
+ "creation_time INTEGER)"))
return false;
}
@@ -173,8 +174,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, expiration_time "
- "FROM origin_bound_certs"));
+ "SELECT origin, private_key, cert, cert_type, expiration_time, "
+ "creation_time FROM origin_bound_certs"));
if (!smt) {
NOTREACHED() << "select statement prep failed";
db_.reset();
@@ -189,6 +190,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(5)),
base::Time::FromInternalValue(smt.ColumnInt64(4)),
private_key_from_db,
cert_from_db));
@@ -234,29 +236,36 @@ bool SQLiteOriginBoundCertStore::Backend::EnsureDatabaseVersion() {
transaction.Commit();
}
- if (cur_version == 2) {
+ 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 origin bound cert database to "
+ << "version 4.";
+ return false;
+ }
+ }
+
if (!db_->Execute("ALTER TABLE origin_bound_certs ADD COLUMN "
- "expiration_time INTEGER")) {
+ "creation_time INTEGER")) {
LOG(WARNING) << "Unable to update origin bound cert database to "
- << "version 3.";
+ << "version 4.";
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) {
+ sql::Statement update_creation_smt(db_->GetUniqueStatement(
+ "UPDATE origin_bound_certs SET creation_time = ? WHERE origin = ?"));
+ if (!smt || !update_expires_smt || !update_creation_smt) {
LOG(WARNING) << "Unable to update origin bound cert database to "
- << "version 3.";
+ << "version 4.";
return false;
}
while (smt.Step()) {
@@ -268,12 +277,24 @@ bool SQLiteOriginBoundCertStore::Backend::EnsureDatabaseVersion() {
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()) {
+ if (cur_version == 2) {
+ 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 4.";
+ return false;
+ }
+ }
+
+ update_creation_smt.Reset();
+ update_creation_smt.BindInt64(0, cert->valid_start().ToInternalValue());
+ update_creation_smt.BindString(1, origin);
+ if (!update_creation_smt.Run()) {
LOG(WARNING) << "Unable to update origin bound cert database to "
- << "version 3.";
+ << "version 4.";
return false;
}
} else {
@@ -284,7 +305,7 @@ bool SQLiteOriginBoundCertStore::Backend::EnsureDatabaseVersion() {
}
}
- ++cur_version;
+ cur_version = 4;
meta_table_.SetVersionNumber(cur_version);
meta_table_.SetCompatibleVersionNumber(
std::min(cur_version, kCompatibleVersionNumber));
diff --git a/chrome/browser/net/sqlite_origin_bound_cert_store_unittest.cc b/chrome/browser/net/sqlite_origin_bound_cert_store_unittest.cc
index 5ee226e..c1715e0 100644
--- a/chrome/browser/net/sqlite_origin_bound_cert_store_unittest.cc
+++ b/chrome/browser/net/sqlite_origin_bound_cert_store_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -43,6 +43,20 @@ class SQLiteOriginBoundCertStoreTest : public testing::Test {
return base::Time::FromInternalValue(GG_INT64_C(16121816625000000));
}
+ static base::Time GetTestCertCreationTime() {
+ // UTCTime 13/12/2011 02:23:45 GMT
+ base::Time::Exploded exploded_time;
+ exploded_time.year = 2011;
+ exploded_time.month = 12;
+ exploded_time.day_of_week = 0; // Unused.
+ exploded_time.day_of_month = 13;
+ exploded_time.hour = 2;
+ exploded_time.minute = 23;
+ exploded_time.second = 45;
+ exploded_time.millisecond = 0;
+ return base::Time::FromUTCExploded(exploded_time);
+ }
+
virtual void SetUp() {
db_thread_.Start();
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
@@ -57,6 +71,7 @@ class SQLiteOriginBoundCertStoreTest : public testing::Test {
"https://encrypted.google.com:8443",
net::CLIENT_CERT_RSA_SIGN,
base::Time(),
+ base::Time(),
"a", "b"));
}
@@ -103,6 +118,7 @@ TEST_F(SQLiteOriginBoundCertStoreTest, TestPersistence) {
"https://www.google.com/",
net::CLIENT_CERT_ECDSA_SIGN,
base::Time(),
+ base::Time(),
"c", "d"));
ScopedVector<net::DefaultOriginBoundCertStore::OriginBoundCert> certs;
@@ -233,7 +249,7 @@ TEST_F(SQLiteOriginBoundCertStoreTest, TestUpgradeV1) {
"SELECT value FROM meta WHERE key = \"version\""));
ASSERT_TRUE(smt);
ASSERT_TRUE(smt.Step());
- EXPECT_EQ(3, smt.ColumnInt(0));
+ EXPECT_EQ(4, smt.ColumnInt(0));
EXPECT_FALSE(smt.Step());
}
}
@@ -322,7 +338,100 @@ TEST_F(SQLiteOriginBoundCertStoreTest, TestUpgradeV2) {
"SELECT value FROM meta WHERE key = \"version\""));
ASSERT_TRUE(smt);
ASSERT_TRUE(smt.Step());
- EXPECT_EQ(3, smt.ColumnInt(0));
+ EXPECT_EQ(4, smt.ColumnInt(0));
+ EXPECT_FALSE(smt.Step());
+ }
+ }
+}
+
+TEST_F(SQLiteOriginBoundCertStoreTest, TestUpgradeV3) {
+ // Reset the store. We'll be using a different database for this test.
+ store_ = NULL;
+
+ FilePath v3_db_path(temp_dir_.path().AppendASCII("v3db"));
+
+ std::string key_data;
+ std::string cert_data;
+ ReadTestKeyAndCert(&key_data, &cert_data);
+
+ // Create a version 3 database.
+ {
+ sql::Connection db;
+ ASSERT_TRUE(db.Open(v3_db_path));
+ ASSERT_TRUE(db.Execute(
+ "CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,"
+ "value LONGVARCHAR);"
+ "INSERT INTO \"meta\" VALUES('version','3');"
+ "INSERT INTO \"meta\" VALUES('last_compatible_version','1');"
+ "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);"
+ ));
+
+ sql::Statement add_smt(db.GetUniqueStatement(
+ "INSERT INTO origin_bound_certs (origin, private_key, cert, cert_type, "
+ "expiration_time) VALUES (?,?,?,?,?)"));
+ add_smt.BindString(0, "https://www.google.com:443");
+ add_smt.BindBlob(1, key_data.data(), key_data.size());
+ add_smt.BindBlob(2, cert_data.data(), cert_data.size());
+ add_smt.BindInt64(3, 1);
+ add_smt.BindInt64(4, 1000);
+ ASSERT_TRUE(add_smt.Run());
+
+ ASSERT_TRUE(db.Execute(
+ "INSERT INTO \"origin_bound_certs\" VALUES("
+ "'https://foo.com',X'AA',X'BB',64,2000);"
+ ));
+ }
+
+ // Load and test the DB contents twice. First time ensures that we can use
+ // the updated values immediately. Second time ensures that the updated
+ // values are saved and read correctly on next load.
+ for (int i = 0; i < 2; ++i) {
+ SCOPED_TRACE(i);
+
+ ScopedVector<net::DefaultOriginBoundCertStore::OriginBoundCert> certs;
+ store_ = new SQLiteOriginBoundCertStore(v3_db_path);
+
+ // Load the database and ensure the certs can be read and are marked as RSA.
+ ASSERT_TRUE(store_->Load(&certs.get()));
+ ASSERT_EQ(2U, certs.size());
+
+ ASSERT_STREQ("https://www.google.com:443", certs[0]->origin().c_str());
+ ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[0]->type());
+ ASSERT_EQ(1000, certs[0]->expiration_time().ToInternalValue());
+ ASSERT_EQ(GetTestCertCreationTime(),
+ certs[0]->creation_time());
+ ASSERT_EQ(key_data, certs[0]->private_key());
+ ASSERT_EQ(cert_data, certs[0]->cert());
+
+ ASSERT_STREQ("https://foo.com", certs[1]->origin().c_str());
+ ASSERT_EQ(net::CLIENT_CERT_ECDSA_SIGN, certs[1]->type());
+ ASSERT_EQ(2000, certs[1]->expiration_time().ToInternalValue());
+ // Undecodable cert, creation time will be uninitialized.
+ ASSERT_EQ(base::Time(), certs[1]->creation_time());
+ ASSERT_STREQ("\xaa", certs[1]->private_key().c_str());
+ ASSERT_STREQ("\xbb", certs[1]->cert().c_str());
+
+ store_ = NULL;
+ // Make sure we wait until the destructor has run.
+ scoped_refptr<base::ThreadTestHelper> helper(
+ new base::ThreadTestHelper(
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)));
+ ASSERT_TRUE(helper->Run());
+
+ // Verify the database version is updated.
+ {
+ sql::Connection db;
+ ASSERT_TRUE(db.Open(v3_db_path));
+ sql::Statement smt(db.GetUniqueStatement(
+ "SELECT value FROM meta WHERE key = \"version\""));
+ ASSERT_TRUE(smt);
+ ASSERT_TRUE(smt.Step());
+ EXPECT_EQ(4, smt.ColumnInt(0));
EXPECT_FALSE(smt.Step());
}
}
@@ -347,6 +456,7 @@ TEST_F(SQLiteOriginBoundCertStoreTest, TestFlush) {
origin,
net::CLIENT_CERT_RSA_SIGN,
base::Time(),
+ base::Time(),
private_key,
cert));
}
diff --git a/chrome/tools/chromeactions.txt b/chrome/tools/chromeactions.txt
index 92c228b..b1e73be 100644
--- a/chrome/tools/chromeactions.txt
+++ b/chrome/tools/chromeactions.txt
@@ -8,6 +8,7 @@
0xc5ec36aaa32ceff4 AboutFlags_confirm-to-quit
0x4e8fe1c674de45dd AboutFlags_conflicting-modules-check
0xe9d2339d6b9225c7 AboutFlags_disable-outdated-plugins
+0xf73b5212b48e2a75 AboutFlags_disable-print-preview
0xdddbf34cee2c636c AboutFlags_dns-server
0x3add7fc42803849e AboutFlags_downloads-new-ui
0x4eae5ccc2900dffa AboutFlags_enable-nacl
@@ -180,6 +181,7 @@
0xea9b835bf0310f85 ClearBrowsingData_Downloads
0xe3c9686626019346 ClearBrowsingData_History
0x86678d0ede469c46 ClearBrowsingData_LSOData
+0x82601d6a3aca0eb1 ClearBrowsingData_OriginBoundCerts
0x511e8366cdda3890 ClearBrowsingData_Passwords
0x6d69a061f7adf595 ClearBrowsingData_ShowDlg
0x9fd631c62234969a ClearSelection
@@ -252,6 +254,7 @@
0x4f07c158c8047ab9 Extensions.ExtensionUninstalled
0x08566bf746b7f665 Extensions.IDChangedError
0xa295e3ad39bbacc0 Extensions.WebStoreLaunch
+0xbea4c2c8eb82d058 Feedback
0x4268aeb48d5c0d1e FileBrowser.CreateNewFolder
0x604a1468d08b7c7b FileBrowser.PhotoEditor.Edit
0xca74d47b273dd801 FileBrowser.PhotoEditor.View
@@ -870,6 +873,7 @@
0x9372bb835cd720fb MoveWordForward
0x002e07cb5223cd33 MoveWordLeft
0xd55f7c4e520b18a4 MoveWordRight
+0xfc8e40d96ab33f1b NTPPromoClosed
0x0cdd043c5d63d234 NTPPromoShown
0xdcf1af37de1d8dd0 NativeUI_Applications
0x3c6e0d9310ba3a20 NewIncognitoWindow
@@ -957,6 +961,8 @@
0x84502179f3e2ae8c Options_ManagerCerts
0x540bea8eaba24835 Options_MetricsReportingCheckbox_Disable
0x4aa2c70a745dbb49 Options_MetricsReportingCheckbox_Enable
+0x224b0bf60dccdeda Options_MousePrimaryRight_Disable
+0xb23cd3cde814d929 Options_MousePrimaryRight_Enable
0xc5fbe9d9b3a165dd Options_PasswordManager_Disable
0x59b4f208d9d9f648 Options_PasswordManager_Enable
0x6149925370ef4f47 Options_PluginsCheckbox_Disable
@@ -994,6 +1000,8 @@
0x6f37e83ce98b3082 Options_TapToClickCheckbox_Enable
0x73defd4825af2700 Options_ThemesGallery
0x60d52658d42b1593 Options_ThemesReset
+0x4a469294c73f23e4 Options_TouchpadTapToClick_Disable
+0x61a29472d343cf72 Options_TouchpadTapToClick_Enable
0xa35806253d8d8b30 Options_Translate_Disable
0x280bb55487be6eb4 Options_Translate_Enable
0x6f40a6712a19568a Options_UseSuggestCheckbox_Disable
@@ -1059,6 +1067,8 @@
0x6cc1116fbd900ebf PasswordManager_Enabled
0x36bb6559696dc912 Paste
0x5d0e6942f354a06c PasteAndMatchStyle
+0xca471265efb33961 PluginContextMenu_RotateClockwise
+0xa260d9dde6e550c4 PluginContextMenu_RotateCounterclockwise
0x6f2cd84fa374c281 Plugin_Blocked
0xcecb82fcd8e64529 Plugin_ClickToPlay
0xc52b281d793adc6b Plugin_Hide_Click
@@ -1142,6 +1152,7 @@
0xfd243b004d004e00 ShowSections_RecentSitesDisabled
0x3b86156dcf560cdb ShowSections_RecentSitesEnabled
0x5118181c3ece5e84 ShowSessions
+0x1a4ebb180ba59b06 Shutdown
0x26f93e6e68e28a69 Star
0x2fbe99005588ef01 StartupTick
0x11a755d598c0c417 Stop
diff --git a/net/base/default_origin_bound_cert_store.cc b/net/base/default_origin_bound_cert_store.cc
index 3c311ca..8e721ae 100644
--- a/net/base/default_origin_bound_cert_store.cc
+++ b/net/base/default_origin_bound_cert_store.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -30,6 +30,7 @@ void DefaultOriginBoundCertStore::FlushStore(
bool DefaultOriginBoundCertStore::GetOriginBoundCert(
const std::string& origin,
SSLClientCertType* type,
+ base::Time* creation_time,
base::Time* expiration_time,
std::string* private_key_result,
std::string* cert_result) {
@@ -43,6 +44,7 @@ bool DefaultOriginBoundCertStore::GetOriginBoundCert(
OriginBoundCert* cert = it->second;
*type = cert->type();
+ *creation_time = cert->creation_time();
*expiration_time = cert->expiration_time();
*private_key_result = cert->private_key();
*cert_result = cert->cert();
@@ -53,6 +55,7 @@ bool DefaultOriginBoundCertStore::GetOriginBoundCert(
void DefaultOriginBoundCertStore::SetOriginBoundCert(
const std::string& origin,
SSLClientCertType type,
+ base::Time creation_time,
base::Time expiration_time,
const std::string& private_key,
const std::string& cert) {
@@ -62,7 +65,8 @@ void DefaultOriginBoundCertStore::SetOriginBoundCert(
InternalDeleteOriginBoundCert(origin);
InternalInsertOriginBoundCert(
origin,
- new OriginBoundCert(origin, type, expiration_time, private_key, cert));
+ new OriginBoundCert(
+ origin, type, creation_time, expiration_time, private_key, cert));
}
void DefaultOriginBoundCertStore::DeleteOriginBoundCert(
@@ -72,17 +76,28 @@ void DefaultOriginBoundCertStore::DeleteOriginBoundCert(
InternalDeleteOriginBoundCert(origin);
}
-void DefaultOriginBoundCertStore::DeleteAll() {
+void DefaultOriginBoundCertStore::DeleteAllCreatedBetween(
+ base::Time delete_begin,
+ base::Time delete_end) {
base::AutoLock autolock(lock_);
InitIfNecessary();
for (OriginBoundCertMap::iterator it = origin_bound_certs_.begin();
- it != origin_bound_certs_.end(); ++it) {
- OriginBoundCert* cert = it->second;
- if (store_)
- store_->DeleteOriginBoundCert(*cert);
- delete cert;
+ it != origin_bound_certs_.end();) {
+ OriginBoundCertMap::iterator cur = it;
+ ++it;
+ OriginBoundCert* cert = cur->second;
+ if ((delete_begin.is_null() || cert->creation_time() >= delete_begin) &&
+ (delete_end.is_null() || cert->creation_time() < delete_end)) {
+ if (store_)
+ store_->DeleteOriginBoundCert(*cert);
+ delete cert;
+ origin_bound_certs_.erase(cur);
+ }
}
- origin_bound_certs_.clear();
+}
+
+void DefaultOriginBoundCertStore::DeleteAll() {
+ DeleteAllCreatedBetween(base::Time(), base::Time());
}
void DefaultOriginBoundCertStore::GetAllOriginBoundCerts(
diff --git a/net/base/default_origin_bound_cert_store.h b/net/base/default_origin_bound_cert_store.h
index 1714248..e717d38 100644
--- a/net/base/default_origin_bound_cert_store.h
+++ b/net/base/default_origin_bound_cert_store.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -57,16 +57,20 @@ class NET_EXPORT DefaultOriginBoundCertStore : public OriginBoundCertStore {
virtual bool GetOriginBoundCert(
const std::string& origin,
SSLClientCertType* type,
+ base::Time* creation_time,
base::Time* expiration_time,
std::string* private_key_result,
std::string* cert_result) OVERRIDE;
virtual void SetOriginBoundCert(
const std::string& origin,
SSLClientCertType type,
+ base::Time creation_time,
base::Time expiration_time,
const std::string& private_key,
const std::string& cert) OVERRIDE;
virtual void DeleteOriginBoundCert(const std::string& origin) OVERRIDE;
+ virtual void DeleteAllCreatedBetween(base::Time delete_begin,
+ base::Time delete_end) OVERRIDE;
virtual void DeleteAll() OVERRIDE;
virtual void GetAllOriginBoundCerts(
std::vector<OriginBoundCert>* origin_bound_certs) OVERRIDE;
diff --git a/net/base/default_origin_bound_cert_store_unittest.cc b/net/base/default_origin_bound_cert_store_unittest.cc
index a62191a..ec55716 100644
--- a/net/base/default_origin_bound_cert_store_unittest.cc
+++ b/net/base/default_origin_bound_cert_store_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -80,12 +80,14 @@ TEST(DefaultOriginBoundCertStoreTest, TestLoading) {
"https://encrypted.google.com/",
CLIENT_CERT_RSA_SIGN,
base::Time(),
+ base::Time(),
"a", "b"));
persistent_store->AddOriginBoundCert(
DefaultOriginBoundCertStore::OriginBoundCert(
"https://www.verisign.com/",
CLIENT_CERT_ECDSA_SIGN,
base::Time(),
+ base::Time(),
"c", "d"));
// Make sure certs load properly.
@@ -94,13 +96,15 @@ TEST(DefaultOriginBoundCertStoreTest, TestLoading) {
store.SetOriginBoundCert(
"https://www.verisign.com/",
CLIENT_CERT_RSA_SIGN,
- base::Time(),
+ base::Time(),
+ base::Time(),
"e", "f");
EXPECT_EQ(2, store.GetCertCount());
store.SetOriginBoundCert(
"https://www.twitter.com/",
CLIENT_CERT_RSA_SIGN,
base::Time(),
+ base::Time(),
"g", "h");
EXPECT_EQ(3, store.GetCertCount());
}
@@ -108,11 +112,13 @@ TEST(DefaultOriginBoundCertStoreTest, TestLoading) {
TEST(DefaultOriginBoundCertStoreTest, TestSettingAndGetting) {
DefaultOriginBoundCertStore store(NULL);
SSLClientCertType type;
+ base::Time creation_time;
base::Time expiration_time;
std::string private_key, cert;
EXPECT_EQ(0, store.GetCertCount());
EXPECT_FALSE(store.GetOriginBoundCert("https://www.verisign.com/",
&type,
+ &creation_time,
&expiration_time,
&private_key,
&cert));
@@ -122,14 +128,17 @@ TEST(DefaultOriginBoundCertStoreTest, TestSettingAndGetting) {
"https://www.verisign.com/",
CLIENT_CERT_RSA_SIGN,
base::Time::FromInternalValue(123),
+ base::Time::FromInternalValue(456),
"i", "j");
EXPECT_TRUE(store.GetOriginBoundCert("https://www.verisign.com/",
&type,
+ &creation_time,
&expiration_time,
&private_key,
&cert));
EXPECT_EQ(CLIENT_CERT_RSA_SIGN, type);
- EXPECT_EQ(123, expiration_time.ToInternalValue());
+ EXPECT_EQ(123, creation_time.ToInternalValue());
+ EXPECT_EQ(456, expiration_time.ToInternalValue());
EXPECT_EQ("i", private_key);
EXPECT_EQ("j", cert);
}
@@ -139,6 +148,7 @@ TEST(DefaultOriginBoundCertStoreTest, TestDuplicateCerts) {
DefaultOriginBoundCertStore store(persistent_store.get());
SSLClientCertType type;
+ base::Time creation_time;
base::Time expiration_time;
std::string private_key, cert;
EXPECT_EQ(0, store.GetCertCount());
@@ -146,21 +156,25 @@ TEST(DefaultOriginBoundCertStoreTest, TestDuplicateCerts) {
"https://www.verisign.com/",
CLIENT_CERT_RSA_SIGN,
base::Time::FromInternalValue(123),
+ base::Time::FromInternalValue(1234),
"a", "b");
store.SetOriginBoundCert(
"https://www.verisign.com/",
CLIENT_CERT_ECDSA_SIGN,
base::Time::FromInternalValue(456),
+ base::Time::FromInternalValue(4567),
"c", "d");
EXPECT_EQ(1, store.GetCertCount());
EXPECT_TRUE(store.GetOriginBoundCert("https://www.verisign.com/",
&type,
+ &creation_time,
&expiration_time,
&private_key,
&cert));
EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type);
- EXPECT_EQ(456, expiration_time.ToInternalValue());
+ EXPECT_EQ(456, creation_time.ToInternalValue());
+ EXPECT_EQ(4567, expiration_time.ToInternalValue());
EXPECT_EQ("c", private_key);
EXPECT_EQ("d", cert);
}
@@ -174,16 +188,19 @@ TEST(DefaultOriginBoundCertStoreTest, TestDeleteAll) {
"https://www.verisign.com/",
CLIENT_CERT_RSA_SIGN,
base::Time(),
+ base::Time(),
"a", "b");
store.SetOriginBoundCert(
"https://www.google.com/",
CLIENT_CERT_RSA_SIGN,
base::Time(),
+ base::Time(),
"c", "d");
store.SetOriginBoundCert(
"https://www.harvard.com/",
CLIENT_CERT_RSA_SIGN,
base::Time(),
+ base::Time(),
"e", "f");
EXPECT_EQ(3, store.GetCertCount());
@@ -196,6 +213,7 @@ TEST(DefaultOriginBoundCertStoreTest, TestDelete) {
DefaultOriginBoundCertStore store(persistent_store.get());
SSLClientCertType type;
+ base::Time creation_time;
base::Time expiration_time;
std::string private_key, cert;
EXPECT_EQ(0, store.GetCertCount());
@@ -203,11 +221,13 @@ TEST(DefaultOriginBoundCertStoreTest, TestDelete) {
"https://www.verisign.com/",
CLIENT_CERT_RSA_SIGN,
base::Time(),
+ base::Time(),
"a", "b");
store.SetOriginBoundCert(
"https://www.google.com/",
CLIENT_CERT_ECDSA_SIGN,
base::Time(),
+ base::Time(),
"c", "d");
EXPECT_EQ(2, store.GetCertCount());
@@ -215,11 +235,13 @@ TEST(DefaultOriginBoundCertStoreTest, TestDelete) {
EXPECT_EQ(1, store.GetCertCount());
EXPECT_FALSE(store.GetOriginBoundCert("https://www.verisign.com/",
&type,
+ &creation_time,
&expiration_time,
&private_key,
&cert));
EXPECT_TRUE(store.GetOriginBoundCert("https://www.google.com/",
&type,
+ &creation_time,
&expiration_time,
&private_key,
&cert));
@@ -227,6 +249,7 @@ TEST(DefaultOriginBoundCertStoreTest, TestDelete) {
EXPECT_EQ(0, store.GetCertCount());
EXPECT_FALSE(store.GetOriginBoundCert("https://www.google.com/",
&type,
+ &creation_time,
&expiration_time,
&private_key,
&cert));
@@ -241,21 +264,25 @@ TEST(DefaultOriginBoundCertStoreTest, TestGetAll) {
"https://www.verisign.com/",
CLIENT_CERT_RSA_SIGN,
base::Time(),
+ base::Time(),
"a", "b");
store.SetOriginBoundCert(
"https://www.google.com/",
CLIENT_CERT_ECDSA_SIGN,
base::Time(),
+ base::Time(),
"c", "d");
store.SetOriginBoundCert(
"https://www.harvard.com/",
CLIENT_CERT_RSA_SIGN,
base::Time(),
+ base::Time(),
"e", "f");
store.SetOriginBoundCert(
"https://www.mit.com/",
CLIENT_CERT_RSA_SIGN,
base::Time(),
+ base::Time(),
"g", "h");
EXPECT_EQ(4, store.GetCertCount());
diff --git a/net/base/origin_bound_cert_service.cc b/net/base/origin_bound_cert_service.cc
index 246383e..1edf9c0 100644
--- a/net/base/origin_bound_cert_service.cc
+++ b/net/base/origin_bound_cert_service.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -134,6 +134,7 @@ class OriginBoundCertServiceWorker {
error_ = OriginBoundCertService::GenerateCert(origin_,
type_,
serial_number_,
+ &creation_time_,
&expiration_time_,
&private_key_,
&cert_);
@@ -161,7 +162,8 @@ class OriginBoundCertServiceWorker {
base::AutoLock locked(lock_);
if (!canceled_) {
origin_bound_cert_service_->HandleResult(
- origin_, error_, type_, expiration_time_, private_key_, cert_);
+ origin_, error_, type_, creation_time_, expiration_time_,
+ private_key_, cert_);
}
}
delete this;
@@ -209,6 +211,7 @@ class OriginBoundCertServiceWorker {
bool canceled_;
int error_;
+ base::Time creation_time_;
base::Time expiration_time_;
std::string private_key_;
std::string cert_;
@@ -302,9 +305,10 @@ int OriginBoundCertService::GetOriginBoundCert(
RequestHandle* out_req) {
DCHECK(CalledOnValidThread());
+ *out_req = NULL;
+
if (callback.is_null() || !private_key || !cert || origin.empty() ||
requested_types.empty()) {
- *out_req = NULL;
return ERR_INVALID_ARGUMENT;
}
@@ -317,7 +321,6 @@ int OriginBoundCertService::GetOriginBoundCert(
}
if (preferred_type == CLIENT_CERT_INVALID_TYPE) {
// None of the requested types are supported.
- *out_req = NULL;
return ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED;
}
@@ -326,9 +329,11 @@ int OriginBoundCertService::GetOriginBoundCert(
// Check if an origin bound cert of an acceptable type already exists for this
// origin, and that it has not expired.
base::Time now = base::Time::Now();
+ base::Time creation_time;
base::Time expiration_time;
if (origin_bound_cert_store_->GetOriginBoundCert(origin,
type,
+ &creation_time,
&expiration_time,
private_key,
cert)) {
@@ -341,7 +346,6 @@ int OriginBoundCertService::GetOriginBoundCert(
<< origin;
} else {
cert_store_hits_++;
- *out_req = NULL;
return OK;
}
}
@@ -360,7 +364,6 @@ int OriginBoundCertService::GetOriginBoundCert(
== requested_types.end()) {
DVLOG(1) << "Found inflight job of wrong type " << job->type()
<< " for " << origin;
- *out_req = NULL;
// If we get here, the server is asking for different types of certs in
// short succession. This probably means the server is broken or
// misconfigured. Since we only store one type of cert per origin, we
@@ -379,7 +382,6 @@ int OriginBoundCertService::GetOriginBoundCert(
if (!worker->Start()) {
delete job;
delete worker;
- *out_req = NULL;
// TODO(rkn): Log to the NetLog.
LOG(ERROR) << "OriginBoundCertServiceWorker couldn't be started.";
return ERR_INSUFFICIENT_RESOURCES; // Just a guess.
@@ -394,10 +396,15 @@ int OriginBoundCertService::GetOriginBoundCert(
return ERR_IO_PENDING;
}
+OriginBoundCertStore* OriginBoundCertService::GetCertStore() {
+ return origin_bound_cert_store_.get();
+}
+
// static
int OriginBoundCertService::GenerateCert(const std::string& origin,
SSLClientCertType type,
uint32 serial_number,
+ base::Time* creation_time,
base::Time* expiration_time,
std::string* private_key,
std::string* cert) {
@@ -466,6 +473,7 @@ int OriginBoundCertService::GenerateCert(const std::string& origin,
private_key->swap(key_out);
cert->swap(der_cert);
+ *creation_time = now;
*expiration_time = not_valid_after;
return OK;
}
@@ -482,13 +490,14 @@ void OriginBoundCertService::CancelRequest(RequestHandle req) {
void OriginBoundCertService::HandleResult(const std::string& origin,
int error,
SSLClientCertType type,
+ base::Time creation_time,
base::Time expiration_time,
const std::string& private_key,
const std::string& cert) {
DCHECK(CalledOnValidThread());
origin_bound_cert_store_->SetOriginBoundCert(
- origin, type, expiration_time, private_key, cert);
+ origin, type, creation_time, expiration_time, private_key, cert);
std::map<std::string, OriginBoundCertServiceJob*>::iterator j;
j = inflight_.find(origin);
diff --git a/net/base/origin_bound_cert_service.h b/net/base/origin_bound_cert_service.h
index 0f78260..298c3e9 100644
--- a/net/base/origin_bound_cert_service.h
+++ b/net/base/origin_bound_cert_service.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -60,9 +60,8 @@ class NET_EXPORT OriginBoundCertService
// could not be completed immediately, in which case the result code will
// be passed to the callback when available.
//
- // If |out_req| is non-NULL, then |*out_req| will be filled with a handle to
- // the async request. This handle is not valid after the request has
- // completed.
+ // |*out_req| will be filled with a handle to the async request. This handle
+ // is not valid after the request has completed.
int GetOriginBoundCert(
const std::string& origin,
const std::vector<uint8>& requested_types,
@@ -77,6 +76,9 @@ class NET_EXPORT OriginBoundCertService
// callback will not be called.
void CancelRequest(RequestHandle req);
+ // Returns the backing OriginBoundCertStore.
+ OriginBoundCertStore* GetCertStore();
+
// Public only for unit testing.
int cert_count();
uint64 requests() const { return requests_; }
@@ -87,15 +89,17 @@ class NET_EXPORT OriginBoundCertService
friend class OriginBoundCertServiceWorker; // Calls HandleResult.
// On success, |private_key| stores a DER-encoded PrivateKeyInfo
- // struct, |cert| stores a DER-encoded certificate, and |expiration_time|
- // stores the expiration time of the certificate. Returns
- // OK if successful and an error code otherwise.
+ // struct, |cert| stores a DER-encoded certificate, |creation_time| stores the
+ // start of the validity period of the certificate and |expiration_time|
+ // stores the expiration time of the certificate. Returns OK if successful and
+ // an error code otherwise.
// |serial_number| is passed in because it is created with the function
// base::RandInt, which opens the file /dev/urandom. /dev/urandom is opened
// with a LazyInstance, which is not allowed on a worker thread.
static int GenerateCert(const std::string& origin,
SSLClientCertType type,
uint32 serial_number,
+ base::Time* creation_time,
base::Time* expiration_time,
std::string* private_key,
std::string* cert);
@@ -103,6 +107,7 @@ class NET_EXPORT OriginBoundCertService
void HandleResult(const std::string& origin,
int error,
SSLClientCertType type,
+ base::Time creation_time,
base::Time expiration_time,
const std::string& private_key,
const std::string& cert);
diff --git a/net/base/origin_bound_cert_service_unittest.cc b/net/base/origin_bound_cert_service_unittest.cc
index 65f40a5..6c0d264 100644
--- a/net/base/origin_bound_cert_service_unittest.cc
+++ b/net/base/origin_bound_cert_service_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -459,14 +459,17 @@ TEST(OriginBoundCertServiceTest, CancelRequest) {
TEST(OriginBoundCertServiceTest, Expiration) {
OriginBoundCertStore* store = new DefaultOriginBoundCertStore(NULL);
+ base::Time now = base::Time::Now();
store->SetOriginBoundCert("https://good",
CLIENT_CERT_RSA_SIGN,
- base::Time::Now() + base::TimeDelta::FromDays(1),
+ now,
+ now + base::TimeDelta::FromDays(1),
"a",
"b");
store->SetOriginBoundCert("https://expired",
CLIENT_CERT_RSA_SIGN,
- base::Time::Now() - base::TimeDelta::FromDays(1),
+ now - base::TimeDelta::FromDays(2),
+ now - base::TimeDelta::FromDays(1),
"c",
"d");
OriginBoundCertService service(store);
diff --git a/net/base/origin_bound_cert_store.cc b/net/base/origin_bound_cert_store.cc
index 6a31a7e..af2acce 100644
--- a/net/base/origin_bound_cert_store.cc
+++ b/net/base/origin_bound_cert_store.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -13,11 +13,13 @@ OriginBoundCertStore::OriginBoundCert::OriginBoundCert()
OriginBoundCertStore::OriginBoundCert::OriginBoundCert(
const std::string& origin,
SSLClientCertType type,
+ base::Time creation_time,
base::Time expiration_time,
const std::string& private_key,
const std::string& cert)
: origin_(origin),
type_(type),
+ creation_time_(creation_time),
expiration_time_(expiration_time),
private_key_(private_key),
cert_(cert) {}
diff --git a/net/base/origin_bound_cert_store.h b/net/base/origin_bound_cert_store.h
index 1eb8382..1101a01 100644
--- a/net/base/origin_bound_cert_store.h
+++ b/net/base/origin_bound_cert_store.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -31,6 +31,7 @@ class NET_EXPORT OriginBoundCertStore {
OriginBoundCert();
OriginBoundCert(const std::string& origin,
SSLClientCertType type,
+ base::Time creation_time,
base::Time expiration_time,
const std::string& private_key,
const std::string& cert);
@@ -40,6 +41,9 @@ class NET_EXPORT OriginBoundCertStore {
const std::string& origin() const { return origin_; }
// TLS ClientCertificateType.
SSLClientCertType type() const { return type_; }
+ // The time the certificate was created, also the start of the certificate
+ // validity period.
+ base::Time creation_time() const { return creation_time_; }
// The time after which this certificate is no longer valid.
base::Time expiration_time() const { return expiration_time_; }
// The encoding of the private key depends on the type.
@@ -52,6 +56,7 @@ class NET_EXPORT OriginBoundCertStore {
private:
std::string origin_;
SSLClientCertType type_;
+ base::Time creation_time_;
base::Time expiration_time_;
std::string private_key_;
std::string cert_;
@@ -63,12 +68,14 @@ class NET_EXPORT OriginBoundCertStore {
// interface.
// Returns true on success. |private_key_result| stores a DER-encoded
// PrivateKeyInfo struct, |cert_result| stores a DER-encoded certificate,
- // |type| is the ClientCertificateType of the returned certificate, and
- // |expiration_time| is the expiration time of the certificate.
+ // |type| is the ClientCertificateType of the returned certificate,
+ // |creation_time| stores the start of the validity period of the certificate
+ // and |expiration_time| is the expiration time of the certificate.
// Returns false if no origin bound cert exists for the specified origin.
virtual bool GetOriginBoundCert(
const std::string& origin,
SSLClientCertType* type,
+ base::Time* creation_time,
base::Time* expiration_time,
std::string* private_key_result,
std::string* cert_result) = 0;
@@ -77,6 +84,7 @@ class NET_EXPORT OriginBoundCertStore {
virtual void SetOriginBoundCert(
const std::string& origin,
SSLClientCertType type,
+ base::Time creation_time,
base::Time expiration_time,
const std::string& private_key,
const std::string& cert) = 0;
@@ -85,6 +93,12 @@ class NET_EXPORT OriginBoundCertStore {
// store.
virtual void DeleteOriginBoundCert(const std::string& origin) = 0;
+ // Deletes all of the origin bound certs that have a creation_date greater
+ // than or equal to |delete_begin| and less than |delete_end|. If a
+ // base::Time value is_null, that side of the comparison is unbounded.
+ virtual void DeleteAllCreatedBetween(base::Time delete_begin,
+ base::Time delete_end) = 0;
+
// Removes all origin bound certs and the corresponding private keys from
// the store.
virtual void DeleteAll() = 0;
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index d9544ab..c296745 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -8,7 +8,9 @@
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/threading/thread.h"
+#include "net/base/default_origin_bound_cert_store.h"
#include "net/base/host_port_pair.h"
+#include "net/base/origin_bound_cert_service.h"
#include "net/http/http_network_session.h"
#include "net/http/http_server_properties_impl.h"
#include "net/url_request/url_request_job_factory.h"
@@ -140,6 +142,12 @@ void TestURLRequestContext::Init() {
// In-memory cookie store.
if (!cookie_store())
context_storage_.set_cookie_store(new net::CookieMonster(NULL, NULL));
+ // In-memory origin bound cert service.
+ if (!origin_bound_cert_service()) {
+ context_storage_.set_origin_bound_cert_service(
+ new net::OriginBoundCertService(
+ new net::DefaultOriginBoundCertStore(NULL)));
+ }
if (accept_language().empty())
set_accept_language("en-us,fr");
if (accept_charset().empty())