summaryrefslogtreecommitdiffstats
path: root/net/base
diff options
context:
space:
mode:
authorrch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-10 04:16:25 +0000
committerrch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-10 04:16:25 +0000
commit62635c758fce2b22a1cf5acdc57579bb5801b2e3 (patch)
tree4085d65bbf01078b722cbcef5930e157d7f793be /net/base
parentd7f6e73fb05992d784e55df2a1ed25924b5d79f3 (diff)
downloadchromium_src-62635c758fce2b22a1cf5acdc57579bb5801b2e3.zip
chromium_src-62635c758fce2b22a1cf5acdc57579bb5801b2e3.tar.gz
chromium_src-62635c758fce2b22a1cf5acdc57579bb5801b2e3.tar.bz2
Define a new CertDatabase::Observer abstract class which can be implemented by classes which wish to be notified when a new ssl client cert is added.
Register SpdySessionPool, SocketPoolManager and SSLClientAuthCache as observers. Notify observers in CertDatabase::AddUserCert(); BUG=75326 Review URL: http://codereview.chromium.org/6588014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@77599 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base')
-rw-r--r--net/base/cert_database.cc35
-rw-r--r--net/base/cert_database.h31
-rw-r--r--net/base/cert_database_mac.cc2
-rw-r--r--net/base/cert_database_nss.cc1
-rw-r--r--net/base/cert_database_win.cc1
-rw-r--r--net/base/ssl_client_auth_cache.cc10
-rw-r--r--net/base/ssl_client_auth_cache.h7
-rw-r--r--net/base/ssl_client_auth_cache_unittest.cc6
8 files changed, 84 insertions, 9 deletions
diff --git a/net/base/cert_database.cc b/net/base/cert_database.cc
index 313a6dd0..f049aca 100644
--- a/net/base/cert_database.cc
+++ b/net/base/cert_database.cc
@@ -4,6 +4,8 @@
#include "net/base/cert_database.h"
+#include "base/observer_list_threadsafe.h"
+#include "base/singleton.h"
#include "net/base/x509_certificate.h"
namespace net {
@@ -16,4 +18,37 @@ CertDatabase::ImportCertFailure::ImportCertFailure(
CertDatabase::ImportCertFailure::~ImportCertFailure() {
}
+// CertDatabaseNotifier notifies registered observers when new user certificates
+// are added to the database.
+class CertDatabaseNotifier {
+ public:
+ CertDatabaseNotifier()
+ : observer_list_(new ObserverListThreadSafe<CertDatabase::Observer>) {
+ }
+
+ static CertDatabaseNotifier* GetInstance() {
+ return Singleton<CertDatabaseNotifier>::get();
+ }
+
+ friend struct DefaultSingletonTraits<CertDatabaseNotifier>;
+ friend class CertDatabase;
+
+ private:
+ const scoped_refptr<ObserverListThreadSafe<CertDatabase::Observer> >
+ observer_list_;
+};
+
+void CertDatabase::AddObserver(Observer* observer) {
+ CertDatabaseNotifier::GetInstance()->observer_list_->AddObserver(observer);
+}
+
+void CertDatabase::RemoveObserver(Observer* observer) {
+ CertDatabaseNotifier::GetInstance()->observer_list_->RemoveObserver(observer);
+}
+
+void CertDatabase::NotifyObserversOfUserCertAdded(X509Certificate* cert) {
+ CertDatabaseNotifier::GetInstance()->observer_list_->Notify(
+ &CertDatabase::Observer::OnUserCertAdded, make_scoped_refptr(cert));
+}
+
} // namespace net
diff --git a/net/base/cert_database.h b/net/base/cert_database.h
index 0e7bdbd..5760dff 100644
--- a/net/base/cert_database.h
+++ b/net/base/cert_database.h
@@ -31,6 +31,25 @@ typedef std::vector<scoped_refptr<X509Certificate> > CertificateList;
class CertDatabase {
public:
+
+ // A CertDatabase::Observer will be notified every time a new user
+ // certificate is added to the database. Observers can register themselves
+ // via CertDatabase::AddObserver, and can un-register with
+ // CertDatabase::RemoveObserver.
+ class Observer {
+ public:
+ virtual ~Observer() {}
+
+ // Will be called when a new user certificate is added.
+ virtual void OnUserCertAdded(X509Certificate* cert) = 0;
+
+ protected:
+ Observer() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Observer);
+ };
+
// Stores per-certificate error codes for import failures.
struct ImportCertFailure {
public:
@@ -141,7 +160,19 @@ class CertDatabase {
bool IsReadOnly(const X509Certificate* cert) const;
#endif
+ // Registers |observer| to receive notifications of certificate changes. The
+ // thread on which this is called is the thread on which |observer| will be
+ // called back with notifications.
+ static void AddObserver(Observer* observer);
+
+ // Unregisters |observer| from receiving notifications. This must be called
+ // on the same thread on which AddObserver() was called.
+ static void RemoveObserver(Observer* observer);
+
private:
+ // Broadcasts a notification to all registered observers.
+ static void NotifyObserversOfUserCertAdded(X509Certificate* cert);
+
DISALLOW_COPY_AND_ASSIGN(CertDatabase);
};
diff --git a/net/base/cert_database_mac.cc b/net/base/cert_database_mac.cc
index e90a712..66828ad 100644
--- a/net/base/cert_database_mac.cc
+++ b/net/base/cert_database_mac.cc
@@ -48,6 +48,8 @@ int CertDatabase::AddUserCert(X509Certificate* cert) {
}
switch (err) {
case noErr:
+ CertDatabase::NotifyObserversOfUserCertAdded(cert);
+ // Fall through.
case errSecDuplicateItem:
return OK;
default:
diff --git a/net/base/cert_database_nss.cc b/net/base/cert_database_nss.cc
index 7e1abaa9..60cc4bc 100644
--- a/net/base/cert_database_nss.cc
+++ b/net/base/cert_database_nss.cc
@@ -89,6 +89,7 @@ int CertDatabase::AddUserCert(X509Certificate* cert_obj) {
return ERR_ADD_USER_CERT_FAILED;
}
PK11_FreeSlot(slot);
+ CertDatabase::NotifyObserversOfUserCertAdded(cert_obj);
return OK;
}
diff --git a/net/base/cert_database_win.cc b/net/base/cert_database_win.cc
index 4c5e8df..038fc1c 100644
--- a/net/base/cert_database_win.cc
+++ b/net/base/cert_database_win.cc
@@ -50,6 +50,7 @@ int CertDatabase::AddUserCert(X509Certificate* cert) {
if (!added)
return ERR_ADD_USER_CERT_FAILED;
+ CertDatabase::NotifyObserversOfUserCertAdded(cert);
return OK;
}
diff --git a/net/base/ssl_client_auth_cache.cc b/net/base/ssl_client_auth_cache.cc
index cdaad7f..ecfada8 100644
--- a/net/base/ssl_client_auth_cache.cc
+++ b/net/base/ssl_client_auth_cache.cc
@@ -9,9 +9,13 @@
namespace net {
-SSLClientAuthCache::SSLClientAuthCache() {}
+SSLClientAuthCache::SSLClientAuthCache() {
+ CertDatabase::AddObserver(this);
+}
-SSLClientAuthCache::~SSLClientAuthCache() {}
+SSLClientAuthCache::~SSLClientAuthCache() {
+ CertDatabase::RemoveObserver(this);
+}
bool SSLClientAuthCache::Lookup(
const std::string& server,
@@ -37,7 +41,7 @@ void SSLClientAuthCache::Remove(const std::string& server) {
cache_.erase(server);
}
-void SSLClientAuthCache::Clear() {
+void SSLClientAuthCache::OnUserCertAdded(X509Certificate* cert) {
cache_.clear();
}
diff --git a/net/base/ssl_client_auth_cache.h b/net/base/ssl_client_auth_cache.h
index b37164a..6cc1d12 100644
--- a/net/base/ssl_client_auth_cache.h
+++ b/net/base/ssl_client_auth_cache.h
@@ -10,6 +10,7 @@
#include <map>
#include "base/ref_counted.h"
+#include "net/base/cert_database.h"
namespace net {
@@ -22,7 +23,7 @@ class X509Certificate;
//
// TODO(wtc): This class is based on FtpAuthCache. We can extract the common
// code to a template class.
-class SSLClientAuthCache {
+class SSLClientAuthCache : public CertDatabase::Observer {
public:
SSLClientAuthCache();
~SSLClientAuthCache();
@@ -44,8 +45,8 @@ class SSLClientAuthCache {
// Remove the client certificate for |server| from the cache, if one exists.
void Remove(const std::string& server);
- // Removes all cache entries.
- void Clear();
+ // CertDatabase::Observer methods:
+ virtual void OnUserCertAdded(X509Certificate* cert);
private:
typedef std::string AuthCacheKey;
diff --git a/net/base/ssl_client_auth_cache_unittest.cc b/net/base/ssl_client_auth_cache_unittest.cc
index 144e114..6408887 100644
--- a/net/base/ssl_client_auth_cache_unittest.cc
+++ b/net/base/ssl_client_auth_cache_unittest.cc
@@ -137,8 +137,8 @@ TEST(SSLClientAuthCacheTest, LookupNullPreference) {
EXPECT_EQ(NULL, cached_cert.get());
}
-// Check that the Clear() method removes all cache entries.
-TEST(SSLClientAuthCacheTest, Clear) {
+// Check that the OnUserCertAdded() method removes all cache entries.
+TEST(SSLClientAuthCacheTest, OnUserCertAdded) {
SSLClientAuthCache cache;
base::Time start_date = base::Time::Now();
base::Time expiration_date = start_date + base::TimeDelta::FromDays(1);
@@ -161,7 +161,7 @@ TEST(SSLClientAuthCacheTest, Clear) {
EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
EXPECT_EQ(NULL, cached_cert.get());
- cache.Clear();
+ cache.OnUserCertAdded(NULL);
// Check that we no longer have entries for either server.
EXPECT_FALSE(cache.Lookup(server1, &cached_cert));