// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef NET_SOCKET_SSL_CLIENT_SOCKET_H_ #define NET_SOCKET_SSL_CLIENT_SOCKET_H_ #include #include #include #include "base/gtest_prod_util.h" #include "base/memory/raw_ptr.h" #include "base/observer_list.h" #include "net/base/net_export.h" #include "net/cert/cert_database.h" #include "net/socket/ssl_socket.h" #include "net/ssl/ssl_client_auth_cache.h" #include "net/ssl/ssl_config_service.h" namespace net { class CTPolicyEnforcer; class CertVerifier; class HostPortPair; class SCTAuditingDelegate; class SSLClientSessionCache; struct SSLConfig; class SSLKeyLogger; class StreamSocket; class TransportSecurityState; // A client socket that uses SSL as the transport layer. // // NOTE: The SSL handshake occurs within the Connect method after a TCP // connection is established. If a SSL error occurs during the handshake, // Connect will fail. // class NET_EXPORT SSLClientSocket : public SSLSocket { public: SSLClientSocket(); // Called in response to |ERR_ECH_NOT_NEGOTIATED| in Connect(), to determine // how to retry the connection, up to some limit. If this method returns a // non-empty string, it is the serialized updated ECHConfigList provided by // the server. The connection can be retried with the new value. If it returns // an empty string, the server has indicated ECH has been disabled. The // connection can be retried with ECH disabled. virtual std::vector GetECHRetryConfigs() = 0; // Log SSL key material to |logger|. Must be called before any // SSLClientSockets are created. // // TODO(davidben): Switch this to a parameter on the SSLClientSocketContext // once https://crbug.com/458365 is resolved. static void SetSSLKeyLogger(std::unique_ptr logger); protected: void set_signed_cert_timestamps_received( bool signed_cert_timestamps_received) { signed_cert_timestamps_received_ = signed_cert_timestamps_received; } void set_stapled_ocsp_response_received(bool stapled_ocsp_response_received) { stapled_ocsp_response_received_ = stapled_ocsp_response_received; } // Serialize |next_protos| in the wire format for ALPN: protocols are listed // in order, each prefixed by a one-byte length. static std::vector SerializeNextProtos( const NextProtoVector& next_protos); private: FRIEND_TEST_ALL_PREFIXES(SSLClientSocket, SerializeNextProtos); // For signed_cert_timestamps_received_ and stapled_ocsp_response_received_. FRIEND_TEST_ALL_PREFIXES(SSLClientSocketVersionTest, ConnectSignedCertTimestampsTLSExtension); FRIEND_TEST_ALL_PREFIXES(SSLClientSocketVersionTest, ConnectSignedCertTimestampsEnablesOCSP); // True if SCTs were received via a TLS extension. bool signed_cert_timestamps_received_ = false; // True if a stapled OCSP response was received. bool stapled_ocsp_response_received_ = false; }; // Shared state and configuration across multiple SSLClientSockets. class NET_EXPORT SSLClientContext : public SSLConfigService::Observer, public CertDatabase::Observer { public: class NET_EXPORT Observer : public base::CheckedObserver { public: // Called when SSL configuration for all hosts changed. Newly-created // SSLClientSockets will pick up the new configuration. Note that changes // which only apply to one server will result in a call to // OnSSLConfigForServerChanged() instead. virtual void OnSSLConfigChanged(bool is_cert_database_change) = 0; // Called when SSL configuration for |server| changed. Newly-created // SSLClientSockets to |server| will pick up the new configuration. virtual void OnSSLConfigForServerChanged(const HostPortPair& server) = 0; }; // Creates a new SSLClientContext with the specified parameters. The // SSLClientContext may not outlive the input parameters. // // |ssl_config_service| may be null to always use the default // SSLContextConfig. |ssl_client_session_cache| may be null to disable session // caching. |sct_auditing_delegate| may be null to disable SCT auditing. SSLClientContext(SSLConfigService* ssl_config_service, CertVerifier* cert_verifier, TransportSecurityState* transport_security_state, CTPolicyEnforcer* ct_policy_enforcer, SSLClientSessionCache* ssl_client_session_cache, SCTAuditingDelegate* sct_auditing_delegate); SSLClientContext(const SSLClientContext&) = delete; SSLClientContext& operator=(const SSLClientContext&) = delete; ~SSLClientContext() override; const SSLContextConfig& config() { return config_; } SSLConfigService* ssl_config_service() { return ssl_config_service_; } CertVerifier* cert_verifier() { return cert_verifier_; } TransportSecurityState* transport_security_state() { return transport_security_state_; } CTPolicyEnforcer* ct_policy_enforcer() { return ct_policy_enforcer_; } SSLClientSessionCache* ssl_client_session_cache() { return ssl_client_session_cache_; } SCTAuditingDelegate* sct_auditing_delegate() { return sct_auditing_delegate_; } // Returns whether ECH (Encrypted ClientHello) should be enabled. This // function checks both config() and feature flags. bool EncryptedClientHelloEnabled() const; // Creates a new SSLClientSocket which can then be used to establish an SSL // connection to |host_and_port| over the already-connected |stream_socket|. std::unique_ptr CreateSSLClientSocket( std::unique_ptr stream_socket, const HostPortPair& host_and_port, const SSLConfig& ssl_config); // Looks up the client certificate preference for |server|. If one is found, // returns true and sets |client_cert| and |private_key| to the certificate // and key. Note these may be null if the preference is to continue with no // client certificate. Returns false if no preferences are configured, // which means client certificate requests should be reported as // ERR_SSL_CLIENT_AUTH_CERT_NEEDED. bool GetClientCertificate(const HostPortPair& server, scoped_refptr* client_cert, scoped_refptr* private_key); // Configures all subsequent connections to |server| to authenticate with // |client_cert| and |private_key| when requested. If there is already a // client certificate for |server|, it will be overwritten. |client_cert| and // |private_key| may be null to indicate that no client certificate should be // sent to |server|. // // Note this method will synchronously call OnSSLConfigForServerChanged() on // observers. void SetClientCertificate(const HostPortPair& server, scoped_refptr client_cert, scoped_refptr private_key); // Clears a client certificate preference for |server| set by // SetClientCertificate(). Returns true if one was removed and false // otherwise. // // Note this method will synchronously call OnSSLConfigForServerChanged() on // observers. bool ClearClientCertificate(const HostPortPair& server); // Add an observer to be notified when configuration has changed. // RemoveObserver() must be called before |observer| is destroyed. void AddObserver(Observer* observer); // Remove an observer added with AddObserver(). void RemoveObserver(Observer* observer); // SSLConfigService::Observer: void OnSSLContextConfigChanged() override; // CertDatabase::Observer: void OnCertDBChanged() override; private: void NotifySSLConfigChanged(bool is_cert_database_change); void NotifySSLConfigForServerChanged(const HostPortPair& server); SSLContextConfig config_; raw_ptr ssl_config_service_; raw_ptr cert_verifier_; raw_ptr transport_security_state_; raw_ptr ct_policy_enforcer_; raw_ptr ssl_client_session_cache_; raw_ptr sct_auditing_delegate_; SSLClientAuthCache ssl_client_auth_cache_; base::ObserverList observers_; }; } // namespace net #endif // NET_SOCKET_SSL_CLIENT_SOCKET_H_