1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket_factory.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/lazy_instance.h" 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "build/build_config.h" 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/cert_database.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket/client_socket_handle.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/socket/ssl_client_socket_nss.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/ssl_client_socket_win.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#elif defined(USE_OPENSSL) 153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/socket/ssl_client_socket_openssl.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(USE_NSS) 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/ssl_client_socket_nss.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_MACOSX) 19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/socket/ssl_client_socket_mac.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket/ssl_client_socket_nss.h" 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/socket/ssl_host_info.h" 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/tcp_client_socket.h" 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass X509Certificate; 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool g_use_system_ssl = false; 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass DefaultClientSocketFactory : public ClientSocketFactory, 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public CertDatabase::Observer { 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DefaultClientSocketFactory() { 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CertDatabase::AddObserver(this); 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual ~DefaultClientSocketFactory() { 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CertDatabase::RemoveObserver(this); 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void OnUserCertAdded(const X509Certificate* cert) { 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ClearSSLSessionCache(); 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void OnCertTrustChanged(const X509Certificate* cert) { 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Per wtc, we actually only need to flush when trust is reduced. 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Always flush now because OnCertTrustChanged does not tell us this. 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // See comments in ClientSocketPoolManager::OnCertTrustChanged. 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ClearSSLSessionCache(); 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual ClientSocket* CreateTransportClientSocket( 563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const AddressList& addresses, 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NetLog* net_log, 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const NetLog::Source& source) { 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return new TCPClientSocket(addresses, net_log, source); 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual SSLClientSocket* CreateSSLClientSocket( 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClientSocketHandle* transport_socket, 644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const HostPortPair& host_and_port, 65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const SSLConfig& ssl_config, 66513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SSLHostInfo* ssl_host_info, 6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CertVerifier* cert_verifier, 68201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DnsCertProvenanceChecker* dns_cert_checker) { 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<SSLHostInfo> shi(ssl_host_info); 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (g_use_system_ssl) { 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return new SSLClientSocketWin(transport_socket, host_and_port, 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ssl_config, cert_verifier); 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return new SSLClientSocketNSS(transport_socket, host_and_port, ssl_config, 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen shi.release(), cert_verifier, 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen dns_cert_checker); 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(USE_OPENSSL) 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return new SSLClientSocketOpenSSL(transport_socket, host_and_port, 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ssl_config, cert_verifier); 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(USE_NSS) 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return new SSLClientSocketNSS(transport_socket, host_and_port, ssl_config, 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen shi.release(), cert_verifier, 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen dns_cert_checker); 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(OS_MACOSX) 86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (g_use_system_ssl) { 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return new SSLClientSocketMac(transport_socket, host_and_port, 88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ssl_config, cert_verifier); 89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return new SSLClientSocketNSS(transport_socket, host_and_port, ssl_config, 91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen shi.release(), cert_verifier, 92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen dns_cert_checker); 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#else 94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NOTIMPLEMENTED(); 95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return NULL; 96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // TODO(rch): This is only implemented for the NSS SSL library, which is the 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen /// default for Windows, Mac and Linux, but we should implement it everywhere. 101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void ClearSSLSessionCache() { 102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!g_use_system_ssl) 104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSLClientSocketNSS::ClearSessionCache(); 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(USE_OPENSSL) 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // no-op 107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(USE_NSS) 108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSLClientSocketNSS::ClearSessionCache(); 109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(OS_MACOSX) 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!g_use_system_ssl) 111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSLClientSocketNSS::ClearSessionCache(); 112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#else 113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NOTIMPLEMENTED(); 114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstatic base::LazyInstance<DefaultClientSocketFactory> 12021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen g_default_client_socket_factory(base::LINKER_INITIALIZED); 12121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Deprecated function (http://crbug.com/37810) that takes a ClientSocket. 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSSLClientSocket* ClientSocketFactory::CreateSSLClientSocket( 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClientSocket* transport_socket, 1274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const HostPortPair& host_and_port, 128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const SSLConfig& ssl_config, 12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSLHostInfo* ssl_host_info, 13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CertVerifier* cert_verifier) { 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClientSocketHandle* socket_handle = new ClientSocketHandle(); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch socket_handle->set_socket(transport_socket); 1334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return CreateSSLClientSocket(socket_handle, host_and_port, ssl_config, 13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_host_info, cert_verifier, 135201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NULL /* DnsCertProvenanceChecker */); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static 13972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenClientSocketFactory* ClientSocketFactory::GetDefaultFactory() { 14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return g_default_client_socket_factory.Pointer(); 14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static 144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ClientSocketFactory::UseSystemSSL() { 145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen g_use_system_ssl = true; 14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 149