diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-18 19:38:58 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-18 19:38:58 +0000 |
commit | 56c866a252b4a7dcb525b0b29bafc4de0168b7bb (patch) | |
tree | 3eb4f9f77dede3481a05e9e2d730dbace83d13fd /net | |
parent | 1a041bb64d411c1902e005cdc1a904607016f707 (diff) | |
download | chromium_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.cc | 25 | ||||
-rw-r--r-- | net/base/ssl_client_auth_cache.h | 51 | ||||
-rw-r--r-- | net/base/ssl_client_auth_cache_unittest.cc | 81 | ||||
-rw-r--r-- | net/ftp/ftp_auth_cache.h | 2 | ||||
-rw-r--r-- | net/http/http_network_session.h | 7 | ||||
-rw-r--r-- | net/net.gyp | 3 |
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', |