diff options
24 files changed, 907 insertions, 20 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 75e74ee..aea5e81 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -9356,6 +9356,30 @@ experiment id: "<ph name="EXPERIMENT_ID">$5<ex>ar1</ex></ph>" <message name="IDS_COOKIES_LAST_ACCESSED_LABEL" desc="The last access date label"> Last accessed: </message> + <message name="IDS_COOKIES_SERVER_BOUND_CERT" desc="The text shown when there is a server bound cert in the Cookies table"> + Domain Bound Certificate + </message> + <message name="IDS_COOKIES_SERVER_BOUND_CERTS" desc="Label for the folder under which a list of server bound certs (name of an internet standard) are displayed"> + Domain Bound Certificates + </message> + <message name="IDS_COOKIES_SERVER_BOUND_CERT_ORIGIN_LABEL" desc="The server bound certificate label for the server domain"> + Domain: + </message> + <message name="IDS_COOKIES_SERVER_BOUND_CERT_TYPE_LABEL" desc="The server bound certificate Type label"> + Certificate Type: + </message> + <message name="IDS_COOKIES_SERVER_BOUND_CERT_CREATED_LABEL" desc="The server bound certificate Created label"> + Created: + </message> + <message name="IDS_COOKIES_SERVER_BOUND_CERT_EXPIRES_LABEL" desc="The server bound certificate Expires label"> + Expires: + </message> + <message name="IDS_CLIENT_CERT_RSA_SIGN" translateable="false" desc=""> + rsa_sign + </message> + <message name="IDS_CLIENT_CERT_ECDSA_SIGN" translateable="false" desc=""> + ecdsa_sign + </message> <!-- New Tab --> <if expr="pp_ifdef('android')"> diff --git a/chrome/browser/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data_remover_unittest.cc index 6df3a3c..b8f94e5 100644 --- a/chrome/browser/browsing_data_remover_unittest.cc +++ b/chrome/browser/browsing_data_remover_unittest.cc @@ -553,9 +553,9 @@ TEST_F(BrowsingDataRemoverTest, RemoveServerBoundCertLastHour) { EXPECT_EQ(BrowsingDataRemover::REMOVE_SERVER_BOUND_CERTS, GetRemovalMask()); EXPECT_EQ(1, tester->ServerBoundCertCount()); - std::vector<net::ServerBoundCertStore::ServerBoundCert> certs; + net::ServerBoundCertStore::ServerBoundCertList certs; tester->GetCertStore()->GetAllServerBoundCerts(&certs); - EXPECT_EQ(kTestOrigin2, certs[0].server_identifier()); + EXPECT_EQ(kTestOrigin2, certs.front().server_identifier()); } TEST_F(BrowsingDataRemoverTest, RemoveHistoryForever) { diff --git a/chrome/browser/browsing_data_server_bound_cert_helper.cc b/chrome/browser/browsing_data_server_bound_cert_helper.cc new file mode 100644 index 0000000..6c70ebc --- /dev/null +++ b/chrome/browser/browsing_data_server_bound_cert_helper.cc @@ -0,0 +1,186 @@ +// 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. + +#include "chrome/browser/browsing_data_server_bound_cert_helper.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" +#include "chrome/browser/profiles/profile.h" +#include "content/public/browser/browser_thread.h" +#include "net/base/server_bound_cert_service.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_getter.h" + +namespace { + +class BrowsingDataServerBoundCertHelperImpl + : public BrowsingDataServerBoundCertHelper { + public: + explicit BrowsingDataServerBoundCertHelperImpl(Profile* profile); + + // BrowsingDataServerBoundCertHelper methods. + virtual void StartFetching(const FetchResultCallback& callback) OVERRIDE; + virtual void DeleteServerBoundCert(const std::string& server_id) OVERRIDE; + + private: + virtual ~BrowsingDataServerBoundCertHelperImpl(); + + // Fetch the certs. This must be called in the IO thread. + void FetchOnIOThread(); + + // Notifies the completion callback. This must be called in the UI thread. + void NotifyInUIThread(); + + // Delete a single cert. This must be called in IO thread. + void DeleteOnIOThread(const std::string& server_id); + + net::ServerBoundCertStore::ServerBoundCertList server_bound_cert_list_; + + // Indicates whether or not we're currently fetching information: + // it's true when StartFetching() is called in the UI thread, and it's reset + // after we notify the callback in the UI thread. + // This only mutates on the UI thread. + bool is_fetching_; + + scoped_refptr<net::URLRequestContextGetter> request_context_getter_; + + // This only mutates on the UI thread. + FetchResultCallback completion_callback_; + + DISALLOW_COPY_AND_ASSIGN(BrowsingDataServerBoundCertHelperImpl); +}; + +BrowsingDataServerBoundCertHelperImpl:: +BrowsingDataServerBoundCertHelperImpl(Profile* profile) + : is_fetching_(false), + request_context_getter_(profile->GetRequestContext()) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); +} + +BrowsingDataServerBoundCertHelperImpl:: +~BrowsingDataServerBoundCertHelperImpl() { +} + +void BrowsingDataServerBoundCertHelperImpl::StartFetching( + const FetchResultCallback& callback) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + DCHECK(!is_fetching_); + DCHECK(!callback.is_null()); + DCHECK(completion_callback_.is_null()); + is_fetching_ = true; + completion_callback_ = callback; + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&BrowsingDataServerBoundCertHelperImpl::FetchOnIOThread, + this)); +} + +void BrowsingDataServerBoundCertHelperImpl::DeleteServerBoundCert( + const std::string& server_id) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&BrowsingDataServerBoundCertHelperImpl::DeleteOnIOThread, + this, server_id)); +} + +void BrowsingDataServerBoundCertHelperImpl::FetchOnIOThread() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + net::ServerBoundCertStore* cert_store = + request_context_getter_->GetURLRequestContext()-> + server_bound_cert_service()->GetCertStore(); + if (cert_store) { + server_bound_cert_list_.clear(); + cert_store->GetAllServerBoundCerts(&server_bound_cert_list_); + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&BrowsingDataServerBoundCertHelperImpl::NotifyInUIThread, + this)); + } +} + +void BrowsingDataServerBoundCertHelperImpl::NotifyInUIThread() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + DCHECK(is_fetching_); + is_fetching_ = false; + completion_callback_.Run(server_bound_cert_list_); + completion_callback_.Reset(); +} + +void BrowsingDataServerBoundCertHelperImpl::DeleteOnIOThread( + const std::string& server_id) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + net::ServerBoundCertStore* cert_store = + request_context_getter_->GetURLRequestContext()-> + server_bound_cert_service()->GetCertStore(); + if (cert_store) + cert_store->DeleteServerBoundCert(server_id); +} + +} // namespace + +// static +BrowsingDataServerBoundCertHelper* +BrowsingDataServerBoundCertHelper::Create(Profile* profile) { + return new BrowsingDataServerBoundCertHelperImpl(profile); +} + +CannedBrowsingDataServerBoundCertHelper:: +CannedBrowsingDataServerBoundCertHelper() {} + +CannedBrowsingDataServerBoundCertHelper:: +~CannedBrowsingDataServerBoundCertHelper() {} + +CannedBrowsingDataServerBoundCertHelper* +CannedBrowsingDataServerBoundCertHelper::Clone() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + CannedBrowsingDataServerBoundCertHelper* clone = + new CannedBrowsingDataServerBoundCertHelper(); + + clone->server_bound_cert_map_ = server_bound_cert_map_; + return clone; +} + +void CannedBrowsingDataServerBoundCertHelper::AddServerBoundCert( + const net::ServerBoundCertStore::ServerBoundCert& server_bound_cert) { + server_bound_cert_map_[server_bound_cert.server_identifier()] = + server_bound_cert; +} + +void CannedBrowsingDataServerBoundCertHelper::Reset() { + server_bound_cert_map_.clear(); +} + +bool CannedBrowsingDataServerBoundCertHelper::empty() const { + return server_bound_cert_map_.empty(); +} + +void CannedBrowsingDataServerBoundCertHelper::StartFetching( + const FetchResultCallback& callback) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + if (callback.is_null()) + return; + // We post a task to emulate async fetching behavior. + completion_callback_ = callback; + MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&CannedBrowsingDataServerBoundCertHelper::FinishFetching, + this)); +} + +void CannedBrowsingDataServerBoundCertHelper::FinishFetching() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + net::ServerBoundCertStore::ServerBoundCertList cert_list; + for (ServerBoundCertMap::iterator i = server_bound_cert_map_.begin(); + i != server_bound_cert_map_.end(); ++i) + cert_list.push_back(i->second); + completion_callback_.Run(cert_list); +} + +void CannedBrowsingDataServerBoundCertHelper::DeleteServerBoundCert( + const std::string& server_id) { + NOTREACHED(); +} diff --git a/chrome/browser/browsing_data_server_bound_cert_helper.h b/chrome/browser/browsing_data_server_bound_cert_helper.h new file mode 100644 index 0000000..0963082 --- /dev/null +++ b/chrome/browser/browsing_data_server_bound_cert_helper.h @@ -0,0 +1,89 @@ +// 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. + +#ifndef CHROME_BROWSER_BROWSING_DATA_SERVER_BOUND_CERT_HELPER_H_ +#define CHROME_BROWSER_BROWSING_DATA_SERVER_BOUND_CERT_HELPER_H_ +#pragma once + +#include <map> +#include <string> + +#include "base/callback.h" +#include "net/base/server_bound_cert_store.h" + +class Profile; + +// BrowsingDataServerBoundCertHelper is an interface for classes dealing with +// aggregating and deleting browsing data stored in the server bound cert store. +// A client of this class need to call StartFetching from the UI thread to +// initiate the flow, and it'll be notified by the callback in its UI thread at +// some later point. +class BrowsingDataServerBoundCertHelper + : public base::RefCountedThreadSafe<BrowsingDataServerBoundCertHelper> { + public: + + // Create a BrowsingDataServerBoundCertHelper instance for the given + // |profile|. + static BrowsingDataServerBoundCertHelper* Create(Profile* profile); + + typedef base::Callback< + void(const net::ServerBoundCertStore::ServerBoundCertList&)> + FetchResultCallback; + + // Starts the fetching process, which will notify its completion via + // callback. + // This must be called only in the UI thread. + virtual void StartFetching(const FetchResultCallback& callback) = 0; + // Requests a single server bound cert to be deleted. This must be called in + // the UI thread. + virtual void DeleteServerBoundCert(const std::string& server_id) = 0; + + protected: + friend class base::RefCountedThreadSafe<BrowsingDataServerBoundCertHelper>; + virtual ~BrowsingDataServerBoundCertHelper() {} +}; + +// This class is a thin wrapper around BrowsingDataServerBoundCertHelper that +// does not fetch its information from the ServerBoundCertService, but gets them +// passed as a parameter during construction. +class CannedBrowsingDataServerBoundCertHelper + : public BrowsingDataServerBoundCertHelper { + public: + CannedBrowsingDataServerBoundCertHelper(); + + // Return a copy of the ServerBoundCert helper. Only one consumer can use the + // StartFetching method at a time, so we need to create a copy of the helper + // every time we instantiate a cookies tree model for it. + CannedBrowsingDataServerBoundCertHelper* Clone(); + + // Add an ServerBoundCert to the set of canned server bound certs that is + // returned by this helper. + void AddServerBoundCert( + const net::ServerBoundCertStore::ServerBoundCert& server_bound_cert); + + // Clears the list of canned server bound certs. + void Reset(); + + // True if no ServerBoundCerts are currently stored. + bool empty() const; + + // BrowsingDataServerBoundCertHelper methods. + virtual void StartFetching(const FetchResultCallback& callback) OVERRIDE; + virtual void DeleteServerBoundCert(const std::string& server_id) OVERRIDE; + + private: + virtual ~CannedBrowsingDataServerBoundCertHelper(); + + void FinishFetching(); + + typedef std::map<std::string, net::ServerBoundCertStore::ServerBoundCert> + ServerBoundCertMap; + ServerBoundCertMap server_bound_cert_map_; + + FetchResultCallback completion_callback_; + + DISALLOW_COPY_AND_ASSIGN(CannedBrowsingDataServerBoundCertHelper); +}; + +#endif // CHROME_BROWSER_BROWSING_DATA_SERVER_BOUND_CERT_HELPER_H_ diff --git a/chrome/browser/browsing_data_server_bound_cert_helper_unittest.cc b/chrome/browser/browsing_data_server_bound_cert_helper_unittest.cc new file mode 100644 index 0000000..1307ba6 --- /dev/null +++ b/chrome/browser/browsing_data_server_bound_cert_helper_unittest.cc @@ -0,0 +1,159 @@ +// 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. + +#include "chrome/browser/browsing_data_server_bound_cert_helper.h" + +#include "base/bind.h" +#include "base/message_loop.h" +#include "base/synchronization/waitable_event.h" +#include "chrome/test/base/testing_profile.h" +#include "content/test/test_browser_thread.h" +#include "net/base/server_bound_cert_service.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" + +using content::BrowserThread; + +class BrowsingDataServerBoundCertHelperTest : public testing::Test { + public: + virtual void SetUp() { + ui_thread_.reset(new content::TestBrowserThread(BrowserThread::UI, + &message_loop_)); + io_thread_.reset(new content::TestBrowserThread(BrowserThread::IO, + &message_loop_)); + testing_profile_.reset(new TestingProfile()); + testing_profile_->CreateRequestContext(); + } + + void CreateCertsForTest() { + scoped_refptr<net::URLRequestContext> context = + testing_profile_->GetRequestContext()->GetURLRequestContext(); + net::ServerBoundCertStore* cert_store = + context->server_bound_cert_service()->GetCertStore(); + cert_store->SetServerBoundCert("https://www.google.com:443", + net::CLIENT_CERT_RSA_SIGN, + base::Time(), base::Time(), + "key", "cert"); + cert_store->SetServerBoundCert("https://www.youtube.com:443", + net::CLIENT_CERT_RSA_SIGN, + base::Time(), base::Time(), + "key", "cert"); + } + + void FetchCallback( + const net::ServerBoundCertStore::ServerBoundCertList& certs) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + server_bound_cert_list_ = certs; + MessageLoop::current()->Quit(); + } + + protected: + MessageLoop message_loop_; + scoped_ptr<content::TestBrowserThread> ui_thread_; + scoped_ptr<content::TestBrowserThread> io_thread_; + scoped_ptr<TestingProfile> testing_profile_; + + net::ServerBoundCertStore::ServerBoundCertList server_bound_cert_list_; +}; + +TEST_F(BrowsingDataServerBoundCertHelperTest, FetchData) { + CreateCertsForTest(); + scoped_refptr<BrowsingDataServerBoundCertHelper> helper( + BrowsingDataServerBoundCertHelper::Create(testing_profile_.get())); + + helper->StartFetching( + base::Bind(&BrowsingDataServerBoundCertHelperTest::FetchCallback, + base::Unretained(this))); + + // Blocks until BrowsingDataServerBoundCertHelperTest::FetchCallback is + // notified. + MessageLoop::current()->Run(); + + ASSERT_EQ(2UL, server_bound_cert_list_.size()); + net::ServerBoundCertStore::ServerBoundCertList::const_iterator it = + server_bound_cert_list_.begin(); + + // Correct because fetching server_bound_cert_list_ will get them out in the + // same order CreateCertsForTest put them in. + ASSERT_TRUE(it != server_bound_cert_list_.end()); + EXPECT_EQ("https://www.google.com:443", it->server_identifier()); + + ASSERT_TRUE(++it != server_bound_cert_list_.end()); + EXPECT_EQ("https://www.youtube.com:443", it->server_identifier()); + + ASSERT_TRUE(++it == server_bound_cert_list_.end()); +} + +TEST_F(BrowsingDataServerBoundCertHelperTest, DeleteCert) { + CreateCertsForTest(); + scoped_refptr<BrowsingDataServerBoundCertHelper> helper( + BrowsingDataServerBoundCertHelper::Create(testing_profile_.get())); + + helper->DeleteServerBoundCert("https://www.google.com:443"); + + helper->StartFetching( + base::Bind(&BrowsingDataServerBoundCertHelperTest::FetchCallback, + base::Unretained(this))); + MessageLoop::current()->Run(); + + ASSERT_EQ(1UL, server_bound_cert_list_.size()); + net::ServerBoundCertStore::ServerBoundCertList::const_iterator it = + server_bound_cert_list_.begin(); + + ASSERT_TRUE(it != server_bound_cert_list_.end()); + EXPECT_EQ("https://www.youtube.com:443", it->server_identifier()); + + ASSERT_TRUE(++it == server_bound_cert_list_.end()); + + helper->DeleteServerBoundCert("https://www.youtube.com:443"); + + helper->StartFetching( + base::Bind(&BrowsingDataServerBoundCertHelperTest::FetchCallback, + base::Unretained(this))); + MessageLoop::current()->Run(); + ASSERT_EQ(0UL, server_bound_cert_list_.size()); +} + +TEST_F(BrowsingDataServerBoundCertHelperTest, CannedUnique) { + std::string origin = "https://www.google.com:443"; + + scoped_refptr<CannedBrowsingDataServerBoundCertHelper> helper( + new CannedBrowsingDataServerBoundCertHelper()); + + ASSERT_TRUE(helper->empty()); + helper->AddServerBoundCert(net::ServerBoundCertStore::ServerBoundCert( + origin, net::CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "key", + "cert")); + helper->AddServerBoundCert(net::ServerBoundCertStore::ServerBoundCert( + origin, net::CLIENT_CERT_ECDSA_SIGN, base::Time(), base::Time(), "key", + "cert")); + + helper->StartFetching( + base::Bind(&BrowsingDataServerBoundCertHelperTest::FetchCallback, + base::Unretained(this))); + MessageLoop::current()->Run(); + + ASSERT_EQ(1UL, server_bound_cert_list_.size()); + net::ServerBoundCertStore::ServerBoundCert& cert = + server_bound_cert_list_.front(); + + EXPECT_EQ("https://www.google.com:443", cert.server_identifier()); + EXPECT_EQ(net::CLIENT_CERT_ECDSA_SIGN, cert.type()); +} + +TEST_F(BrowsingDataServerBoundCertHelperTest, CannedEmpty) { + std::string origin = "https://www.google.com"; + + scoped_refptr<CannedBrowsingDataServerBoundCertHelper> helper( + new CannedBrowsingDataServerBoundCertHelper()); + + ASSERT_TRUE(helper->empty()); + helper->AddServerBoundCert(net::ServerBoundCertStore::ServerBoundCert( + origin, net::CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "key", + "cert")); + ASSERT_FALSE(helper->empty()); + helper->Reset(); + ASSERT_TRUE(helper->empty()); +} diff --git a/chrome/browser/content_settings/local_shared_objects_container.cc b/chrome/browser/content_settings/local_shared_objects_container.cc index f196230..e5e59e6f 100644 --- a/chrome/browser/content_settings/local_shared_objects_container.cc +++ b/chrome/browser/content_settings/local_shared_objects_container.cc @@ -10,6 +10,7 @@ #include "chrome/browser/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data_indexed_db_helper.h" #include "chrome/browser/browsing_data_local_storage_helper.h" +#include "chrome/browser/browsing_data_server_bound_cert_helper.h" #include "chrome/browser/profiles/profile.h" LocalSharedObjectsContainer::LocalSharedObjectsContainer(Profile* profile) @@ -19,6 +20,7 @@ LocalSharedObjectsContainer::LocalSharedObjectsContainer(Profile* profile) file_systems_(new CannedBrowsingDataFileSystemHelper(profile)), indexed_dbs_(new CannedBrowsingDataIndexedDBHelper()), local_storages_(new CannedBrowsingDataLocalStorageHelper(profile)), + server_bound_certs_(new CannedBrowsingDataServerBoundCertHelper()), session_storages_(new CannedBrowsingDataLocalStorageHelper(profile)) { } @@ -32,6 +34,7 @@ void LocalSharedObjectsContainer::Reset() { file_systems_->Reset(); indexed_dbs_->Reset(); local_storages_->Reset(); + server_bound_certs_->Reset(); session_storages_->Reset(); } @@ -42,5 +45,6 @@ bool LocalSharedObjectsContainer::IsEmpty() const { file_systems_->empty() && indexed_dbs_->empty() && local_storages_->empty() && + server_bound_certs_->empty() && session_storages_->empty(); } diff --git a/chrome/browser/content_settings/local_shared_objects_container.h b/chrome/browser/content_settings/local_shared_objects_container.h index f47395b..6efedf0 100644 --- a/chrome/browser/content_settings/local_shared_objects_container.h +++ b/chrome/browser/content_settings/local_shared_objects_container.h @@ -14,6 +14,7 @@ class CannedBrowsingDataDatabaseHelper; class CannedBrowsingDataFileSystemHelper; class CannedBrowsingDataIndexedDBHelper; class CannedBrowsingDataLocalStorageHelper; +class CannedBrowsingDataServerBoundCertHelper; class Profile; class LocalSharedObjectsContainer { @@ -46,6 +47,9 @@ class LocalSharedObjectsContainer { CannedBrowsingDataLocalStorageHelper* local_storages() const { return local_storages_; } + CannedBrowsingDataServerBoundCertHelper* server_bound_certs() const { + return server_bound_certs_; + } CannedBrowsingDataLocalStorageHelper* session_storages() const { return session_storages_; } @@ -57,6 +61,7 @@ class LocalSharedObjectsContainer { scoped_refptr<CannedBrowsingDataFileSystemHelper> file_systems_; scoped_refptr<CannedBrowsingDataIndexedDBHelper> indexed_dbs_; scoped_refptr<CannedBrowsingDataLocalStorageHelper> local_storages_; + scoped_refptr<CannedBrowsingDataServerBoundCertHelper> server_bound_certs_; scoped_refptr<CannedBrowsingDataLocalStorageHelper> session_storages_; DISALLOW_COPY_AND_ASSIGN(LocalSharedObjectsContainer); diff --git a/chrome/browser/cookies_tree_model.cc b/chrome/browser/cookies_tree_model.cc index f960744..d90bdfb 100644 --- a/chrome/browser/cookies_tree_model.cc +++ b/chrome/browser/cookies_tree_model.cc @@ -13,6 +13,7 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "chrome/browser/browsing_data_cookie_helper.h" +#include "chrome/browser/browsing_data_server_bound_cert_helper.h" #include "chrome/browser/content_settings/cookie_settings.h" #include "chrome/browser/extensions/extension_service.h" #include "grit/generated_resources.h" @@ -297,6 +298,29 @@ CookieTreeNode::DetailedInfo CookieTreeQuotaNode::GetDetailedInfo() const { } /////////////////////////////////////////////////////////////////////////////// +// CookieTreeServerBoundCertNode, public: + +CookieTreeServerBoundCertNode::CookieTreeServerBoundCertNode( + net::ServerBoundCertStore::ServerBoundCertList::iterator cert) + : CookieTreeNode(ASCIIToUTF16(cert->server_identifier())), + server_bound_cert_(cert) { +} + +CookieTreeServerBoundCertNode::~CookieTreeServerBoundCertNode() {} + +void CookieTreeServerBoundCertNode::DeleteStoredObjects() { + GetModel()->server_bound_cert_helper_->DeleteServerBoundCert( + server_bound_cert_->server_identifier()); + GetModel()->server_bound_cert_list_.erase(server_bound_cert_); +} + +CookieTreeNode::DetailedInfo +CookieTreeServerBoundCertNode::GetDetailedInfo() const { + return DetailedInfo(parent()->parent()->GetTitle()).InitServerBoundCert( + &*server_bound_cert_); +} + +/////////////////////////////////////////////////////////////////////////////// // CookieTreeRootNode, public: CookieTreeRootNode::CookieTreeRootNode(CookiesTreeModel* model) @@ -355,6 +379,7 @@ CookieTreeOriginNode::CookieTreeOriginNode(const GURL& url) indexed_dbs_child_(NULL), file_systems_child_(NULL), quota_child_(NULL), + server_bound_certs_child_(NULL), url_(url) {} CookieTreeOriginNode::~CookieTreeOriginNode() {} @@ -430,6 +455,15 @@ CookieTreeQuotaNode* CookieTreeOriginNode::UpdateOrCreateQuotaNode( return quota_child_; } +CookieTreeServerBoundCertsNode* +CookieTreeOriginNode::GetOrCreateServerBoundCertsNode() { + if (server_bound_certs_child_) + return server_bound_certs_child_; + server_bound_certs_child_ = new CookieTreeServerBoundCertsNode; + AddChildSortedByTitle(server_bound_certs_child_); + return server_bound_certs_child_; +} + void CookieTreeOriginNode::CreateContentException( CookieSettings* cookie_settings, ContentSetting setting) const { DCHECK(setting == CONTENT_SETTING_ALLOW || @@ -551,6 +585,22 @@ CookieTreeFileSystemsNode::GetDetailedInfo() const { } /////////////////////////////////////////////////////////////////////////////// +// CookieTreeServerBoundCertsNode, public: + +CookieTreeServerBoundCertsNode::CookieTreeServerBoundCertsNode() + : CookieTreeNode( + l10n_util::GetStringUTF16(IDS_COOKIES_SERVER_BOUND_CERTS)) { +} + +CookieTreeServerBoundCertsNode::~CookieTreeServerBoundCertsNode() {} + +CookieTreeNode::DetailedInfo +CookieTreeServerBoundCertsNode::GetDetailedInfo() const { + return DetailedInfo(parent()->GetTitle()).Init( + DetailedInfo::TYPE_SERVER_BOUND_CERTS); +} + +/////////////////////////////////////////////////////////////////////////////// // CookieTreeNode, protected bool CookieTreeNode::NodeTitleComparator::operator() ( @@ -584,6 +634,7 @@ CookiesTreeModel::CookiesTreeModel( BrowsingDataIndexedDBHelper* indexed_db_helper, BrowsingDataFileSystemHelper* file_system_helper, BrowsingDataQuotaHelper* quota_helper, + BrowsingDataServerBoundCertHelper* server_bound_cert_helper, bool use_cookie_source) : ALLOW_THIS_IN_INITIALIZER_LIST(ui::TreeNodeModel<CookieTreeNode>( new CookieTreeRootNode(this))), @@ -595,6 +646,7 @@ CookiesTreeModel::CookiesTreeModel( indexed_db_helper_(indexed_db_helper), file_system_helper_(file_system_helper), quota_helper_(quota_helper), + server_bound_cert_helper_(server_bound_cert_helper), batch_update_(0), use_cookie_source_(use_cookie_source), ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { @@ -641,6 +693,12 @@ CookiesTreeModel::CookiesTreeModel( base::Bind(&CookiesTreeModel::OnQuotaModelInfoLoaded, weak_ptr_factory_.GetWeakPtr())); } + + if (server_bound_cert_helper_) { + server_bound_cert_helper_->StartFetching( + base::Bind(&CookiesTreeModel::OnServerBoundCertModelInfoLoaded, + base::Unretained(this))); + } } CookiesTreeModel::~CookiesTreeModel() {} @@ -684,6 +742,8 @@ int CookiesTreeModel::GetIconIndex(ui::TreeModelNode* node) { return DATABASE; // ditto case CookieTreeNode::DetailedInfo::TYPE_QUOTA: return -1; + case CookieTreeNode::DetailedInfo::TYPE_SERVER_BOUND_CERT: + return COOKIE; // It's kinda like a cookie? default: break; } @@ -725,6 +785,7 @@ void CookiesTreeModel::UpdateSearchResults(const std::wstring& filter) { PopulateIndexedDBInfoWithFilter(filter); PopulateFileSystemInfoWithFilter(filter); PopulateQuotaInfoWithFilter(filter); + PopulateServerBoundCertInfoWithFilter(filter); NotifyObserverTreeNodeChanged(root); NotifyObserverEndBatch(); } @@ -1027,6 +1088,45 @@ void CookiesTreeModel::PopulateQuotaInfoWithFilter( NotifyObserverEndBatch(); } +void CookiesTreeModel::OnServerBoundCertModelInfoLoaded( + const ServerBoundCertList& cert_list) { + server_bound_cert_list_ = cert_list; + PopulateServerBoundCertInfoWithFilter(std::wstring()); +} + +void CookiesTreeModel::PopulateServerBoundCertInfoWithFilter( + const std::wstring& filter) { + if (server_bound_cert_list_.empty()) + return; + CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); + NotifyObserverBeginBatch(); + for (ServerBoundCertList::iterator cert_info = + server_bound_cert_list_.begin(); + cert_info != server_bound_cert_list_.end(); + ++cert_info) { + GURL origin(cert_info->server_identifier()); + if (!origin.is_valid()) { + // Domain Bound Cert. Make a valid URL to satisfy the + // CookieTreeRootNode::GetOrCreateOriginNode interface. + origin = GURL(std::string(chrome::kHttpsScheme) + + chrome::kStandardSchemeSeparator + + cert_info->server_identifier() + "/"); + } + std::wstring title = CookieTreeOriginNode::TitleForUrl(origin); + + if (!filter.size() || title.find(filter) != std::wstring::npos) { + CookieTreeOriginNode* origin_node = + root->GetOrCreateOriginNode(origin); + CookieTreeServerBoundCertsNode* server_bound_certs_node = + origin_node->GetOrCreateServerBoundCertsNode(); + server_bound_certs_node->AddServerBoundCertNode( + new CookieTreeServerBoundCertNode(cert_info)); + } + } + NotifyObserverTreeNodeChanged(root); + NotifyObserverEndBatch(); +} + void CookiesTreeModel::NotifyObserverBeginBatch() { // Only notify the model once if we're batching in a nested manner. if (batch_update_++ == 0) { diff --git a/chrome/browser/cookies_tree_model.h b/chrome/browser/cookies_tree_model.h index ee2cb55..aec5a5f 100644 --- a/chrome/browser/cookies_tree_model.h +++ b/chrome/browser/cookies_tree_model.h @@ -25,10 +25,12 @@ #include "chrome/browser/browsing_data_local_storage_helper.h" #include "chrome/browser/browsing_data_quota_helper.h" #include "chrome/common/content_settings.h" +#include "net/base/server_bound_cert_store.h" #include "net/cookies/cookie_monster.h" #include "ui/base/models/tree_node_model.h" class BrowsingDataCookieHelper; +class BrowsingDataServerBoundCertHelper; class CookieSettings; class CookiesTreeModel; class CookieTreeAppCacheNode; @@ -41,6 +43,8 @@ class CookieTreeFileSystemsNode; class CookieTreeFileSystemNode; class CookieTreeLocalStorageNode; class CookieTreeLocalStoragesNode; +class CookieTreeServerBoundCertNode; +class CookieTreeServerBoundCertsNode; class CookieTreeQuotaNode; class CookieTreeSessionStorageNode; class CookieTreeSessionStoragesNode; @@ -78,6 +82,8 @@ class CookieTreeNode : public ui::TreeNode<CookieTreeNode> { TYPE_FILE_SYSTEMS, // This is used for CookieTreeFileSystemsNode. TYPE_FILE_SYSTEM, // This is used for CookieTreeFileSystemNode. TYPE_QUOTA, // This is used for CookieTreeQuotaNode. + TYPE_SERVER_BOUND_CERTS, // Used for CookieTreeServerBoundCertsNode. + TYPE_SERVER_BOUND_CERT, // Used for CookieTreeServerBoundCertNode. }; // TODO(viettrungluu): Figure out whether we want to store |origin| as a @@ -92,7 +98,8 @@ class CookieTreeNode : public ui::TreeNode<CookieTreeNode> { appcache_info(NULL), indexed_db_info(NULL), file_system_info(NULL), - quota_info(NULL) {} + quota_info(NULL), + server_bound_cert(NULL) {} DetailedInfo& Init(NodeType type) { DCHECK_EQ(TYPE_NONE, node_type); @@ -157,6 +164,13 @@ class CookieTreeNode : public ui::TreeNode<CookieTreeNode> { return *this; } + DetailedInfo& InitServerBoundCert( + const net::ServerBoundCertStore::ServerBoundCert* server_bound_cert) { + Init(TYPE_SERVER_BOUND_CERT); + this->server_bound_cert = server_bound_cert; + return *this; + } + string16 origin; NodeType node_type; const net::CookieMonster::CanonicalCookie* cookie; @@ -168,6 +182,7 @@ class CookieTreeNode : public ui::TreeNode<CookieTreeNode> { const BrowsingDataIndexedDBHelper::IndexedDBInfo* indexed_db_info; const BrowsingDataFileSystemHelper::FileSystemInfo* file_system_info; const BrowsingDataQuotaHelper::QuotaInfo* quota_info; + const net::ServerBoundCertStore::ServerBoundCert* server_bound_cert; }; CookieTreeNode() {} @@ -238,6 +253,7 @@ class CookieTreeOriginNode : public CookieTreeNode { CookieTreeAppCachesNode* GetOrCreateAppCachesNode(); CookieTreeIndexedDBsNode* GetOrCreateIndexedDBsNode(); CookieTreeFileSystemsNode* GetOrCreateFileSystemsNode(); + CookieTreeServerBoundCertsNode* GetOrCreateServerBoundCertsNode(); CookieTreeQuotaNode* UpdateOrCreateQuotaNode( std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info); @@ -263,6 +279,7 @@ class CookieTreeOriginNode : public CookieTreeNode { CookieTreeIndexedDBsNode* indexed_dbs_child_; CookieTreeFileSystemsNode* file_systems_child_; CookieTreeQuotaNode* quota_child_; + CookieTreeServerBoundCertsNode* server_bound_certs_child_; // The URL for which this node was initially created. GURL url_; @@ -559,6 +576,44 @@ class CookieTreeQuotaNode : public CookieTreeNode { DISALLOW_COPY_AND_ASSIGN(CookieTreeQuotaNode); }; +// CookieTreeServerBoundCertNode --------------------------------------------- +class CookieTreeServerBoundCertNode : public CookieTreeNode { + public: + friend class CookieTreeServerBoundCertsNode; + + // The iterator should remain valid at least as long as the + // CookieTreeServerBoundCertNode is valid. + explicit CookieTreeServerBoundCertNode( + net::ServerBoundCertStore::ServerBoundCertList::iterator cert); + virtual ~CookieTreeServerBoundCertNode(); + + // CookieTreeNode methods: + virtual void DeleteStoredObjects() OVERRIDE; + virtual DetailedInfo GetDetailedInfo() const OVERRIDE; + + private: + // server_bound_cert_ is expected to remain valid as long as the + // CookieTreeServerBoundCertNode is valid. + net::ServerBoundCertStore::ServerBoundCertList::iterator server_bound_cert_; + + DISALLOW_COPY_AND_ASSIGN(CookieTreeServerBoundCertNode); +}; + +class CookieTreeServerBoundCertsNode : public CookieTreeNode { + public: + CookieTreeServerBoundCertsNode(); + virtual ~CookieTreeServerBoundCertsNode(); + + virtual DetailedInfo GetDetailedInfo() const OVERRIDE; + + void AddServerBoundCertNode(CookieTreeServerBoundCertNode* child) { + AddChildSortedByTitle(child); + } + + private: + DISALLOW_COPY_AND_ASSIGN(CookieTreeServerBoundCertsNode); +}; + // CookiesTreeModel ----------------------------------------------------------- class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> { public: @@ -582,6 +637,7 @@ class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> { BrowsingDataIndexedDBHelper* indexed_db_helper, BrowsingDataFileSystemHelper* file_system_helper, BrowsingDataQuotaHelper* quota_helper, + BrowsingDataServerBoundCertHelper* server_bound_cert_helper, bool use_cookie_source); virtual ~CookiesTreeModel(); @@ -627,6 +683,7 @@ class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> { typedef std::list<BrowsingDataFileSystemHelper::FileSystemInfo> FileSystemInfoList; typedef std::list<BrowsingDataQuotaHelper::QuotaInfo> QuotaInfoArray; + typedef net::ServerBoundCertStore::ServerBoundCertList ServerBoundCertList; void OnAppCacheModelInfoLoaded(); void OnCookiesModelInfoLoaded(const net::CookieList& cookie_list); @@ -640,6 +697,7 @@ class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> { void OnFileSystemModelInfoLoaded( const FileSystemInfoList& file_system_info); void OnQuotaModelInfoLoaded(const QuotaInfoArray& quota_info); + void OnServerBoundCertModelInfoLoaded(const ServerBoundCertList& cert_list); void PopulateAppCacheInfoWithFilter(const std::wstring& filter); void PopulateCookieInfoWithFilter(const std::wstring& filter); @@ -649,6 +707,7 @@ class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> { void PopulateIndexedDBInfoWithFilter(const std::wstring& filter); void PopulateFileSystemInfoWithFilter(const std::wstring& filter); void PopulateQuotaInfoWithFilter(const std::wstring& filter); + void PopulateServerBoundCertInfoWithFilter(const std::wstring& filter); void NotifyObserverBeginBatch(); void NotifyObserverEndBatch(); @@ -661,6 +720,7 @@ class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> { scoped_refptr<BrowsingDataIndexedDBHelper> indexed_db_helper_; scoped_refptr<BrowsingDataFileSystemHelper> file_system_helper_; scoped_refptr<BrowsingDataQuotaHelper> quota_helper_; + scoped_refptr<BrowsingDataServerBoundCertHelper> server_bound_cert_helper_; std::map<GURL, std::list<appcache::AppCacheInfo> > appcache_info_; CookieList cookie_list_; @@ -670,6 +730,7 @@ class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> { IndexedDBInfoList indexed_db_info_list_; FileSystemInfoList file_system_info_list_; QuotaInfoArray quota_info_list_; + ServerBoundCertList server_bound_cert_list_; // The CookiesTreeModel maintains a separate list of observers that are // specifically of the type CookiesTreeModel::Observer. @@ -694,6 +755,7 @@ class CookiesTreeModel : public ui::TreeNodeModel<CookieTreeNode> { friend class CookieTreeIndexedDBNode; friend class CookieTreeFileSystemNode; friend class CookieTreeQuotaNode; + friend class CookieTreeServerBoundCertNode; DISALLOW_COPY_AND_ASSIGN(CookiesTreeModel); }; diff --git a/chrome/browser/cookies_tree_model_unittest.cc b/chrome/browser/cookies_tree_model_unittest.cc index d98f041..2980767 100644 --- a/chrome/browser/cookies_tree_model_unittest.cc +++ b/chrome/browser/cookies_tree_model_unittest.cc @@ -17,6 +17,7 @@ #include "chrome/browser/mock_browsing_data_indexed_db_helper.h" #include "chrome/browser/mock_browsing_data_local_storage_helper.h" #include "chrome/browser/mock_browsing_data_quota_helper.h" +#include "chrome/browser/mock_browsing_data_server_bound_cert_helper.h" #include "chrome/test/base/testing_profile.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_types.h" @@ -65,9 +66,12 @@ class CookiesTreeModelTest : public testing::Test { new MockBrowsingDataFileSystemHelper(profile_.get()); mock_browsing_data_quota_helper_ = new MockBrowsingDataQuotaHelper(profile_.get()); + mock_browsing_data_server_bound_cert_helper_ = + new MockBrowsingDataServerBoundCertHelper(); } virtual void TearDown() OVERRIDE { + mock_browsing_data_server_bound_cert_helper_ = NULL; mock_browsing_data_quota_helper_ = NULL; mock_browsing_data_file_system_helper_ = NULL; mock_browsing_data_indexed_db_helper_ = NULL; @@ -88,6 +92,7 @@ class CookiesTreeModelTest : public testing::Test { mock_browsing_data_indexed_db_helper_, mock_browsing_data_file_system_helper_, mock_browsing_data_quota_helper_, + mock_browsing_data_server_bound_cert_helper_, false); mock_browsing_data_cookie_helper_-> AddCookieSamples(GURL("http://foo1"), "A=1"); @@ -108,6 +113,11 @@ class CookiesTreeModelTest : public testing::Test { mock_browsing_data_file_system_helper_->Notify(); mock_browsing_data_quota_helper_->AddQuotaSamples(); mock_browsing_data_quota_helper_->Notify(); + mock_browsing_data_server_bound_cert_helper_->AddServerBoundCertSample( + "sbc1"); + mock_browsing_data_server_bound_cert_helper_->AddServerBoundCertSample( + "sbc2"); + mock_browsing_data_server_bound_cert_helper_->Notify(); { SCOPED_TRACE("Initial State 3 cookies, 2 databases, 2 local storages, " "2 session storages, 2 indexed DBs, 3 filesystems, " @@ -125,8 +135,10 @@ class CookiesTreeModelTest : public testing::Test { // idbhost1 -> indexeddb -> http://idbhost1:1/, // idbhost2 -> indexeddb -> http://idbhost2:2/, // quotahost1 -> quotahost1, - // quotahost2 -> quotahost2. - EXPECT_EQ(45, cookies_model->GetRoot()->GetTotalNodeCount()); + // quotahost2 -> quotahost2, + // sbc1 -> sbcerts -> sbc1, + // sbc2 -> sbcerts -> sbc2. + EXPECT_EQ(51, cookies_model->GetRoot()->GetTotalNodeCount()); EXPECT_EQ("A,B,C", GetDisplayedCookies(cookies_model)); EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model)); EXPECT_EQ("http://host1:1/,http://host2:2/", @@ -139,6 +151,8 @@ class CookiesTreeModelTest : public testing::Test { GetDisplayedFileSystems(cookies_model)); EXPECT_EQ("quotahost1,quotahost2", GetDisplayedQuotas(cookies_model)); + EXPECT_EQ("sbc1,sbc2", + GetDisplayedServerBoundCerts(cookies_model)); } return cookies_model; } @@ -174,6 +188,9 @@ class CookiesTreeModelTest : public testing::Test { ","; case CookieTreeNode::DetailedInfo::TYPE_QUOTA: return node->GetDetailedInfo().quota_info->host + ","; + case CookieTreeNode::DetailedInfo::TYPE_SERVER_BOUND_CERT: + return node->GetDetailedInfo( + ).server_bound_cert->server_identifier() + ","; default: return ""; } @@ -270,6 +287,11 @@ class CookiesTreeModelTest : public testing::Test { CookieTreeNode::DetailedInfo::TYPE_QUOTA); } + std::string GetDisplayedServerBoundCerts(CookiesTreeModel* cookies_model) { + return GetDisplayedNodes( + cookies_model, CookieTreeNode::DetailedInfo::TYPE_SERVER_BOUND_CERT); + } + // Do not call on the root. void DeleteStoredObjects(CookieTreeNode* node) { node->DeleteStoredObjects(); @@ -301,6 +323,8 @@ class CookiesTreeModelTest : public testing::Test { mock_browsing_data_file_system_helper_; scoped_refptr<MockBrowsingDataQuotaHelper> mock_browsing_data_quota_helper_; + scoped_refptr<MockBrowsingDataServerBoundCertHelper> + mock_browsing_data_server_bound_cert_helper_; }; TEST_F(CookiesTreeModelTest, RemoveAll) { @@ -324,6 +348,8 @@ TEST_F(CookiesTreeModelTest, RemoveAll) { GetDisplayedFileSystems(cookies_model.get())); EXPECT_EQ("quotahost1,quotahost2", GetDisplayedQuotas(cookies_model.get())); + EXPECT_EQ("sbc1,sbc2", + GetDisplayedServerBoundCerts(cookies_model.get())); } mock_browsing_data_cookie_helper_->Reset(); @@ -350,6 +376,7 @@ TEST_F(CookiesTreeModelTest, RemoveAll) { EXPECT_FALSE(mock_browsing_data_session_storage_helper_->AllDeleted()); EXPECT_TRUE(mock_browsing_data_indexed_db_helper_->AllDeleted()); EXPECT_TRUE(mock_browsing_data_file_system_helper_->AllDeleted()); + EXPECT_TRUE(mock_browsing_data_server_bound_cert_helper_->AllDeleted()); } } @@ -373,10 +400,48 @@ TEST_F(CookiesTreeModelTest, Remove) { // 11. `idbhost2` // 12. `quotahost1` // 13. `quotahost2` + // 14. `sbc1` + // 15. `sbc2` // // Here, we'll remove them one by one, starting from the end, and // check that the state makes sense. + DeleteStoredObjects(cookies_model->GetRoot()->GetChild(15)); + { + SCOPED_TRACE("`sbc2` removed."); + EXPECT_STREQ("A,B,C", GetDisplayedCookies(cookies_model.get()).c_str()); + EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model.get())); + EXPECT_EQ("http://host1:1/,http://host2:2/", + GetDisplayedLocalStorages(cookies_model.get())); + EXPECT_EQ("http://host1:1/,http://host2:2/", + GetDisplayedSessionStorages(cookies_model.get())); + EXPECT_EQ("http://fshost1:1/,http://fshost2:2/,http://fshost3:3/", + GetDisplayedFileSystems(cookies_model.get())); + EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", + GetDisplayedIndexedDBs(cookies_model.get())); + EXPECT_EQ("quotahost1,quotahost2", + GetDisplayedQuotas(cookies_model.get())); + EXPECT_EQ("sbc1", + GetDisplayedServerBoundCerts(cookies_model.get())); + EXPECT_EQ(48, cookies_model->GetRoot()->GetTotalNodeCount()); + } + DeleteStoredObjects(cookies_model->GetRoot()->GetChild(14)); + { + SCOPED_TRACE("`sbc1` removed."); + EXPECT_STREQ("A,B,C", GetDisplayedCookies(cookies_model.get()).c_str()); + EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model.get())); + EXPECT_EQ("http://host1:1/,http://host2:2/", + GetDisplayedLocalStorages(cookies_model.get())); + EXPECT_EQ("http://host1:1/,http://host2:2/", + GetDisplayedSessionStorages(cookies_model.get())); + EXPECT_EQ("http://fshost1:1/,http://fshost2:2/,http://fshost3:3/", + GetDisplayedFileSystems(cookies_model.get())); + EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/", + GetDisplayedIndexedDBs(cookies_model.get())); + EXPECT_EQ("quotahost1,quotahost2", + GetDisplayedQuotas(cookies_model.get())); + EXPECT_EQ(45, cookies_model->GetRoot()->GetTotalNodeCount()); + } DeleteStoredObjects(cookies_model->GetRoot()->GetChild(13)); { SCOPED_TRACE("`quotahost2` removed."); @@ -578,8 +643,10 @@ TEST_F(CookiesTreeModelTest, RemoveCookiesNode) { // idbhost1 -> sessionstorage -> http://idbhost1:1/, // idbhost2 -> sessionstorage -> http://idbhost2:2/, // quotahost1 -> quotahost1, - // quotahost2 -> quotahost1. - EXPECT_EQ(43, cookies_model->GetRoot()->GetTotalNodeCount()); + // quotahost2 -> quotahost1, + // sbc1 -> sbcerts -> sbc1, + // sbc2 -> sbcerts -> sbc2. + EXPECT_EQ(49, cookies_model->GetRoot()->GetTotalNodeCount()); EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model.get())); EXPECT_EQ("http://host1:1/,http://host2:2/", GetDisplayedLocalStorages(cookies_model.get())); @@ -590,6 +657,7 @@ TEST_F(CookiesTreeModelTest, RemoveCookiesNode) { EXPECT_EQ("http://fshost1:1/,http://fshost2:2/,http://fshost3:3/", GetDisplayedFileSystems(cookies_model.get())); EXPECT_EQ("quotahost1,quotahost2", GetDisplayedQuotas(cookies_model.get())); + EXPECT_EQ("sbc1,sbc2", GetDisplayedServerBoundCerts(cookies_model.get())); } DeleteStoredObjects(cookies_model->GetRoot()->GetChild(6)->GetChild(0)); @@ -606,7 +674,8 @@ TEST_F(CookiesTreeModelTest, RemoveCookiesNode) { EXPECT_EQ("http://fshost1:1/,http://fshost2:2/,http://fshost3:3/", GetDisplayedFileSystems(cookies_model.get())); EXPECT_EQ("quotahost1,quotahost2", GetDisplayedQuotas(cookies_model.get())); - EXPECT_EQ(41, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ("sbc1,sbc2", GetDisplayedServerBoundCerts(cookies_model.get())); + EXPECT_EQ(47, cookies_model->GetRoot()->GetTotalNodeCount()); } DeleteStoredObjects(cookies_model->GetRoot()->GetChild(8)->GetChild(0)); @@ -623,7 +692,8 @@ TEST_F(CookiesTreeModelTest, RemoveCookiesNode) { EXPECT_EQ("http://fshost1:1/,http://fshost2:2/,http://fshost3:3/", GetDisplayedFileSystems(cookies_model.get())); EXPECT_EQ("quotahost1,quotahost2", GetDisplayedQuotas(cookies_model.get())); - EXPECT_EQ(39, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ("sbc1,sbc2", GetDisplayedServerBoundCerts(cookies_model.get())); + EXPECT_EQ(45, cookies_model->GetRoot()->GetTotalNodeCount()); } } @@ -645,6 +715,7 @@ TEST_F(CookiesTreeModelTest, RemoveCookieNode) { EXPECT_EQ("http://fshost1:1/,http://fshost2:2/,http://fshost3:3/", GetDisplayedFileSystems(cookies_model.get())); EXPECT_EQ("quotahost1,quotahost2", GetDisplayedQuotas(cookies_model.get())); + EXPECT_EQ("sbc1,sbc2", GetDisplayedServerBoundCerts(cookies_model.get())); // 43 because in this case, the origin remains, although the COOKIES // node beneath it has been deleted. So, we have // root -> foo1 -> cookies -> a, foo2, foo3 -> cookies -> c @@ -660,7 +731,7 @@ TEST_F(CookiesTreeModelTest, RemoveCookieNode) { // idbhost2 -> sessionstorage -> http://idbhost2:2/, // quotahost1 -> quotahost1, // quotahost2 -> quotahost2. - EXPECT_EQ(43, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ(49, cookies_model->GetRoot()->GetTotalNodeCount()); } DeleteStoredObjects(cookies_model->GetRoot()->GetChild(6)->GetChild(0)); @@ -677,7 +748,8 @@ TEST_F(CookiesTreeModelTest, RemoveCookieNode) { EXPECT_EQ("http://fshost1:1/,http://fshost2:2/,http://fshost3:3/", GetDisplayedFileSystems(cookies_model.get())); EXPECT_EQ("quotahost1,quotahost2", GetDisplayedQuotas(cookies_model.get())); - EXPECT_EQ(41, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ("sbc1,sbc2", GetDisplayedServerBoundCerts(cookies_model.get())); + EXPECT_EQ(47, cookies_model->GetRoot()->GetTotalNodeCount()); } DeleteStoredObjects(cookies_model->GetRoot()->GetChild(8)->GetChild(0)); @@ -694,7 +766,8 @@ TEST_F(CookiesTreeModelTest, RemoveCookieNode) { EXPECT_EQ("http://fshost1:1/,http://fshost2:2/,http://fshost3:3/", GetDisplayedFileSystems(cookies_model.get())); EXPECT_EQ("quotahost1,quotahost2", GetDisplayedQuotas(cookies_model.get())); - EXPECT_EQ(39, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ("sbc1,sbc2", GetDisplayedServerBoundCerts(cookies_model.get())); + EXPECT_EQ(45, cookies_model->GetRoot()->GetTotalNodeCount()); } } @@ -707,6 +780,7 @@ TEST_F(CookiesTreeModelTest, RemoveSingleCookieNode) { mock_browsing_data_indexed_db_helper_, mock_browsing_data_file_system_helper_, mock_browsing_data_quota_helper_, + mock_browsing_data_server_bound_cert_helper_, false); mock_browsing_data_cookie_helper_-> AddCookieSamples(GURL("http://foo1"), "A=1"); @@ -787,6 +861,7 @@ TEST_F(CookiesTreeModelTest, RemoveSingleCookieNodeOf3) { mock_browsing_data_indexed_db_helper_, mock_browsing_data_file_system_helper_, mock_browsing_data_quota_helper_, + mock_browsing_data_server_bound_cert_helper_, false); mock_browsing_data_cookie_helper_-> AddCookieSamples(GURL("http://foo1"), "A=1"); @@ -871,6 +946,7 @@ TEST_F(CookiesTreeModelTest, RemoveSecondOrigin) { mock_browsing_data_indexed_db_helper_, mock_browsing_data_file_system_helper_, mock_browsing_data_quota_helper_, + mock_browsing_data_server_bound_cert_helper_, false); mock_browsing_data_cookie_helper_-> AddCookieSamples(GURL("http://foo1"), "A=1"); @@ -909,6 +985,7 @@ TEST_F(CookiesTreeModelTest, OriginOrdering) { mock_browsing_data_indexed_db_helper_, mock_browsing_data_file_system_helper_, mock_browsing_data_quota_helper_, + mock_browsing_data_server_bound_cert_helper_, false); mock_browsing_data_cookie_helper_-> AddCookieSamples(GURL("http://a.foo2.com"), "A=1"); @@ -951,6 +1028,7 @@ TEST_F(CookiesTreeModelTest, ContentSettings) { mock_browsing_data_indexed_db_helper_, mock_browsing_data_file_system_helper_, mock_browsing_data_quota_helper_, + mock_browsing_data_server_bound_cert_helper_, false); mock_browsing_data_cookie_helper_->AddCookieSamples(host, "A=1"); mock_browsing_data_cookie_helper_->Notify(); diff --git a/chrome/browser/mock_browsing_data_server_bound_cert_helper.cc b/chrome/browser/mock_browsing_data_server_bound_cert_helper.cc new file mode 100644 index 0000000..63b063f --- /dev/null +++ b/chrome/browser/mock_browsing_data_server_bound_cert_helper.cc @@ -0,0 +1,61 @@ +// 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. + +#include "chrome/browser/mock_browsing_data_server_bound_cert_helper.h" + +#include "base/logging.h" + +MockBrowsingDataServerBoundCertHelper::MockBrowsingDataServerBoundCertHelper() + : BrowsingDataServerBoundCertHelper() {} + +MockBrowsingDataServerBoundCertHelper:: +~MockBrowsingDataServerBoundCertHelper() {} + +void MockBrowsingDataServerBoundCertHelper::StartFetching( + const FetchResultCallback& callback) { + callback_ = callback; +} + +void MockBrowsingDataServerBoundCertHelper::DeleteServerBoundCert( + const std::string& server_id) { + CHECK(server_bound_certs_.find(server_id) != server_bound_certs_.end()); + server_bound_certs_[server_id] = false; +} + +void MockBrowsingDataServerBoundCertHelper::AddServerBoundCertSample( + const std::string& server_id) { + DCHECK(server_bound_certs_.find(server_id) == server_bound_certs_.end()); + server_bound_cert_list_.push_back( + net::ServerBoundCertStore::ServerBoundCert( + server_id, net::CLIENT_CERT_ECDSA_SIGN, + base::Time(), base::Time(), "key", "cert")); + server_bound_certs_[server_id] = true; +} + +void MockBrowsingDataServerBoundCertHelper::Notify() { + net::ServerBoundCertStore::ServerBoundCertList cert_list; + for (net::ServerBoundCertStore::ServerBoundCertList::iterator i = + server_bound_cert_list_.begin(); + i != server_bound_cert_list_.end(); ++i) { + if (server_bound_certs_[i->server_identifier()]) + cert_list.push_back(*i); + } + callback_.Run(cert_list); +} + +void MockBrowsingDataServerBoundCertHelper::Reset() { + for (std::map<const std::string, bool>::iterator i = + server_bound_certs_.begin(); + i != server_bound_certs_.end(); ++i) + i->second = true; +} + +bool MockBrowsingDataServerBoundCertHelper::AllDeleted() { + for (std::map<const std::string, bool>::const_iterator i = + server_bound_certs_.begin(); + i != server_bound_certs_.end(); ++i) + if (i->second) + return false; + return true; +} diff --git a/chrome/browser/mock_browsing_data_server_bound_cert_helper.h b/chrome/browser/mock_browsing_data_server_bound_cert_helper.h new file mode 100644 index 0000000..0630be0 --- /dev/null +++ b/chrome/browser/mock_browsing_data_server_bound_cert_helper.h @@ -0,0 +1,48 @@ +// 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. + +#ifndef CHROME_BROWSER_MOCK_BROWSING_DATA_SERVER_BOUND_CERT_HELPER_H_ +#define CHROME_BROWSER_MOCK_BROWSING_DATA_SERVER_BOUND_CERT_HELPER_H_ +#pragma once + +#include <map> +#include <string> + +#include "chrome/browser/browsing_data_server_bound_cert_helper.h" + +// Mock for BrowsingDataServerBoundCertHelper. +class MockBrowsingDataServerBoundCertHelper + : public BrowsingDataServerBoundCertHelper { + public: + explicit MockBrowsingDataServerBoundCertHelper(); + + // BrowsingDataServerBoundCertHelper methods. + virtual void StartFetching(const FetchResultCallback& callback) OVERRIDE; + virtual void DeleteServerBoundCert(const std::string& server_id) OVERRIDE; + + // Adds a server_bound_cert sample. + void AddServerBoundCertSample(const std::string& server_id); + + // Notifies the callback. + void Notify(); + + // Marks all server_bound_certs as existing. + void Reset(); + + // Returns true if all server_bound_certs since the last Reset() invocation + // were deleted. + bool AllDeleted(); + + private: + virtual ~MockBrowsingDataServerBoundCertHelper(); + + FetchResultCallback callback_; + + net::ServerBoundCertStore::ServerBoundCertList server_bound_cert_list_; + + // Stores which server_bound_certs exist. + std::map<const std::string, bool> server_bound_certs_; +}; + +#endif // CHROME_BROWSER_MOCK_BROWSING_DATA_SERVER_BOUND_CERT_HELPER_H_ diff --git a/chrome/browser/resources/options2/cookies_list.js b/chrome/browser/resources/options2/cookies_list.js index c541d2e..e887ca0 100644 --- a/chrome/browser/resources/options2/cookies_list.js +++ b/chrome/browser/resources/options2/cookies_list.js @@ -37,6 +37,10 @@ cr.define('options', function() { 'file_system': [['origin', 'label_file_system_origin'], ['persistent', 'label_file_system_persistent_usage'], ['temporary', 'label_file_system_temporary_usage']], + 'server_bound_cert': [['serverId', 'label_server_bound_cert_server_id'], + ['certType', 'label_server_bound_cert_type'], + ['created', 'label_server_bound_cert_created'], + ['expires', 'label_server_bound_cert_expires']], }; /** @const */ var localStrings = new LocalStrings(); @@ -227,6 +231,7 @@ cr.define('options', function() { appCache: false, indexedDb: false, fileSystem: false, + serverBoundCerts: 0, }; if (this.origin) this.origin.collectSummaryInfo(info); @@ -243,6 +248,8 @@ cr.define('options', function() { list.push(localStrings.getString('cookie_app_cache')); if (info.fileSystem) list.push(localStrings.getString('cookie_file_system')); + if (info.serverBoundCerts) + list.push(localStrings.getString('cookie_server_bound_cert')); var text = ''; for (var i = 0; i < list.length; ++i) if (text.length > 0) @@ -448,6 +455,8 @@ cr.define('options', function() { info.fileSystem = true; } else if (this.data.type == 'quota') { info.quota = this.data; + } else if (this.data.type == 'server_bound_cert') { + info.serverBoundCerts++; } } }, @@ -480,6 +489,9 @@ cr.define('options', function() { case 'file_system': text = localStrings.getString('cookie_file_system'); break; + case 'server_bound_cert': + text = localStrings.getString('cookie_server_bound_cert'); + break; } if (!text) return; diff --git a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm index a0c2f8e..ae379ef 100644 --- a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm +++ b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm @@ -15,6 +15,7 @@ #include "chrome/browser/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data_indexed_db_helper.h" #include "chrome/browser/browsing_data_local_storage_helper.h" +#include "chrome/browser/browsing_data_server_bound_cert_helper.h" #include "chrome/browser/content_settings/cookie_settings.h" #include "chrome/browser/content_settings/local_shared_objects_container.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" @@ -389,6 +390,7 @@ void CollectedCookiesMac::OnSheetDidEnd(NSWindow* sheet) { allowed_lsos.indexed_dbs()->Clone(), allowed_lsos.file_systems()->Clone(), NULL, + allowed_lsos.server_bound_certs()->Clone(), true)); const LocalSharedObjectsContainer& blocked_lsos = content_settings->blocked_local_shared_objects(); @@ -401,6 +403,7 @@ void CollectedCookiesMac::OnSheetDidEnd(NSWindow* sheet) { blocked_lsos.indexed_dbs()->Clone(), blocked_lsos.file_systems()->Clone(), NULL, + blocked_lsos.server_bound_certs()->Clone(), true)); // Convert the model's icons from Skia to Cocoa. diff --git a/chrome/browser/ui/gtk/collected_cookies_gtk.cc b/chrome/browser/ui/gtk/collected_cookies_gtk.cc index 8c83b4c..0b1d209 100644 --- a/chrome/browser/ui/gtk/collected_cookies_gtk.cc +++ b/chrome/browser/ui/gtk/collected_cookies_gtk.cc @@ -11,6 +11,7 @@ #include "chrome/browser/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data_indexed_db_helper.h" #include "chrome/browser/browsing_data_local_storage_helper.h" +#include "chrome/browser/browsing_data_server_bound_cert_helper.h" #include "chrome/browser/content_settings/cookie_settings.h" #include "chrome/browser/content_settings/local_shared_objects_container.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" @@ -217,6 +218,7 @@ GtkWidget* CollectedCookiesGtk::CreateAllowedPane() { allowed_lsos.indexed_dbs()->Clone(), allowed_lsos.file_systems()->Clone(), NULL, + allowed_lsos.server_bound_certs()->Clone(), true)); allowed_cookies_tree_adapter_.reset( new gtk_tree::TreeAdapter(this, allowed_cookies_tree_model_.get())); @@ -304,6 +306,7 @@ GtkWidget* CollectedCookiesGtk::CreateBlockedPane() { blocked_lsos.indexed_dbs()->Clone(), blocked_lsos.file_systems()->Clone(), NULL, + blocked_lsos.server_bound_certs()->Clone(), true)); blocked_cookies_tree_adapter_.reset( new gtk_tree::TreeAdapter(this, blocked_cookies_tree_model_.get())); diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc index b2e5757..6b8722c 100644 --- a/chrome/browser/ui/views/collected_cookies_views.cc +++ b/chrome/browser/ui/views/collected_cookies_views.cc @@ -10,6 +10,7 @@ #include "chrome/browser/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data_indexed_db_helper.h" #include "chrome/browser/browsing_data_local_storage_helper.h" +#include "chrome/browser/browsing_data_server_bound_cert_helper.h" #include "chrome/browser/content_settings/cookie_settings.h" #include "chrome/browser/content_settings/local_shared_objects_container.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" @@ -338,6 +339,7 @@ views::View* CollectedCookiesViews::CreateAllowedPane() { allowed_lsos.indexed_dbs()->Clone(), allowed_lsos.file_systems()->Clone(), NULL, + allowed_lsos.server_bound_certs()->Clone(), true)); allowed_cookies_tree_ = new views::TreeView(); allowed_cookies_tree_->SetModel(allowed_cookies_tree_model_.get()); @@ -404,6 +406,7 @@ views::View* CollectedCookiesViews::CreateBlockedPane() { blocked_lsos.indexed_dbs()->Clone(), blocked_lsos.file_systems()->Clone(), NULL, + blocked_lsos.server_bound_certs()->Clone(), true)); blocked_cookies_tree_ = new views::TreeView(); blocked_cookies_tree_->SetModel(blocked_cookies_tree_model_.get()); diff --git a/chrome/browser/ui/webui/cookies_tree_model_util.cc b/chrome/browser/ui/webui/cookies_tree_model_util.cc index 599e995..7692ee6 100644 --- a/chrome/browser/ui/webui/cookies_tree_model_util.cc +++ b/chrome/browser/ui/webui/cookies_tree_model_util.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. @@ -32,6 +32,7 @@ static const char kKeyDesc[] = "desc"; static const char kKeySize[] = "size"; static const char kKeyOrigin[] = "origin"; static const char kKeyManifest[] = "manifest"; +static const char kKeyServerId[] = "serverId"; static const char kKeyAccessed[] = "accessed"; static const char kKeyCreated[] = "created"; @@ -46,6 +47,8 @@ static const char kKeyTemporaryUsage[] = "temporaryUsage"; static const char kKeyPersistentUsage[] = "persistentUsage"; static const char kKeyPersistentQuota[] = "persistentQuota"; +static const char kKeyCertType[] = "certType"; + static const int64 kNegligibleUsage = 1024; // 1KiB // Encodes a pointer value into a hex string. @@ -64,6 +67,17 @@ void* HexStringToPointer(const std::string& str) { return *reinterpret_cast<void**>(&buffer[0]); } +std::string ClientCertTypeToString(net::SSLClientCertType type) { + switch (type) { + case net::CLIENT_CERT_RSA_SIGN: + return l10n_util::GetStringUTF8(IDS_CLIENT_CERT_RSA_SIGN); + case net::CLIENT_CERT_ECDSA_SIGN: + return l10n_util::GetStringUTF8(IDS_CLIENT_CERT_ECDSA_SIGN); + default: + return base::IntToString(type); + } +} + } // namespace namespace cookies_tree_model_util { @@ -220,6 +234,24 @@ bool GetCookieTreeNodeDictionary(const CookieTreeNode& node, quota_info.persistent_usage))); break; } + case CookieTreeNode::DetailedInfo::TYPE_SERVER_BOUND_CERT: { + dict->SetString(kKeyType, "server_bound_cert"); + dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_ICON"); + + const net::ServerBoundCertStore::ServerBoundCert& server_bound_cert = + *node.GetDetailedInfo().server_bound_cert; + + dict->SetString(kKeyServerId, server_bound_cert.server_identifier()); + dict->SetString(kKeyCertType, + ClientCertTypeToString(server_bound_cert.type())); + dict->SetString(kKeyCreated, UTF16ToUTF8( + base::TimeFormatFriendlyDateAndTime( + server_bound_cert.creation_time()))); + dict->SetString(kKeyExpires, UTF16ToUTF8( + base::TimeFormatFriendlyDateAndTime( + server_bound_cert.expiration_time()))); + break; + } default: #if defined(OS_MACOSX) dict->SetString(kKeyIcon, "chrome://theme/IDR_BOOKMARK_BAR_FOLDER"); diff --git a/chrome/browser/ui/webui/options2/cookies_view_handler2.cc b/chrome/browser/ui/webui/options2/cookies_view_handler2.cc index 22755c7..3d60f337 100644 --- a/chrome/browser/ui/webui/options2/cookies_view_handler2.cc +++ b/chrome/browser/ui/webui/options2/cookies_view_handler2.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,8 +13,9 @@ #include "chrome/browser/browsing_data_database_helper.h" #include "chrome/browser/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data_indexed_db_helper.h" -#include "chrome/browser/browsing_data_quota_helper.h" #include "chrome/browser/browsing_data_local_storage_helper.h" +#include "chrome/browser/browsing_data_quota_helper.h" +#include "chrome/browser/browsing_data_server_bound_cert_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/cookies_tree_model_util.h" #include "content/public/browser/web_ui.h" @@ -73,6 +74,15 @@ void CookiesViewHandler::GetLocalizedValues( IDS_COOKIES_FILE_SYSTEM_TEMPORARY_USAGE_LABEL }, { "label_file_system_persistent_usage", IDS_COOKIES_FILE_SYSTEM_PERSISTENT_USAGE_LABEL }, + { "cookie_server_bound_cert", IDS_COOKIES_SERVER_BOUND_CERT }, + { "label_server_bound_cert_server_id", + IDS_COOKIES_SERVER_BOUND_CERT_ORIGIN_LABEL }, + { "label_server_bound_cert_type", + IDS_COOKIES_SERVER_BOUND_CERT_TYPE_LABEL }, + { "label_server_bound_cert_created", + IDS_COOKIES_SERVER_BOUND_CERT_CREATED_LABEL }, + { "label_server_bound_cert_expires", + IDS_COOKIES_SERVER_BOUND_CERT_EXPIRES_LABEL }, }; RegisterStrings(localized_strings, resources, arraysize(resources)); @@ -161,6 +171,7 @@ void CookiesViewHandler::EnsureCookiesTreeModelCreated() { BrowsingDataIndexedDBHelper::Create(profile), BrowsingDataFileSystemHelper::Create(profile), BrowsingDataQuotaHelper::Create(profile), + BrowsingDataServerBoundCertHelper::Create(profile), false)); cookies_tree_model_->AddCookiesTreeObserver(this); } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 82bab51..14c6443 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -349,6 +349,8 @@ 'browser/browsing_data_quota_helper_impl.h', 'browser/browsing_data_remover.cc', 'browser/browsing_data_remover.h', + 'browser/browsing_data_server_bound_cert_helper.cc', + 'browser/browsing_data_server_bound_cert_helper.h', 'browser/feedback/feedback_data.cc', 'browser/feedback/feedback_data.h', 'browser/feedback/feedback_util.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 9e5b38a..c6896d2 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -127,6 +127,8 @@ 'browser/mock_browsing_data_local_storage_helper.h', 'browser/mock_browsing_data_quota_helper.cc', 'browser/mock_browsing_data_quota_helper.h', + 'browser/mock_browsing_data_server_bound_cert_helper.cc', + 'browser/mock_browsing_data_server_bound_cert_helper.h', 'browser/notifications/notification_test_util.cc', 'browser/notifications/notification_test_util.h', 'browser/password_manager/mock_password_store.cc', @@ -1267,6 +1269,7 @@ 'browser/browsing_data_local_storage_helper_unittest.cc', 'browser/browsing_data_quota_helper_unittest.cc', 'browser/browsing_data_remover_unittest.cc', + 'browser/browsing_data_server_bound_cert_helper_unittest.cc', 'browser/chrome_browser_application_mac_unittest.mm', 'browser/chrome_browser_main_unittest.cc', 'browser/chrome_page_zoom_unittest.cc', diff --git a/net/base/default_server_bound_cert_store.cc b/net/base/default_server_bound_cert_store.cc index 180792a..3252899 100644 --- a/net/base/default_server_bound_cert_store.cc +++ b/net/base/default_server_bound_cert_store.cc @@ -102,7 +102,7 @@ void DefaultServerBoundCertStore::DeleteAll() { } void DefaultServerBoundCertStore::GetAllServerBoundCerts( - std::vector<ServerBoundCert>* server_bound_certs) { + ServerBoundCertList* server_bound_certs) { base::AutoLock autolock(lock_); InitIfNecessary(); for (ServerBoundCertMap::iterator it = server_bound_certs_.begin(); diff --git a/net/base/default_server_bound_cert_store.h b/net/base/default_server_bound_cert_store.h index 1ba7090d..cd664fe 100644 --- a/net/base/default_server_bound_cert_store.h +++ b/net/base/default_server_bound_cert_store.h @@ -74,7 +74,7 @@ class NET_EXPORT DefaultServerBoundCertStore : public ServerBoundCertStore { base::Time delete_end) OVERRIDE; virtual void DeleteAll() OVERRIDE; virtual void GetAllServerBoundCerts( - std::vector<ServerBoundCert>* server_bound_certs) OVERRIDE; + ServerBoundCertList* server_bound_certs) OVERRIDE; virtual int GetCertCount() OVERRIDE; private: diff --git a/net/base/default_server_bound_cert_store_unittest.cc b/net/base/default_server_bound_cert_store_unittest.cc index 5fbe4e2..fb94234a 100644 --- a/net/base/default_server_bound_cert_store_unittest.cc +++ b/net/base/default_server_bound_cert_store_unittest.cc @@ -286,7 +286,7 @@ TEST(DefaultServerBoundCertStoreTest, TestGetAll) { "g", "h"); EXPECT_EQ(4, store.GetCertCount()); - std::vector<ServerBoundCertStore::ServerBoundCert> certs; + ServerBoundCertStore::ServerBoundCertList certs; store.GetAllServerBoundCerts(&certs); EXPECT_EQ(4u, certs.size()); } diff --git a/net/base/server_bound_cert_store.h b/net/base/server_bound_cert_store.h index 02dfe52..32b178e 100644 --- a/net/base/server_bound_cert_store.h +++ b/net/base/server_bound_cert_store.h @@ -6,8 +6,8 @@ #define NET_BASE_SERVER_BOUND_CERT_STORE_H_ #pragma once +#include <list> #include <string> -#include <vector> #include "base/time.h" #include "net/base/net_export.h" @@ -62,6 +62,8 @@ class NET_EXPORT ServerBoundCertStore { std::string cert_; }; + typedef std::list<ServerBoundCert> ServerBoundCertList; + virtual ~ServerBoundCertStore() {} // TODO(rkn): File I/O may be required, so this should have an asynchronous @@ -105,7 +107,7 @@ class NET_EXPORT ServerBoundCertStore { // Returns all server bound certs and the corresponding private keys. virtual void GetAllServerBoundCerts( - std::vector<ServerBoundCert>* server_bound_certs) = 0; + ServerBoundCertList* server_bound_certs) = 0; // Returns the number of certs in the store. // Public only for unit testing. |