1 // Copyright 2012 The Chromium Authors 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 <stdint.h> 9 10 #include <memory> 11 #include <optional> 12 #include <set> 13 #include <string> 14 #include <vector> 15 16 #include "base/memory/ref_counted.h" 17 #include "base/time/time.h" 18 #include "net/base/completion_once_callback.h" 19 #include "net/base/completion_repeating_callback.h" 20 #include "net/base/net_export.h" 21 #include "net/base/network_anonymization_key.h" 22 #include "net/dns/public/host_resolver_results.h" 23 #include "net/dns/public/resolve_error_info.h" 24 #include "net/socket/connect_job.h" 25 #include "net/socket/connect_job_params.h" 26 #include "net/socket/connection_attempts.h" 27 #include "net/socket/ssl_client_socket.h" 28 #include "net/ssl/ssl_cert_request_info.h" 29 #include "net/ssl/ssl_config_service.h" 30 31 namespace net { 32 33 class HostPortPair; 34 class HttpProxySocketParams; 35 class SocketTag; 36 class SOCKSSocketParams; 37 class TransportSocketParams; 38 39 class NET_EXPORT_PRIVATE SSLSocketParams 40 : public base::RefCounted<SSLSocketParams> { 41 public: 42 enum ConnectionType { DIRECT, SOCKS_PROXY, HTTP_PROXY }; 43 44 // Exactly one of |direct_params|, |socks_proxy_params|, and 45 // |http_proxy_params| must be non-NULL. 46 SSLSocketParams(ConnectJobParams params, 47 const HostPortPair& host_and_port, 48 const SSLConfig& ssl_config, 49 NetworkAnonymizationKey network_anonymization_key); 50 51 SSLSocketParams(const SSLSocketParams&) = delete; 52 SSLSocketParams& operator=(const SSLSocketParams&) = delete; 53 54 // Returns the type of the underlying connection. 55 ConnectionType GetConnectionType() const; 56 57 // Must be called only when GetConnectionType() returns DIRECT. GetDirectConnectionParams()58 const scoped_refptr<TransportSocketParams>& GetDirectConnectionParams() 59 const { 60 return nested_params_.transport(); 61 } 62 63 // Must be called only when GetConnectionType() returns SOCKS_PROXY. GetSocksProxyConnectionParams()64 const scoped_refptr<SOCKSSocketParams>& GetSocksProxyConnectionParams() 65 const { 66 return nested_params_.socks(); 67 } 68 69 // Must be called only when GetConnectionType() returns HTTP_PROXY. GetHttpProxyConnectionParams()70 const scoped_refptr<HttpProxySocketParams>& GetHttpProxyConnectionParams() 71 const { 72 return nested_params_.http_proxy(); 73 } 74 host_and_port()75 const HostPortPair& host_and_port() const { return host_and_port_; } ssl_config()76 const SSLConfig& ssl_config() const { return ssl_config_; } network_anonymization_key()77 const NetworkAnonymizationKey& network_anonymization_key() const { 78 return network_anonymization_key_; 79 } 80 81 private: 82 friend class base::RefCounted<SSLSocketParams>; 83 ~SSLSocketParams(); 84 85 const ConnectJobParams nested_params_; 86 const HostPortPair host_and_port_; 87 const SSLConfig ssl_config_; 88 const NetworkAnonymizationKey network_anonymization_key_; 89 }; 90 91 // SSLConnectJob establishes a connection, through a proxy if needed, and then 92 // handles the SSL handshake. It returns an SSLClientSocket on success. 93 class NET_EXPORT_PRIVATE SSLConnectJob : public ConnectJob, 94 public ConnectJob::Delegate { 95 public: 96 class NET_EXPORT_PRIVATE Factory { 97 public: 98 Factory() = default; 99 virtual ~Factory() = default; 100 101 virtual std::unique_ptr<SSLConnectJob> Create( 102 RequestPriority priority, 103 const SocketTag& socket_tag, 104 const CommonConnectJobParams* common_connect_job_params, 105 scoped_refptr<SSLSocketParams> params, 106 ConnectJob::Delegate* delegate, 107 const NetLogWithSource* net_log); 108 }; 109 110 SSLConnectJob(RequestPriority priority, 111 const SocketTag& socket_tag, 112 const CommonConnectJobParams* common_connect_job_params, 113 scoped_refptr<SSLSocketParams> params, 114 ConnectJob::Delegate* delegate, 115 const NetLogWithSource* net_log); 116 117 SSLConnectJob(const SSLConnectJob&) = delete; 118 SSLConnectJob& operator=(const SSLConnectJob&) = delete; 119 120 ~SSLConnectJob() override; 121 122 // ConnectJob methods. 123 LoadState GetLoadState() const override; 124 bool HasEstablishedConnection() const override; 125 126 // ConnectJob::Delegate methods. 127 void OnConnectJobComplete(int result, ConnectJob* job) override; 128 void OnNeedsProxyAuth(const HttpResponseInfo& response, 129 HttpAuthController* auth_controller, 130 base::OnceClosure restart_with_auth_callback, 131 ConnectJob* job) override; 132 ConnectionAttempts GetConnectionAttempts() const override; 133 ResolveErrorInfo GetResolveErrorInfo() const override; 134 bool IsSSLError() const override; 135 scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override; 136 137 // Returns the timeout for the SSL handshake. This is the same for all 138 // connections regardless of whether or not there is a proxy in use. 139 static base::TimeDelta HandshakeTimeoutForTesting(); 140 141 private: 142 enum State { 143 STATE_TRANSPORT_CONNECT, 144 STATE_TRANSPORT_CONNECT_COMPLETE, 145 STATE_SOCKS_CONNECT, 146 STATE_SOCKS_CONNECT_COMPLETE, 147 STATE_TUNNEL_CONNECT, 148 STATE_TUNNEL_CONNECT_COMPLETE, 149 STATE_SSL_CONNECT, 150 STATE_SSL_CONNECT_COMPLETE, 151 STATE_NONE, 152 }; 153 154 void OnIOComplete(int result); 155 156 // Runs the state transition loop. 157 int DoLoop(int result); 158 159 int DoTransportConnect(); 160 int DoTransportConnectComplete(int result); 161 int DoSOCKSConnect(); 162 int DoSOCKSConnectComplete(int result); 163 int DoTunnelConnect(); 164 int DoTunnelConnectComplete(int result); 165 int DoSSLConnect(); 166 int DoSSLConnectComplete(int result); 167 168 // Returns the initial state for the state machine based on the 169 // |connection_type|. 170 static State GetInitialState(SSLSocketParams::ConnectionType connection_type); 171 172 // Starts the SSL connection process. Returns OK on success and 173 // ERR_IO_PENDING if it cannot immediately service the request. 174 // Otherwise, it returns a net error code. 175 int ConnectInternal() override; 176 177 void ResetStateForRestart(); 178 179 void ChangePriorityInternal(RequestPriority priority) override; 180 181 scoped_refptr<SSLSocketParams> params_; 182 183 State next_state_; 184 CompletionRepeatingCallback callback_; 185 std::unique_ptr<ConnectJob> nested_connect_job_; 186 std::unique_ptr<StreamSocket> nested_socket_; 187 std::unique_ptr<SSLClientSocket> ssl_socket_; 188 189 // True once SSL negotiation has started. 190 bool ssl_negotiation_started_ = false; 191 192 // True if legacy crypto should be disabled for the job's current connection 193 // attempt. On error, the connection will be retried with legacy crypto 194 // enabled. 195 bool disable_legacy_crypto_with_fallback_ = true; 196 197 scoped_refptr<SSLCertRequestInfo> ssl_cert_request_info_; 198 199 ConnectionAttempts connection_attempts_; 200 ResolveErrorInfo resolve_error_info_; 201 // The address of the server the connect job is connected to. Populated if 202 // and only if the connect job is connected *directly* to the server (not 203 // through an HTTPS CONNECT request or a SOCKS proxy). 204 IPEndPoint server_address_; 205 206 // Any DNS aliases for the remote endpoint. Includes all known aliases, e.g. 207 // from A, AAAA, or HTTPS, not just from the address used for the connection, 208 // in no particular order. Stored because `nested_connect_job_` has a limited 209 // lifetime and the aliases can no longer be retrieved from there by by the 210 // time that the aliases are needed to be passed in SetSocket. 211 std::set<std::string> dns_aliases_; 212 213 // The endpoint result used by `nested_connect_job_`. Stored because 214 // `nested_connect_job_` has a limited lifetime. 215 std::optional<HostResolverEndpointResult> endpoint_result_; 216 217 // If not `std::nullopt`, the ECH retry configs to use in the ECH recovery 218 // flow. `endpoint_result_` will then contain the endpoint to reconnect to. 219 std::optional<std::vector<uint8_t>> ech_retry_configs_; 220 }; 221 222 } // namespace net 223 224 #endif // NET_SOCKET_SSL_CONNECT_JOB_H_ 225