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