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.
4 
5 #ifndef NET_SOCKET_SSL_CONNECT_JOB_H_
6 #define NET_SOCKET_SSL_CONNECT_JOB_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "base/macros.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/time/time.h"
14 #include "net/base/completion_once_callback.h"
15 #include "net/base/completion_repeating_callback.h"
16 #include "net/base/net_export.h"
17 #include "net/base/network_isolation_key.h"
18 #include "net/base/privacy_mode.h"
19 #include "net/dns/public/resolve_error_info.h"
20 #include "net/socket/connect_job.h"
21 #include "net/socket/connection_attempts.h"
22 #include "net/socket/ssl_client_socket.h"
23 #include "net/ssl/ssl_cert_request_info.h"
24 #include "net/ssl/ssl_config_service.h"
25 
26 namespace net {
27 
28 class HostPortPair;
29 class HttpProxySocketParams;
30 class SocketTag;
31 class SOCKSSocketParams;
32 class TransportSocketParams;
33 
34 class NET_EXPORT_PRIVATE SSLSocketParams
35     : public base::RefCounted<SSLSocketParams> {
36  public:
37   enum ConnectionType { DIRECT, SOCKS_PROXY, HTTP_PROXY };
38 
39   // Exactly one of |direct_params|, |socks_proxy_params|, and
40   // |http_proxy_params| must be non-NULL.
41   SSLSocketParams(scoped_refptr<TransportSocketParams> direct_params,
42                   scoped_refptr<SOCKSSocketParams> socks_proxy_params,
43                   scoped_refptr<HttpProxySocketParams> http_proxy_params,
44                   const HostPortPair& host_and_port,
45                   const SSLConfig& ssl_config,
46                   PrivacyMode privacy_mode,
47                   NetworkIsolationKey network_isolation_key);
48 
49   // Returns the type of the underlying connection.
50   ConnectionType GetConnectionType() const;
51 
52   // Must be called only when GetConnectionType() returns DIRECT.
53   const scoped_refptr<TransportSocketParams>& GetDirectConnectionParams() const;
54 
55   // Must be called only when GetConnectionType() returns SOCKS_PROXY.
56   const scoped_refptr<SOCKSSocketParams>& GetSocksProxyConnectionParams() const;
57 
58   // Must be called only when GetConnectionType() returns HTTP_PROXY.
59   const scoped_refptr<HttpProxySocketParams>& GetHttpProxyConnectionParams()
60       const;
61 
host_and_port()62   const HostPortPair& host_and_port() const { return host_and_port_; }
ssl_config()63   const SSLConfig& ssl_config() const { return ssl_config_; }
privacy_mode()64   PrivacyMode privacy_mode() const { return privacy_mode_; }
network_isolation_key()65   const NetworkIsolationKey& network_isolation_key() const {
66     return network_isolation_key_;
67   }
68 
69  private:
70   friend class base::RefCounted<SSLSocketParams>;
71   ~SSLSocketParams();
72 
73   const scoped_refptr<TransportSocketParams> direct_params_;
74   const scoped_refptr<SOCKSSocketParams> socks_proxy_params_;
75   const scoped_refptr<HttpProxySocketParams> http_proxy_params_;
76   const HostPortPair host_and_port_;
77   const SSLConfig ssl_config_;
78   const PrivacyMode privacy_mode_;
79   const NetworkIsolationKey network_isolation_key_;
80 
81   DISALLOW_COPY_AND_ASSIGN(SSLSocketParams);
82 };
83 
84 // SSLConnectJob establishes a connection, through a proxy if needed, and then
85 // handles the SSL handshake. It returns an SSLClientSocket on success.
86 class NET_EXPORT_PRIVATE SSLConnectJob : public ConnectJob,
87                                          public ConnectJob::Delegate {
88  public:
89   // Note: the SSLConnectJob does not own |messenger| so it must outlive the
90   // job.
91   SSLConnectJob(RequestPriority priority,
92                 const SocketTag& socket_tag,
93                 const CommonConnectJobParams* common_connect_job_params,
94                 scoped_refptr<SSLSocketParams> params,
95                 ConnectJob::Delegate* delegate,
96                 const NetLogWithSource* net_log);
97   ~SSLConnectJob() override;
98 
99   // ConnectJob methods.
100   LoadState GetLoadState() const override;
101   bool HasEstablishedConnection() const override;
102 
103   // ConnectJob::Delegate methods.
104   void OnConnectJobComplete(int result, ConnectJob* job) override;
105   void OnNeedsProxyAuth(const HttpResponseInfo& response,
106                         HttpAuthController* auth_controller,
107                         base::OnceClosure restart_with_auth_callback,
108                         ConnectJob* job) override;
109   ConnectionAttempts GetConnectionAttempts() const override;
110   ResolveErrorInfo GetResolveErrorInfo() const override;
111   bool IsSSLError() const override;
112   scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override;
113 
114   // Returns the timeout for the SSL handshake. This is the same for all
115   // connections regardless of whether or not there is a proxy in use.
116   static base::TimeDelta HandshakeTimeoutForTesting();
117 
118  private:
119   enum State {
120     STATE_TRANSPORT_CONNECT,
121     STATE_TRANSPORT_CONNECT_COMPLETE,
122     STATE_SOCKS_CONNECT,
123     STATE_SOCKS_CONNECT_COMPLETE,
124     STATE_TUNNEL_CONNECT,
125     STATE_TUNNEL_CONNECT_COMPLETE,
126     STATE_SSL_CONNECT,
127     STATE_SSL_CONNECT_COMPLETE,
128     STATE_NONE,
129   };
130 
131   void OnIOComplete(int result);
132 
133   // Runs the state transition loop.
134   int DoLoop(int result);
135 
136   int DoTransportConnect();
137   int DoTransportConnectComplete(int result);
138   int DoSOCKSConnect();
139   int DoSOCKSConnectComplete(int result);
140   int DoTunnelConnect();
141   int DoTunnelConnectComplete(int result);
142   int DoSSLConnect();
143   int DoSSLConnectComplete(int result);
144 
145   // Returns the initial state for the state machine based on the
146   // |connection_type|.
147   static State GetInitialState(SSLSocketParams::ConnectionType connection_type);
148 
149   // Starts the SSL connection process.  Returns OK on success and
150   // ERR_IO_PENDING if it cannot immediately service the request.
151   // Otherwise, it returns a net error code.
152   int ConnectInternal() override;
153 
154   void ResetStateForRestart();
155 
156   void ChangePriorityInternal(RequestPriority priority) override;
157 
158   scoped_refptr<SSLSocketParams> params_;
159 
160   State next_state_;
161   CompletionRepeatingCallback callback_;
162   std::unique_ptr<ConnectJob> nested_connect_job_;
163   std::unique_ptr<StreamSocket> nested_socket_;
164   std::unique_ptr<SSLClientSocket> ssl_socket_;
165 
166   // True once SSL negotiation has started.
167   bool ssl_negotiation_started_;
168 
169   // True if legacy crypto should be disabled for the job's current connection
170   // attempt. On error, the connection will be retried with legacy crypto
171   // enabled.
172   bool disable_legacy_crypto_with_fallback_;
173 
174   scoped_refptr<SSLCertRequestInfo> ssl_cert_request_info_;
175 
176   ConnectionAttempts connection_attempts_;
177   ResolveErrorInfo resolve_error_info_;
178   // The address of the server the connect job is connected to. Populated if
179   // and only if the connect job is connected *directly* to the server (not
180   // through an HTTPS CONNECT request or a SOCKS proxy).
181   IPEndPoint server_address_;
182 
183   DISALLOW_COPY_AND_ASSIGN(SSLConnectJob);
184 };
185 
186 }  // namespace net
187 
188 #endif  // NET_SOCKET_SSL_CONNECT_JOB_H_
189