summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-18 19:38:58 +0000
committerwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-18 19:38:58 +0000
commit56c866a252b4a7dcb525b0b29bafc4de0168b7bb (patch)
tree3eb4f9f77dede3481a05e9e2d730dbace83d13fd /net
parent1a041bb64d411c1902e005cdc1a904607016f707 (diff)
downloadchromium_src-56c866a252b4a7dcb525b0b29bafc4de0168b7bb.zip
chromium_src-56c866a252b4a7dcb525b0b29bafc4de0168b7bb.tar.gz
chromium_src-56c866a252b4a7dcb525b0b29bafc4de0168b7bb.tar.bz2
Add a simple cache of certificates for SSL client authentication.
It is based on FtpAuthCache and will be used in similar ways. The the only difference is that the authentication data is a certificate rather than username and password. R=eroman BUG=http://crbug.com/318 TEST=new unit tests. Review URL: http://codereview.chromium.org/132004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18735 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/base/ssl_client_auth_cache.cc25
-rw-r--r--net/base/ssl_client_auth_cache.h51
-rw-r--r--net/base/ssl_client_auth_cache_unittest.cc81
-rw-r--r--net/ftp/ftp_auth_cache.h2
-rw-r--r--net/http/http_network_session.h7
-rw-r--r--net/net.gyp3
6 files changed, 167 insertions, 2 deletions
diff --git a/net/base/ssl_client_auth_cache.cc b/net/base/ssl_client_auth_cache.cc
new file mode 100644
index 0000000..b0deec9
--- /dev/null
+++ b/net/base/ssl_client_auth_cache.cc
@@ -0,0 +1,25 @@
+// Copyright (c) 2009 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 "net/base/ssl_client_auth_cache.h"
+
+namespace net {
+
+X509Certificate* SSLClientAuthCache::Lookup(const std::string& server) {
+ AuthCacheMap::iterator iter = cache_.find(server);
+ return (iter == cache_.end()) ? NULL : iter->second;
+}
+
+void SSLClientAuthCache::Add(const std::string& server,
+ X509Certificate* value) {
+ cache_[server] = value;
+
+ // TODO(wtc): enforce a maximum number of entries.
+}
+
+void SSLClientAuthCache::Remove(const std::string& server) {
+ cache_.erase(server);
+}
+
+} // namespace net
diff --git a/net/base/ssl_client_auth_cache.h b/net/base/ssl_client_auth_cache.h
new file mode 100644
index 0000000..386da41
--- /dev/null
+++ b/net/base/ssl_client_auth_cache.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2009 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 NET_BASE_SSL_CLIENT_AUTH_CACHE_H_
+#define NET_BASE_SSL_CLIENT_AUTH_CACHE_H_
+
+#include <string>
+#include <map>
+
+#include "base/ref_counted.h"
+#include "net/base/x509_certificate.h"
+
+namespace net {
+
+// The SSLClientAuthCache class is a simple cache structure to store SSL
+// client certificates. Provides lookup, insertion, and deletion of entries.
+// The parameter for doing lookups, insertions, and deletions is the server's
+// host and port.
+//
+// TODO(wtc): This class is based on FtpAuthCache. We can extract the common
+// code to a template class.
+class SSLClientAuthCache {
+ public:
+ SSLClientAuthCache() {}
+ ~SSLClientAuthCache() {}
+
+ // Check if we have a client certificate for SSL server at |server|.
+ // Returns the client certificate (if found) or NULL (if not found).
+ X509Certificate* Lookup(const std::string& server);
+
+ // Add a client certificate for |server| to the cache. If there is already
+ // a client certificate for |server|, it will be overwritten. Both parameters
+ // are IN only.
+ void Add(const std::string& server, X509Certificate* client_cert);
+
+ // Remove the client certificate for |server| from the cache, if one exists.
+ void Remove(const std::string& server);
+
+ private:
+ typedef std::string AuthCacheKey;
+ typedef scoped_refptr<X509Certificate> AuthCacheValue;
+ typedef std::map<AuthCacheKey, AuthCacheValue> AuthCacheMap;
+
+ // internal representation of cache, an STL map.
+ AuthCacheMap cache_;
+};
+
+} // namespace net
+
+#endif // NET_BASE_SSL_CLIENT_AUTH_CACHE_H_
diff --git a/net/base/ssl_client_auth_cache_unittest.cc b/net/base/ssl_client_auth_cache_unittest.cc
new file mode 100644
index 0000000..33eb25f
--- /dev/null
+++ b/net/base/ssl_client_auth_cache_unittest.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2009 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 "net/base/ssl_client_auth_cache.h"
+
+#include "base/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+TEST(SSLClientAuthCacheTest, LookupAddRemove) {
+ SSLClientAuthCache cache;
+
+ base::Time start_date = base::Time::Now();
+ base::Time expiration_date = start_date + base::TimeDelta::FromDays(1);
+
+ std::string server1("foo1:443");
+ scoped_refptr<X509Certificate> cert1(
+ new X509Certificate("foo1", "CA", start_date, expiration_date));
+
+ std::string server2("foo2:443");
+ scoped_refptr<X509Certificate> cert2(
+ new X509Certificate("foo2", "CA", start_date, expiration_date));
+
+ std::string server3("foo3:443");
+ scoped_refptr<X509Certificate> cert3(
+ new X509Certificate("foo3", "CA", start_date, expiration_date));
+
+ // Lookup non-existent client certificate.
+ EXPECT_EQ(NULL, cache.Lookup(server1));
+
+ // Add client certificate for server1.
+ cache.Add(server1, cert1.get());
+ EXPECT_EQ(cert1.get(), cache.Lookup(server1));
+
+ // Add client certificate for server2.
+ cache.Add(server2, cert2.get());
+ EXPECT_EQ(cert1.get(), cache.Lookup(server1));
+ EXPECT_EQ(cert2.get(), cache.Lookup(server2));
+
+ // Overwrite the client certificate for server1.
+ cache.Add(server1, cert3.get());
+ EXPECT_EQ(cert3.get(), cache.Lookup(server1));
+ EXPECT_EQ(cert2.get(), cache.Lookup(server2));
+
+ // Remove client certificate of server1.
+ cache.Remove(server1);
+ EXPECT_EQ(NULL, cache.Lookup(server1));
+ EXPECT_EQ(cert2.get(), cache.Lookup(server2));
+
+ // Remove non-existent client certificate.
+ cache.Remove(server1);
+ EXPECT_EQ(NULL, cache.Lookup(server1));
+ EXPECT_EQ(cert2.get(), cache.Lookup(server2));
+}
+
+// Check that if the server differs only by port number, it is considered
+// a separate server.
+TEST(SSLClientAuthCacheTest, LookupWithPort) {
+ SSLClientAuthCache cache;
+
+ base::Time start_date = base::Time::Now();
+ base::Time expiration_date = start_date + base::TimeDelta::FromDays(1);
+
+ std::string server1("foo:443");
+ scoped_refptr<X509Certificate> cert1(
+ new X509Certificate("foo", "CA", start_date, expiration_date));
+
+ std::string server2("foo:8443");
+ scoped_refptr<X509Certificate> cert2(
+ new X509Certificate("foo", "CA", start_date, expiration_date));
+
+ cache.Add(server1, cert1.get());
+ cache.Add(server2, cert2.get());
+
+ EXPECT_EQ(cert1.get(), cache.Lookup(server1));
+ EXPECT_EQ(cert2.get(), cache.Lookup(server2));
+}
+
+} // namespace net
diff --git a/net/ftp/ftp_auth_cache.h b/net/ftp/ftp_auth_cache.h
index 1bde911..1286511 100644
--- a/net/ftp/ftp_auth_cache.h
+++ b/net/ftp/ftp_auth_cache.h
@@ -42,7 +42,7 @@ class FtpAuthCache {
private:
typedef std::string AuthCacheKey;
typedef scoped_refptr<AuthData> AuthCacheValue;
- typedef std::map<AuthCacheKey,AuthCacheValue> AuthCacheMap;
+ typedef std::map<AuthCacheKey, AuthCacheValue> AuthCacheMap;
// Get the key in hash table |cache_| where entries for ftp server |origin|
// should be saved.
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index c7ebb3c..d8345ca 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2009 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.
@@ -6,6 +6,7 @@
#define NET_HTTP_HTTP_NETWORK_SESSION_H_
#include "base/ref_counted.h"
+#include "net/base/ssl_client_auth_cache.h"
#include "net/base/ssl_config_service.h"
#include "net/base/tcp_client_socket_pool.h"
#include "net/http/http_auth_cache.h"
@@ -29,6 +30,9 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> {
}
HttpAuthCache* auth_cache() { return &auth_cache_; }
+ SSLClientAuthCache* ssl_client_auth_cache() {
+ return &ssl_client_auth_cache_;
+ }
ClientSocketPool* connection_pool() { return connection_pool_; }
HostResolver* host_resolver() { return host_resolver_; }
ProxyService* proxy_service() { return proxy_service_; }
@@ -45,6 +49,7 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> {
static int max_sockets_per_group_;
HttpAuthCache auth_cache_;
+ SSLClientAuthCache ssl_client_auth_cache_;
scoped_refptr<ClientSocketPool> connection_pool_;
HostResolver* host_resolver_;
ProxyService* proxy_service_;
diff --git a/net/net.gyp b/net/net.gyp
index 9296919..cbf302d 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -115,6 +115,8 @@
'base/sdch_manager.h',
'base/socket.h',
'base/ssl_cert_request_info.h',
+ 'base/ssl_client_auth_cache.cc',
+ 'base/ssl_client_auth_cache.h',
'base/ssl_client_socket.h',
'base/ssl_client_socket_mac.cc',
'base/ssl_client_socket_nss.cc',
@@ -420,6 +422,7 @@
'base/registry_controlled_domain_unittest.cc',
'base/run_all_unittests.cc',
'base/sdch_filter_unittest.cc',
+ 'base/ssl_client_auth_cache_unittest.cc',
'base/ssl_client_socket_unittest.cc',
'base/ssl_config_service_unittest.cc',
'base/tcp_client_socket_pool_unittest.cc',