1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/socket/client_socket_factory.h"
7 #include "base/lazy_instance.h"
8 #include "base/thread_task_runner_handle.h"
9 #include "base/threading/sequenced_worker_pool.h"
10 #include "build/build_config.h"
11 #include "net/base/cert_database.h"
12 #include "net/socket/client_socket_handle.h"
14 #include "net/socket/ssl_client_socket_nss.h"
15 #include "net/socket/ssl_client_socket_win.h"
16 #elif defined(USE_OPENSSL)
17 #include "net/socket/ssl_client_socket_openssl.h"
18 #elif defined(USE_NSS) || defined(OS_IOS)
19 #include "net/socket/ssl_client_socket_nss.h"
20 #elif defined(OS_MACOSX)
21 #include "net/socket/ssl_client_socket_mac.h"
22 #include "net/socket/ssl_client_socket_nss.h"
24 #include "net/socket/tcp_client_socket.h"
25 #include "net/udp/udp_client_socket.h"
29 class X509Certificate
;
33 bool g_use_system_ssl
= false;
35 // ChromeOS and Linux may require interaction with smart cards or TPMs, which
36 // may cause NSS functions to block for upwards of several seconds. To avoid
37 // blocking all activity on the current task runner, such as network or IPC
38 // traffic, run NSS SSL functions on a dedicated thread.
39 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
40 bool g_use_dedicated_nss_thread
= true;
42 bool g_use_dedicated_nss_thread
= false;
45 class DefaultClientSocketFactory
: public ClientSocketFactory
,
46 public CertDatabase::Observer
{
48 DefaultClientSocketFactory() {
49 if (g_use_dedicated_nss_thread
) {
50 // Use a single thread for the worker pool.
51 worker_pool_
= new base::SequencedWorkerPool(1, "NSS SSL Thread");
52 nss_thread_task_runner_
=
53 worker_pool_
->GetSequencedTaskRunnerWithShutdownBehavior(
54 worker_pool_
->GetSequenceToken(),
55 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
);
58 CertDatabase::GetInstance()->AddObserver(this);
61 virtual ~DefaultClientSocketFactory() {
62 // Note: This code never runs, as the factory is defined as a Leaky
64 CertDatabase::GetInstance()->RemoveObserver(this);
67 virtual void OnCertAdded(const X509Certificate
* cert
) OVERRIDE
{
68 ClearSSLSessionCache();
71 virtual void OnCertTrustChanged(const X509Certificate
* cert
) OVERRIDE
{
72 // Per wtc, we actually only need to flush when trust is reduced.
73 // Always flush now because OnCertTrustChanged does not tell us this.
74 // See comments in ClientSocketPoolManager::OnCertTrustChanged.
75 ClearSSLSessionCache();
78 virtual DatagramClientSocket
* CreateDatagramClientSocket(
79 DatagramSocket::BindType bind_type
,
80 const RandIntCallback
& rand_int_cb
,
82 const NetLog::Source
& source
) OVERRIDE
{
83 return new UDPClientSocket(bind_type
, rand_int_cb
, net_log
, source
);
86 virtual StreamSocket
* CreateTransportClientSocket(
87 const AddressList
& addresses
,
89 const NetLog::Source
& source
) OVERRIDE
{
90 return new TCPClientSocket(addresses
, net_log
, source
);
93 virtual SSLClientSocket
* CreateSSLClientSocket(
94 ClientSocketHandle
* transport_socket
,
95 const HostPortPair
& host_and_port
,
96 const SSLConfig
& ssl_config
,
97 const SSLClientSocketContext
& context
) OVERRIDE
{
98 // nss_thread_task_runner_ may be NULL if g_use_dedicated_nss_thread is
99 // false or if the dedicated NSS thread failed to start. If so, cause NSS
100 // functions to execute on the current task runner.
102 // Note: The current task runner is obtained on each call due to unit
103 // tests, which may create and tear down the current thread's TaskRunner
104 // between each test. Because the DefaultClientSocketFactory is leaky, it
105 // may span multiple tests, and thus the current task runner may change
106 // from call to call.
107 scoped_refptr
<base::SequencedTaskRunner
> nss_task_runner(
108 nss_thread_task_runner_
);
109 if (!nss_task_runner
)
110 nss_task_runner
= base::ThreadTaskRunnerHandle::Get();
112 #if defined(USE_OPENSSL)
113 return new SSLClientSocketOpenSSL(transport_socket
, host_and_port
,
114 ssl_config
, context
);
115 #elif defined(USE_NSS) || defined(OS_IOS)
116 return new SSLClientSocketNSS(nss_task_runner
, transport_socket
,
117 host_and_port
, ssl_config
, context
);
118 #elif defined(OS_WIN)
119 if (g_use_system_ssl
) {
120 return new SSLClientSocketWin(transport_socket
, host_and_port
,
121 ssl_config
, context
);
123 return new SSLClientSocketNSS(nss_task_runner
, transport_socket
,
124 host_and_port
, ssl_config
,
126 #elif defined(OS_MACOSX)
127 if (g_use_system_ssl
) {
128 return new SSLClientSocketMac(transport_socket
, host_and_port
,
129 ssl_config
, context
);
131 return new SSLClientSocketNSS(nss_task_runner
, transport_socket
,
132 host_and_port
, ssl_config
,
140 virtual void ClearSSLSessionCache() OVERRIDE
{
141 SSLClientSocket::ClearSessionCache();
145 scoped_refptr
<base::SequencedWorkerPool
> worker_pool_
;
146 scoped_refptr
<base::SequencedTaskRunner
> nss_thread_task_runner_
;
149 static base::LazyInstance
<DefaultClientSocketFactory
>::Leaky
150 g_default_client_socket_factory
= LAZY_INSTANCE_INITIALIZER
;
154 // Deprecated function (http://crbug.com/37810) that takes a StreamSocket.
155 SSLClientSocket
* ClientSocketFactory::CreateSSLClientSocket(
156 StreamSocket
* transport_socket
,
157 const HostPortPair
& host_and_port
,
158 const SSLConfig
& ssl_config
,
159 const SSLClientSocketContext
& context
) {
160 ClientSocketHandle
* socket_handle
= new ClientSocketHandle();
161 socket_handle
->set_socket(transport_socket
);
162 return CreateSSLClientSocket(socket_handle
, host_and_port
, ssl_config
,
167 ClientSocketFactory
* ClientSocketFactory::GetDefaultFactory() {
168 return g_default_client_socket_factory
.Pointer();
172 void ClientSocketFactory::UseSystemSSL() {
173 g_use_system_ssl
= true;
176 // Reflect the capability of SSLClientSocketWin.
177 SSLConfigService::SetDefaultVersionMax(SSL_PROTOCOL_VERSION_TLS1
);
178 #elif defined(OS_MACOSX) && !defined(OS_IOS)
179 // Reflect the capability of SSLClientSocketMac.
180 SSLConfigService::SetDefaultVersionMax(SSL_PROTOCOL_VERSION_TLS1
);