diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-11 04:27:43 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-11 04:27:43 +0000 |
commit | 5482ef9ec189ae47ae1567eee7707de464e9325d (patch) | |
tree | 8b90133ed39f4242dc11d48801cf9ba59c35e45c /net | |
parent | 454da65a84f777a79703d7344395494ee2810e59 (diff) | |
download | chromium_src-5482ef9ec189ae47ae1567eee7707de464e9325d.zip chromium_src-5482ef9ec189ae47ae1567eee7707de464e9325d.tar.gz chromium_src-5482ef9ec189ae47ae1567eee7707de464e9325d.tar.bz2 |
Split net::ClientCertStoreImpl into actual platform-specific classes.
BUG=none
Review URL: https://codereview.chromium.org/108233005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240010 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/net.gyp | 31 | ||||
-rw-r--r-- | net/ssl/client_cert_store_impl.h | 79 | ||||
-rw-r--r-- | net/ssl/client_cert_store_impl_unittest.cc | 169 | ||||
-rw-r--r-- | net/ssl/client_cert_store_mac.cc (renamed from net/ssl/client_cert_store_impl_mac.cc) | 16 | ||||
-rw-r--r-- | net/ssl/client_cert_store_mac.h | 55 | ||||
-rw-r--r-- | net/ssl/client_cert_store_mac_unittest.cc | 89 | ||||
-rw-r--r-- | net/ssl/client_cert_store_nss.cc (renamed from net/ssl/client_cert_store_impl_nss.cc) | 19 | ||||
-rw-r--r-- | net/ssl/client_cert_store_nss.h | 56 | ||||
-rw-r--r-- | net/ssl/client_cert_store_nss_unittest.cc | 31 | ||||
-rw-r--r-- | net/ssl/client_cert_store_unittest-inl.h | 128 | ||||
-rw-r--r-- | net/ssl/client_cert_store_win.cc (renamed from net/ssl/client_cert_store_impl_win.cc) | 12 | ||||
-rw-r--r-- | net/ssl/client_cert_store_win.h | 43 | ||||
-rw-r--r-- | net/ssl/client_cert_store_win_unittest.cc | 28 |
13 files changed, 468 insertions, 288 deletions
diff --git a/net/net.gyp b/net/net.gyp index 7b17b60..b48a4c7 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -1021,10 +1021,12 @@ 'spdy/spdy_write_queue.h', 'spdy/write_blocked_list.h', 'ssl/client_cert_store.h', - 'ssl/client_cert_store_impl.h', - 'ssl/client_cert_store_impl_mac.cc', - 'ssl/client_cert_store_impl_nss.cc', - 'ssl/client_cert_store_impl_win.cc', + 'ssl/client_cert_store_mac.cc', + 'ssl/client_cert_store_mac.h', + 'ssl/client_cert_store_nss.cc', + 'ssl/client_cert_store_nss.h', + 'ssl/client_cert_store_win.cc', + 'ssl/client_cert_store_win.h', 'ssl/default_server_bound_cert_store.cc', 'ssl/default_server_bound_cert_store.h', 'ssl/openssl_client_key_store.cc', @@ -1310,7 +1312,6 @@ 'socket/ssl_client_socket_nss.h', 'socket/ssl_server_socket_nss.cc', 'socket/ssl_server_socket_nss.h', - 'ssl/client_cert_store_impl_nss.cc', 'third_party/mozilla_security_manager/nsKeygenHandler.cpp', 'third_party/mozilla_security_manager/nsKeygenHandler.h', 'third_party/mozilla_security_manager/nsNSSCertificateDB.cpp', @@ -1419,7 +1420,8 @@ 'sources!': [ 'cert/cert_verify_proc_nss.cc', 'cert/cert_verify_proc_nss.h', - 'ssl/client_cert_store_impl_nss.cc', + 'ssl/client_cert_store_nss.cc', + 'ssl/client_cert_store_nss.h', ], }], [ 'enable_websockets != 1', { @@ -1451,7 +1453,6 @@ 'http/http_auth_handler_ntlm_portable.cc', 'socket/tcp_socket_libevent.cc', 'socket/tcp_socket_libevent.h', - 'ssl/client_cert_store_impl_nss.cc', 'udp/udp_socket_libevent.cc', 'udp/udp_socket_libevent.h', ], @@ -1474,9 +1475,6 @@ }, ], [ 'OS == "mac"', { - 'sources!': [ - 'ssl/client_cert_store_impl_nss.cc', - ], 'dependencies': [ '../third_party/nss/nss.gyp:nspr', '../third_party/nss/nss.gyp:nss', @@ -1928,7 +1926,10 @@ 'spdy/spdy_websocket_test_util.h', 'spdy/spdy_write_queue_unittest.cc', 'spdy/write_blocked_list_test.cc', - 'ssl/client_cert_store_impl_unittest.cc', + 'ssl/client_cert_store_mac_unittest.cc', + 'ssl/client_cert_store_nss_unittest.cc', + 'ssl/client_cert_store_unittest-inl.h', + 'ssl/client_cert_store_win_unittest.cc', 'ssl/default_server_bound_cert_store_unittest.cc', 'ssl/openssl_client_key_store_unittest.cc', 'ssl/server_bound_cert_service_unittest.cc', @@ -2041,13 +2042,17 @@ # No res_ninit() et al on Android, so this doesn't make a lot of # sense. 'dns/dns_config_service_posix_unittest.cc', - 'ssl/client_cert_store_impl_unittest.cc', ], 'dependencies': [ 'net_javatests', 'net_test_jni_headers', ], }], + [ 'use_nss != 1', { + 'sources!': [ + 'ssl/client_cert_store_nss_unittest.cc', + ], + }], [ 'use_openssl == 1', { # Avoid compiling/linking with the system library. 'dependencies': [ @@ -2111,7 +2116,6 @@ 'cert/nss_cert_database_unittest.cc', 'cert/x509_util_nss_unittest.cc', 'quic/test_tools/crypto_test_utils_nss.cc', - 'ssl/client_cert_store_impl_unittest.cc', ], }, { # else !use_openssl: remove the unneeded files 'sources!': [ @@ -2223,7 +2227,6 @@ # Need TestServer. 'proxy/proxy_script_fetcher_impl_unittest.cc', 'socket/ssl_client_socket_unittest.cc', - 'ssl/client_cert_store_impl_unittest.cc', 'url_request/url_fetcher_impl_unittest.cc', 'url_request/url_request_context_builder_unittest.cc', # Needs GetAppOutput(). diff --git a/net/ssl/client_cert_store_impl.h b/net/ssl/client_cert_store_impl.h deleted file mode 100644 index 6a39c28..0000000 --- a/net/ssl/client_cert_store_impl.h +++ /dev/null @@ -1,79 +0,0 @@ -// 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 NET_SSL_CLIENT_CERT_STORE_IMPL_H_ -#define NET_SSL_CLIENT_CERT_STORE_IMPL_H_ - -#include "base/basictypes.h" -#include "base/callback.h" -#include "base/gtest_prod_util.h" -#include "net/base/net_export.h" -#include "net/ssl/client_cert_store.h" -#include "net/ssl/ssl_cert_request_info.h" - -namespace crypto { -class CryptoModuleBlockingPasswordDelegate; -} - -namespace net { - -class NET_EXPORT ClientCertStoreImpl : public ClientCertStore { - public: - ClientCertStoreImpl(); - virtual ~ClientCertStoreImpl(); - - // ClientCertStore: - virtual void GetClientCerts(const SSLCertRequestInfo& cert_request_info, - CertificateList* selected_certs, - const base::Closure& callback) OVERRIDE; - -#if defined(USE_NSS) - typedef base::Callback<crypto::CryptoModuleBlockingPasswordDelegate*( - const std::string& /* server */)> PasswordDelegateFactory; - // Set a factory that will be used to create a delegate for unlocking PKCS #11 - // tokens. The host:port string of the server requesting client auth will be - // passed to the factory. - void set_password_delegate_factory( - const PasswordDelegateFactory& password_delegate_factory); -#endif - - private: - friend class ClientCertStoreImplTest; - - // A hook for testing. Filters |input_certs| using the logic being used to - // filter the system store when GetClientCerts() is called. Depending on the - // implementation, this might be: - // - Implemented by creating a temporary in-memory store and filtering it - // using the common logic (preferable, currently on Windows). - // - Implemented by creating a list of certificates that otherwise would be - // extracted from the system store and filtering it using the common logic - // (less adequate, currently on NSS and Mac). - bool SelectClientCertsForTesting(const CertificateList& input_certs, - const SSLCertRequestInfo& cert_request_info, - CertificateList* selected_certs); - -#if defined(OS_MACOSX) && !defined(OS_IOS) - // Testing hook specific to Mac, where the internal logic recognizes preferred - // certificates for particular domains. If the preferred certificate is - // present in the output list (i.e. it doesn't get filtered out), it should - // always come first. - bool SelectClientCertsGivenPreferredForTesting( - const scoped_refptr<X509Certificate>& preferred_cert, - const CertificateList& regular_certs, - const SSLCertRequestInfo& request, - CertificateList* selected_certs); -#endif - -#if defined(USE_NSS) - // The factory for creating the delegate for requesting a password to a - // PKCS #11 token. May be null. - PasswordDelegateFactory password_delegate_factory_; -#endif // defined(USE_NSS) - - DISALLOW_COPY_AND_ASSIGN(ClientCertStoreImpl); -}; - -} // namespace net - -#endif // NET_SSL_CLIENT_CERT_STORE_IMPL_H_ diff --git a/net/ssl/client_cert_store_impl_unittest.cc b/net/ssl/client_cert_store_impl_unittest.cc deleted file mode 100644 index 500e156..0000000 --- a/net/ssl/client_cert_store_impl_unittest.cc +++ /dev/null @@ -1,169 +0,0 @@ -// 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 "net/ssl/client_cert_store_impl.h" - -#include <string> -#include <vector> - -#include "base/files/file_path.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "net/base/test_data_directory.h" -#include "net/test/cert_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -namespace { - -// "CN=B CA" - DER encoded DN of the issuer of client_1.pem -const unsigned char kAuthority1DN[] = { - 0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, - 0x04, 0x42, 0x20, 0x43, 0x41 -}; - -// "CN=E CA" - DER encoded DN of the issuer of client_2.pem -unsigned char kAuthority2DN[] = { - 0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, - 0x04, 0x45, 0x20, 0x43, 0x41 -}; - -} // namespace - -class ClientCertStoreImplTest : public ::testing::Test { - protected: - bool SelectClientCerts(const CertificateList& input_certs, - const SSLCertRequestInfo& cert_request_info, - CertificateList* selected_certs) { - return store_.SelectClientCertsForTesting( - input_certs, cert_request_info, selected_certs); - } - -#if defined(OS_MACOSX) && !defined(OS_IOS) - bool SelectClientCertsGivenPreferred( - const scoped_refptr<X509Certificate>& preferred_cert, - const CertificateList& regular_certs, - const SSLCertRequestInfo& request, - CertificateList* selected_certs) { - return store_.SelectClientCertsGivenPreferredForTesting( - preferred_cert, regular_certs, request, selected_certs); - } -#endif - - private: - ClientCertStoreImpl store_; -}; - -TEST_F(ClientCertStoreImplTest, EmptyQuery) { - std::vector<scoped_refptr<X509Certificate> > certs; - scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo()); - - std::vector<scoped_refptr<X509Certificate> > selected_certs; - bool rv = SelectClientCerts(certs, *request.get(), &selected_certs); - EXPECT_TRUE(rv); - EXPECT_EQ(0u, selected_certs.size()); -} - -// Verify that CertRequestInfo with empty |cert_authorities| matches all -// issuers, rather than no issuers. -TEST_F(ClientCertStoreImplTest, AllIssuersAllowed) { - scoped_refptr<X509Certificate> cert( - ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem")); - ASSERT_TRUE(cert.get()); - - std::vector<scoped_refptr<X509Certificate> > certs; - certs.push_back(cert); - scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo()); - - std::vector<scoped_refptr<X509Certificate> > selected_certs; - bool rv = SelectClientCerts(certs, *request.get(), &selected_certs); - EXPECT_TRUE(rv); - ASSERT_EQ(1u, selected_certs.size()); - EXPECT_TRUE(selected_certs[0]->Equals(cert.get())); -} - -// Verify that certificates are correctly filtered against CertRequestInfo with -// |cert_authorities| containing only |authority_1_DN|. -TEST_F(ClientCertStoreImplTest, CertAuthorityFiltering) { - scoped_refptr<X509Certificate> cert_1( - ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem")); - ASSERT_TRUE(cert_1.get()); - scoped_refptr<X509Certificate> cert_2( - ImportCertFromFile(GetTestCertsDirectory(), "client_2.pem")); - ASSERT_TRUE(cert_2.get()); - - std::vector<std::string> authority_1( - 1, std::string(reinterpret_cast<const char*>(kAuthority1DN), - sizeof(kAuthority1DN))); - std::vector<std::string> authority_2( - 1, std::string(reinterpret_cast<const char*>(kAuthority2DN), - sizeof(kAuthority2DN))); - EXPECT_TRUE(cert_1->IsIssuedByEncoded(authority_1)); - EXPECT_FALSE(cert_1->IsIssuedByEncoded(authority_2)); - EXPECT_TRUE(cert_2->IsIssuedByEncoded(authority_2)); - EXPECT_FALSE(cert_2->IsIssuedByEncoded(authority_1)); - - std::vector<scoped_refptr<X509Certificate> > certs; - certs.push_back(cert_1); - certs.push_back(cert_2); - scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo()); - request->cert_authorities = authority_1; - - std::vector<scoped_refptr<X509Certificate> > selected_certs; - bool rv = SelectClientCerts(certs, *request.get(), &selected_certs); - EXPECT_TRUE(rv); - ASSERT_EQ(1u, selected_certs.size()); - EXPECT_TRUE(selected_certs[0]->Equals(cert_1.get())); -} - -#if defined(OS_MACOSX) && !defined(OS_IOS) -// Verify that the preferred cert gets filtered out when it doesn't match the -// server criteria. -TEST_F(ClientCertStoreImplTest, FilterOutThePreferredCert) { - scoped_refptr<X509Certificate> cert_1( - ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem")); - ASSERT_TRUE(cert_1.get()); - - std::vector<std::string> authority_2( - 1, std::string(reinterpret_cast<const char*>(kAuthority2DN), - sizeof(kAuthority2DN))); - EXPECT_FALSE(cert_1->IsIssuedByEncoded(authority_2)); - - std::vector<scoped_refptr<X509Certificate> > certs; - scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo()); - request->cert_authorities = authority_2; - - std::vector<scoped_refptr<X509Certificate> > selected_certs; - bool rv = SelectClientCertsGivenPreferred( - cert_1, certs, *request.get(), &selected_certs); - EXPECT_TRUE(rv); - EXPECT_EQ(0u, selected_certs.size()); -} - -// Verify that the preferred cert takes the first position in the output list, -// when it does not get filtered out. -TEST_F(ClientCertStoreImplTest, PreferredCertGoesFirst) { - scoped_refptr<X509Certificate> cert_1( - ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem")); - ASSERT_TRUE(cert_1.get()); - scoped_refptr<X509Certificate> cert_2( - ImportCertFromFile(GetTestCertsDirectory(), "client_2.pem")); - ASSERT_TRUE(cert_2.get()); - - std::vector<scoped_refptr<X509Certificate> > certs; - certs.push_back(cert_2); - scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo()); - - std::vector<scoped_refptr<X509Certificate> > selected_certs; - bool rv = SelectClientCertsGivenPreferred( - cert_1, certs, *request.get(), &selected_certs); - EXPECT_TRUE(rv); - ASSERT_EQ(2u, selected_certs.size()); - EXPECT_TRUE(selected_certs[0]->Equals(cert_1.get())); - EXPECT_TRUE(selected_certs[1]->Equals(cert_2.get())); -} -#endif - -} // namespace net diff --git a/net/ssl/client_cert_store_impl_mac.cc b/net/ssl/client_cert_store_mac.cc index 25def0f..746d123 100644 --- a/net/ssl/client_cert_store_impl_mac.cc +++ b/net/ssl/client_cert_store_mac.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2013 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/ssl/client_cert_store_impl.h" +#include "net/ssl/client_cert_store_mac.h" #include <CommonCrypto/CommonDigest.h> #include <CoreFoundation/CFArray.h> @@ -172,11 +172,11 @@ void GetClientCertsImpl(const scoped_refptr<X509Certificate>& preferred_cert, } // namespace -ClientCertStoreImpl::ClientCertStoreImpl() {} +ClientCertStoreMac::ClientCertStoreMac() {} -ClientCertStoreImpl::~ClientCertStoreImpl() {} +ClientCertStoreMac::~ClientCertStoreMac() {} -void ClientCertStoreImpl::GetClientCerts(const SSLCertRequestInfo& request, +void ClientCertStoreMac::GetClientCerts(const SSLCertRequestInfo& request, CertificateList* selected_certs, const base::Closure& callback) { std::string server_domain = @@ -257,7 +257,7 @@ void ClientCertStoreImpl::GetClientCerts(const SSLCertRequestInfo& request, callback.Run(); } -bool ClientCertStoreImpl::SelectClientCertsForTesting( +bool ClientCertStoreMac::SelectClientCertsForTesting( const CertificateList& input_certs, const SSLCertRequestInfo& request, CertificateList* selected_certs) { @@ -265,8 +265,7 @@ bool ClientCertStoreImpl::SelectClientCertsForTesting( return true; } -#if !defined(OS_IOS) -bool ClientCertStoreImpl::SelectClientCertsGivenPreferredForTesting( +bool ClientCertStoreMac::SelectClientCertsGivenPreferredForTesting( const scoped_refptr<X509Certificate>& preferred_cert, const CertificateList& regular_certs, const SSLCertRequestInfo& request, @@ -275,6 +274,5 @@ bool ClientCertStoreImpl::SelectClientCertsGivenPreferredForTesting( preferred_cert, regular_certs, request, false, selected_certs); return true; } -#endif } // namespace net diff --git a/net/ssl/client_cert_store_mac.h b/net/ssl/client_cert_store_mac.h new file mode 100644 index 0000000..b3f7ef3 --- /dev/null +++ b/net/ssl/client_cert_store_mac.h @@ -0,0 +1,55 @@ +// Copyright 2013 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_SSL_CLIENT_CERT_STORE_MAC_H_ +#define NET_SSL_CLIENT_CERT_STORE_MAC_H_ + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/gtest_prod_util.h" +#include "net/base/net_export.h" +#include "net/ssl/client_cert_store.h" +#include "net/ssl/ssl_cert_request_info.h" + +namespace net { + +class NET_EXPORT ClientCertStoreMac : public ClientCertStore { + public: + ClientCertStoreMac(); + virtual ~ClientCertStoreMac(); + + // ClientCertStore: + virtual void GetClientCerts(const SSLCertRequestInfo& cert_request_info, + CertificateList* selected_certs, + const base::Closure& callback) OVERRIDE; + + private: + friend class ClientCertStoreMacTest; + friend class ClientCertStoreMacTestDelegate; + + // A hook for testing. Filters |input_certs| using the logic being used to + // filter the system store when GetClientCerts() is called. + // Implemented by creating a list of certificates that otherwise would be + // extracted from the system store and filtering it using the common logic + // (less adequate than the approach used on Windows). + bool SelectClientCertsForTesting(const CertificateList& input_certs, + const SSLCertRequestInfo& cert_request_info, + CertificateList* selected_certs); + + // Testing hook specific to Mac, where the internal logic recognizes preferred + // certificates for particular domains. If the preferred certificate is + // present in the output list (i.e. it doesn't get filtered out), it should + // always come first. + bool SelectClientCertsGivenPreferredForTesting( + const scoped_refptr<X509Certificate>& preferred_cert, + const CertificateList& regular_certs, + const SSLCertRequestInfo& request, + CertificateList* selected_certs); + + DISALLOW_COPY_AND_ASSIGN(ClientCertStoreMac); +}; + +} // namespace net + +#endif // NET_SSL_CLIENT_CERT_STORE_MAC_H_ diff --git a/net/ssl/client_cert_store_mac_unittest.cc b/net/ssl/client_cert_store_mac_unittest.cc new file mode 100644 index 0000000..6dc9279 --- /dev/null +++ b/net/ssl/client_cert_store_mac_unittest.cc @@ -0,0 +1,89 @@ +// Copyright 2013 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/ssl/client_cert_store_mac.h" + +#include "net/ssl/client_cert_store_unittest-inl.h" + +namespace net { + +class ClientCertStoreMacTestDelegate { + public: + bool SelectClientCerts(const CertificateList& input_certs, + const SSLCertRequestInfo& cert_request_info, + CertificateList* selected_certs) { + return store_.SelectClientCertsForTesting( + input_certs, cert_request_info, selected_certs); + } + + private: + ClientCertStoreMac store_; +}; + +INSTANTIATE_TYPED_TEST_CASE_P(Mac, + ClientCertStoreTest, + ClientCertStoreMacTestDelegate); + +class ClientCertStoreMacTest : public ::testing::Test { + protected: + bool SelectClientCertsGivenPreferred( + const scoped_refptr<X509Certificate>& preferred_cert, + const CertificateList& regular_certs, + const SSLCertRequestInfo& request, + CertificateList* selected_certs) { + return store_.SelectClientCertsGivenPreferredForTesting( + preferred_cert, regular_certs, request, selected_certs); + } + + private: + ClientCertStoreMac store_; +}; + +// Verify that the preferred cert gets filtered out when it doesn't match the +// server criteria. +TEST_F(ClientCertStoreMacTest, FilterOutThePreferredCert) { + scoped_refptr<X509Certificate> cert_1( + ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem")); + ASSERT_TRUE(cert_1.get()); + + std::vector<std::string> authority_2( + 1, std::string(reinterpret_cast<const char*>(kAuthority2DN), + sizeof(kAuthority2DN))); + EXPECT_FALSE(cert_1->IsIssuedByEncoded(authority_2)); + + std::vector<scoped_refptr<X509Certificate> > certs; + scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo()); + request->cert_authorities = authority_2; + + std::vector<scoped_refptr<X509Certificate> > selected_certs; + bool rv = SelectClientCertsGivenPreferred( + cert_1, certs, *request.get(), &selected_certs); + EXPECT_TRUE(rv); + EXPECT_EQ(0u, selected_certs.size()); +} + +// Verify that the preferred cert takes the first position in the output list, +// when it does not get filtered out. +TEST_F(ClientCertStoreMacTest, PreferredCertGoesFirst) { + scoped_refptr<X509Certificate> cert_1( + ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem")); + ASSERT_TRUE(cert_1.get()); + scoped_refptr<X509Certificate> cert_2( + ImportCertFromFile(GetTestCertsDirectory(), "client_2.pem")); + ASSERT_TRUE(cert_2.get()); + + std::vector<scoped_refptr<X509Certificate> > certs; + certs.push_back(cert_2); + scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo()); + + std::vector<scoped_refptr<X509Certificate> > selected_certs; + bool rv = SelectClientCertsGivenPreferred( + cert_1, certs, *request.get(), &selected_certs); + EXPECT_TRUE(rv); + ASSERT_EQ(2u, selected_certs.size()); + EXPECT_TRUE(selected_certs[0]->Equals(cert_1.get())); + EXPECT_TRUE(selected_certs[1]->Equals(cert_2.get())); +} + +} // namespace net diff --git a/net/ssl/client_cert_store_impl_nss.cc b/net/ssl/client_cert_store_nss.cc index 266fef9..6e82723 100644 --- a/net/ssl/client_cert_store_impl_nss.cc +++ b/net/ssl/client_cert_store_nss.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2013 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/ssl/client_cert_store_impl.h" +#include "net/ssl/client_cert_store_nss.h" #include <nss.h> #include <ssl.h> @@ -101,11 +101,13 @@ void GetClientCertsOnWorkerThread( } // namespace -ClientCertStoreImpl::ClientCertStoreImpl() {} +ClientCertStoreNSS::ClientCertStoreNSS( + const PasswordDelegateFactory& password_delegate_factory) + : password_delegate_factory_(password_delegate_factory) {} -ClientCertStoreImpl::~ClientCertStoreImpl() {} +ClientCertStoreNSS::~ClientCertStoreNSS() {} -void ClientCertStoreImpl::GetClientCerts(const SSLCertRequestInfo& request, +void ClientCertStoreNSS::GetClientCerts(const SSLCertRequestInfo& request, CertificateList* selected_certs, const base::Closure& callback) { scoped_ptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate; @@ -126,12 +128,7 @@ void ClientCertStoreImpl::GetClientCerts(const SSLCertRequestInfo& request, } } -void ClientCertStoreImpl::set_password_delegate_factory( - const PasswordDelegateFactory& password_delegate_factory) { - password_delegate_factory_ = password_delegate_factory; -} - -bool ClientCertStoreImpl::SelectClientCertsForTesting( +bool ClientCertStoreNSS::SelectClientCertsForTesting( const CertificateList& input_certs, const SSLCertRequestInfo& request, CertificateList* selected_certs) { diff --git a/net/ssl/client_cert_store_nss.h b/net/ssl/client_cert_store_nss.h new file mode 100644 index 0000000..53b7c60 --- /dev/null +++ b/net/ssl/client_cert_store_nss.h @@ -0,0 +1,56 @@ +// Copyright 2013 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_SSL_CLIENT_CERT_STORE_NSS_H_ +#define NET_SSL_CLIENT_CERT_STORE_NSS_H_ + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/gtest_prod_util.h" +#include "net/base/net_export.h" +#include "net/ssl/client_cert_store.h" +#include "net/ssl/ssl_cert_request_info.h" + +namespace crypto { +class CryptoModuleBlockingPasswordDelegate; +} + +namespace net { + +class NET_EXPORT ClientCertStoreNSS : public ClientCertStore { + public: + typedef base::Callback<crypto::CryptoModuleBlockingPasswordDelegate*( + const std::string& /* server */)> PasswordDelegateFactory; + + explicit ClientCertStoreNSS( + const PasswordDelegateFactory& password_delegate_factory); + virtual ~ClientCertStoreNSS(); + + // ClientCertStore: + virtual void GetClientCerts(const SSLCertRequestInfo& cert_request_info, + CertificateList* selected_certs, + const base::Closure& callback) OVERRIDE; + + private: + friend class ClientCertStoreNSSTestDelegate; + + // A hook for testing. Filters |input_certs| using the logic being used to + // filter the system store when GetClientCerts() is called. + // Implemented by creating a list of certificates that otherwise would be + // extracted from the system store and filtering it using the common logic + // (less adequate than the approach used on Windows). + bool SelectClientCertsForTesting(const CertificateList& input_certs, + const SSLCertRequestInfo& cert_request_info, + CertificateList* selected_certs); + + // The factory for creating the delegate for requesting a password to a + // PKCS #11 token. May be null. + PasswordDelegateFactory password_delegate_factory_; + + DISALLOW_COPY_AND_ASSIGN(ClientCertStoreNSS); +}; + +} // namespace net + +#endif // NET_SSL_CLIENT_CERT_STORE_NSS_H_ diff --git a/net/ssl/client_cert_store_nss_unittest.cc b/net/ssl/client_cert_store_nss_unittest.cc new file mode 100644 index 0000000..6690e67 --- /dev/null +++ b/net/ssl/client_cert_store_nss_unittest.cc @@ -0,0 +1,31 @@ +// Copyright 2013 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/ssl/client_cert_store_nss.h" + +#include "net/ssl/client_cert_store_unittest-inl.h" + +namespace net { + +class ClientCertStoreNSSTestDelegate { + public: + ClientCertStoreNSSTestDelegate() + : store_(ClientCertStoreNSS::PasswordDelegateFactory()) {} + + bool SelectClientCerts(const CertificateList& input_certs, + const SSLCertRequestInfo& cert_request_info, + CertificateList* selected_certs) { + return store_.SelectClientCertsForTesting( + input_certs, cert_request_info, selected_certs); + } + + private: + ClientCertStoreNSS store_; +}; + +INSTANTIATE_TYPED_TEST_CASE_P(NSS, + ClientCertStoreTest, + ClientCertStoreNSSTestDelegate); + +} // namespace net diff --git a/net/ssl/client_cert_store_unittest-inl.h b/net/ssl/client_cert_store_unittest-inl.h new file mode 100644 index 0000000..a0e29dc --- /dev/null +++ b/net/ssl/client_cert_store_unittest-inl.h @@ -0,0 +1,128 @@ +// Copyright 2013 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_SSL_CLIENT_CERT_STORE_UNITTEST_INL_H_ +#define NET_SSL_CLIENT_CERT_STORE_UNITTEST_INL_H_ + +#include <string> +#include <vector> + +#include "base/files/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "net/base/test_data_directory.h" +#include "net/test/cert_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { + +namespace { + +// "CN=B CA" - DER encoded DN of the issuer of client_1.pem +const unsigned char kAuthority1DN[] = { + 0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x04, 0x42, 0x20, 0x43, 0x41 +}; + +// "CN=E CA" - DER encoded DN of the issuer of client_2.pem +unsigned char kAuthority2DN[] = { + 0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x04, 0x45, 0x20, 0x43, 0x41 +}; + +} // namespace + +// Use a templated test to provide common testcases for all the platform +// implementations of ClientCertStore. These cases test the client cert +// filtering behavior. +// +// NOTE: If any test cases are added, removed, or renamed, the +// REGISTER_TYPED_TEST_CASE_P macro at the bottom of this file must be updated. +// +// The type T provided as the third argument to INSTANTIATE_TYPED_TEST_CASE_P by +// the platform implementation should implement this method: +// bool SelectClientCerts(const CertificateList& input_certs, +// const SSLCertRequestInfo& cert_request_info, +// CertificateList* selected_certs); +template <typename T> +class ClientCertStoreTest : public ::testing::Test { + public: + T delegate_; +}; + +TYPED_TEST_CASE_P(ClientCertStoreTest); + +TYPED_TEST_P(ClientCertStoreTest, EmptyQuery) { + std::vector<scoped_refptr<X509Certificate> > certs; + scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo()); + + std::vector<scoped_refptr<X509Certificate> > selected_certs; + bool rv = this->delegate_.SelectClientCerts( + certs, *request.get(), &selected_certs); + EXPECT_TRUE(rv); + EXPECT_EQ(0u, selected_certs.size()); +} + +// Verify that CertRequestInfo with empty |cert_authorities| matches all +// issuers, rather than no issuers. +TYPED_TEST_P(ClientCertStoreTest, AllIssuersAllowed) { + scoped_refptr<X509Certificate> cert( + ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem")); + ASSERT_TRUE(cert.get()); + + std::vector<scoped_refptr<X509Certificate> > certs; + certs.push_back(cert); + scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo()); + + std::vector<scoped_refptr<X509Certificate> > selected_certs; + bool rv = this->delegate_.SelectClientCerts( + certs, *request.get(), &selected_certs); + EXPECT_TRUE(rv); + ASSERT_EQ(1u, selected_certs.size()); + EXPECT_TRUE(selected_certs[0]->Equals(cert.get())); +} + +// Verify that certificates are correctly filtered against CertRequestInfo with +// |cert_authorities| containing only |authority_1_DN|. +TYPED_TEST_P(ClientCertStoreTest, CertAuthorityFiltering) { + scoped_refptr<X509Certificate> cert_1( + ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem")); + ASSERT_TRUE(cert_1.get()); + scoped_refptr<X509Certificate> cert_2( + ImportCertFromFile(GetTestCertsDirectory(), "client_2.pem")); + ASSERT_TRUE(cert_2.get()); + + std::vector<std::string> authority_1( + 1, std::string(reinterpret_cast<const char*>(kAuthority1DN), + sizeof(kAuthority1DN))); + std::vector<std::string> authority_2( + 1, std::string(reinterpret_cast<const char*>(kAuthority2DN), + sizeof(kAuthority2DN))); + EXPECT_TRUE(cert_1->IsIssuedByEncoded(authority_1)); + EXPECT_FALSE(cert_1->IsIssuedByEncoded(authority_2)); + EXPECT_TRUE(cert_2->IsIssuedByEncoded(authority_2)); + EXPECT_FALSE(cert_2->IsIssuedByEncoded(authority_1)); + + std::vector<scoped_refptr<X509Certificate> > certs; + certs.push_back(cert_1); + certs.push_back(cert_2); + scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo()); + request->cert_authorities = authority_1; + + std::vector<scoped_refptr<X509Certificate> > selected_certs; + bool rv = this->delegate_.SelectClientCerts( + certs, *request.get(), &selected_certs); + EXPECT_TRUE(rv); + ASSERT_EQ(1u, selected_certs.size()); + EXPECT_TRUE(selected_certs[0]->Equals(cert_1.get())); +} + +REGISTER_TYPED_TEST_CASE_P(ClientCertStoreTest, + EmptyQuery, + AllIssuersAllowed, + CertAuthorityFiltering); + +} // namespace net + +#endif // NET_SSL_CLIENT_CERT_STORE_UNITTEST_INL_H_ diff --git a/net/ssl/client_cert_store_impl_win.cc b/net/ssl/client_cert_store_win.cc index 936035e..24ae1aa 100644 --- a/net/ssl/client_cert_store_impl_win.cc +++ b/net/ssl/client_cert_store_win.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2013 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/ssl/client_cert_store_impl.h" +#include "net/ssl/client_cert_store_win.h" #include <algorithm> #include <string> @@ -143,11 +143,11 @@ void GetClientCertsImpl(HCERTSTORE cert_store, } // namespace -ClientCertStoreImpl::ClientCertStoreImpl() {} +ClientCertStoreWin::ClientCertStoreWin() {} -ClientCertStoreImpl::~ClientCertStoreImpl() {} +ClientCertStoreWin::~ClientCertStoreWin() {} -void ClientCertStoreImpl::GetClientCerts(const SSLCertRequestInfo& request, +void ClientCertStoreWin::GetClientCerts(const SSLCertRequestInfo& request, CertificateList* selected_certs, const base::Closure& callback) { // Client certificates of the user are in the "MY" system certificate store. @@ -165,7 +165,7 @@ void ClientCertStoreImpl::GetClientCerts(const SSLCertRequestInfo& request, callback.Run(); } -bool ClientCertStoreImpl::SelectClientCertsForTesting( +bool ClientCertStoreWin::SelectClientCertsForTesting( const CertificateList& input_certs, const SSLCertRequestInfo& request, CertificateList* selected_certs) { diff --git a/net/ssl/client_cert_store_win.h b/net/ssl/client_cert_store_win.h new file mode 100644 index 0000000..785603d --- /dev/null +++ b/net/ssl/client_cert_store_win.h @@ -0,0 +1,43 @@ +// Copyright 2013 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_SSL_CLIENT_CERT_STORE_WIN_H_ +#define NET_SSL_CLIENT_CERT_STORE_WIN_H_ + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/gtest_prod_util.h" +#include "net/base/net_export.h" +#include "net/ssl/client_cert_store.h" +#include "net/ssl/ssl_cert_request_info.h" + +namespace net { + +class NET_EXPORT ClientCertStoreWin : public ClientCertStore { + public: + ClientCertStoreWin(); + virtual ~ClientCertStoreWin(); + + // ClientCertStore: + virtual void GetClientCerts(const SSLCertRequestInfo& cert_request_info, + CertificateList* selected_certs, + const base::Closure& callback) OVERRIDE; + + private: + friend class ClientCertStoreWinTestDelegate; + + // A hook for testing. Filters |input_certs| using the logic being used to + // filter the system store when GetClientCerts() is called. + // Implemented by creating a temporary in-memory store and filtering it + // using the common logic. + bool SelectClientCertsForTesting(const CertificateList& input_certs, + const SSLCertRequestInfo& cert_request_info, + CertificateList* selected_certs); + + DISALLOW_COPY_AND_ASSIGN(ClientCertStoreWin); +}; + +} // namespace net + +#endif // NET_SSL_CLIENT_CERT_STORE_WIN_H_ diff --git a/net/ssl/client_cert_store_win_unittest.cc b/net/ssl/client_cert_store_win_unittest.cc new file mode 100644 index 0000000..eb8c0a6 --- /dev/null +++ b/net/ssl/client_cert_store_win_unittest.cc @@ -0,0 +1,28 @@ +// Copyright 2013 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/ssl/client_cert_store_win.h" + +#include "net/ssl/client_cert_store_unittest-inl.h" + +namespace net { + +class ClientCertStoreWinTestDelegate { + public: + bool SelectClientCerts(const CertificateList& input_certs, + const SSLCertRequestInfo& cert_request_info, + CertificateList* selected_certs) { + return store_.SelectClientCertsForTesting( + input_certs, cert_request_info, selected_certs); + } + + private: + ClientCertStoreWin store_; +}; + +INSTANTIATE_TYPED_TEST_CASE_P(Win, + ClientCertStoreTest, + ClientCertStoreWinTestDelegate); + +} // namespace net |