Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ | 5 #ifndef NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ |
| 6 #define NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ | 6 #define NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ |
| 7 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include <certt.h> | 9 #include <certt.h> |
| 10 #include <keyt.h> | 10 #include <keyt.h> |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 #include "net/base/completion_callback.h" | 23 #include "net/base/completion_callback.h" |
| 24 #include "net/base/host_port_pair.h" | 24 #include "net/base/host_port_pair.h" |
| 25 #include "net/base/net_export.h" | 25 #include "net/base/net_export.h" |
| 26 #include "net/base/net_log.h" | 26 #include "net/base/net_log.h" |
| 27 #include "net/base/nss_memio.h" | 27 #include "net/base/nss_memio.h" |
| 28 #include "net/base/server_bound_cert_service.h" | 28 #include "net/base/server_bound_cert_service.h" |
| 29 #include "net/base/ssl_config_service.h" | 29 #include "net/base/ssl_config_service.h" |
| 30 #include "net/base/x509_certificate.h" | 30 #include "net/base/x509_certificate.h" |
| 31 #include "net/socket/ssl_client_socket.h" | 31 #include "net/socket/ssl_client_socket.h" |
| 32 | 32 |
| 33 namespace base { | |
| 34 class SingleThreadTaskRunner; | |
| 35 } | |
| 36 | |
| 33 namespace net { | 37 namespace net { |
| 34 | 38 |
| 35 class BoundNetLog; | 39 class BoundNetLog; |
| 36 class CertVerifier; | 40 class CertVerifier; |
| 37 class ClientSocketHandle; | 41 class ClientSocketHandle; |
| 38 class ServerBoundCertService; | 42 class ServerBoundCertService; |
| 39 class SingleRequestCertVerifier; | 43 class SingleRequestCertVerifier; |
| 40 class SSLHostInfo; | 44 class SSLHostInfo; |
| 41 class TransportSecurityState; | 45 class TransportSecurityState; |
| 42 class X509Certificate; | 46 class X509Certificate; |
| 43 | 47 |
| 44 // An SSL client socket implemented with Mozilla NSS. | 48 // An SSL client socket implemented with Mozilla NSS. |
| 45 class SSLClientSocketNSS : public SSLClientSocket { | 49 class SSLClientSocketNSS : public SSLClientSocket { |
| 46 public: | 50 public: |
| 47 // Takes ownership of the |transport_socket|, which must already be connected. | 51 // Takes ownership of the |transport_socket|, which must already be connected. |
| 48 // The hostname specified in |host_and_port| will be compared with the name(s) | 52 // The hostname specified in |host_and_port| will be compared with the name(s) |
| 49 // in the server's certificate during the SSL handshake. If SSL client | 53 // in the server's certificate during the SSL handshake. If SSL client |
| 50 // authentication is requested, the host_and_port field of SSLCertRequestInfo | 54 // authentication is requested, the host_and_port field of SSLCertRequestInfo |
| 51 // will be populated with |host_and_port|. |ssl_config| specifies | 55 // will be populated with |host_and_port|. |ssl_config| specifies |
| 52 // the SSL settings. | 56 // the SSL settings. |
| 53 SSLClientSocketNSS(ClientSocketHandle* transport_socket, | 57 // |
| 58 // Because calls to NSS may block, such as due to needing to access slow | |
| 59 // hardware or needing to synchronously unlock protected tokens, calls to | |
| 60 // NSS may optionally be run on a dedicated thread. If synchronous/blocking | |
| 61 // behaviour is desired, for performance or compatibility, the current task | |
|
willchan no longer on Chromium
2012/06/04 16:50:38
behavior
| |
| 62 // runner should be supplied instead. | |
| 63 SSLClientSocketNSS(base::SingleThreadTaskRunner* nss_task_runner, | |
| 64 ClientSocketHandle* transport_socket, | |
| 54 const HostPortPair& host_and_port, | 65 const HostPortPair& host_and_port, |
| 55 const SSLConfig& ssl_config, | 66 const SSLConfig& ssl_config, |
| 56 SSLHostInfo* ssl_host_info, | 67 SSLHostInfo* ssl_host_info, |
| 57 const SSLClientSocketContext& context); | 68 const SSLClientSocketContext& context); |
| 58 virtual ~SSLClientSocketNSS(); | 69 virtual ~SSLClientSocketNSS(); |
| 59 | 70 |
| 60 // SSLClientSocket implementation. | 71 // SSLClientSocket implementation. |
| 61 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE; | 72 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE; |
| 62 virtual void GetSSLCertRequestInfo( | 73 virtual void GetSSLCertRequestInfo( |
| 63 SSLCertRequestInfo* cert_request_info) OVERRIDE; | 74 SSLCertRequestInfo* cert_request_info) OVERRIDE; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 89 int buf_len, | 100 int buf_len, |
| 90 const CompletionCallback& callback) OVERRIDE; | 101 const CompletionCallback& callback) OVERRIDE; |
| 91 virtual int Write(IOBuffer* buf, | 102 virtual int Write(IOBuffer* buf, |
| 92 int buf_len, | 103 int buf_len, |
| 93 const CompletionCallback& callback) OVERRIDE; | 104 const CompletionCallback& callback) OVERRIDE; |
| 94 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE; | 105 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE; |
| 95 virtual bool SetSendBufferSize(int32 size) OVERRIDE; | 106 virtual bool SetSendBufferSize(int32 size) OVERRIDE; |
| 96 virtual ServerBoundCertService* GetServerBoundCertService() const OVERRIDE; | 107 virtual ServerBoundCertService* GetServerBoundCertService() const OVERRIDE; |
| 97 | 108 |
| 98 private: | 109 private: |
| 110 // Helper class to handle marshalling any NSS interaction to and from the | |
| 111 // NSS and network task runners. Not every call needs to happen on the Core | |
| 112 class Core; | |
| 113 | |
| 99 enum State { | 114 enum State { |
| 100 STATE_NONE, | 115 STATE_NONE, |
| 101 STATE_LOAD_SSL_HOST_INFO, | 116 STATE_LOAD_SSL_HOST_INFO, |
| 102 STATE_HANDSHAKE, | 117 STATE_HANDSHAKE, |
| 103 STATE_GET_DOMAIN_BOUND_CERT_COMPLETE, | 118 STATE_HANDSHAKE_COMPLETE, |
| 104 STATE_VERIFY_DNSSEC, | 119 STATE_VERIFY_DNSSEC, |
| 105 STATE_VERIFY_CERT, | 120 STATE_VERIFY_CERT, |
| 106 STATE_VERIFY_CERT_COMPLETE, | 121 STATE_VERIFY_CERT_COMPLETE, |
| 107 }; | 122 }; |
| 108 | 123 |
| 109 int Init(); | 124 int Init(); |
| 125 void InitCore(); | |
| 110 | 126 |
| 111 // Initializes NSS SSL options. Returns a net error code. | 127 // Initializes NSS SSL options. Returns a net error code. |
| 112 int InitializeSSLOptions(); | 128 int InitializeSSLOptions(); |
| 113 | 129 |
| 114 // Initializes the socket peer name in SSL. Returns a net error code. | 130 // Initializes the socket peer name in SSL. Returns a net error code. |
| 115 int InitializeSSLPeerName(); | 131 int InitializeSSLPeerName(); |
| 116 | 132 |
| 117 void UpdateServerCert(); | |
| 118 void UpdateConnectionStatus(); | |
| 119 void DoReadCallback(int result); | |
| 120 void DoWriteCallback(int result); | |
| 121 void DoConnectCallback(int result); | 133 void DoConnectCallback(int result); |
| 122 void OnHandshakeIOComplete(int result); | 134 void OnHandshakeIOComplete(int result); |
| 123 void OnSendComplete(int result); | 135 |
| 124 void OnRecvComplete(int result); | 136 void LoadSSLHostInfo(); |
| 137 int DoLoadSSLHostInfo(); | |
| 125 | 138 |
| 126 int DoHandshakeLoop(int last_io_result); | 139 int DoHandshakeLoop(int last_io_result); |
| 127 int DoReadLoop(int result); | |
| 128 int DoWriteLoop(int result); | |
| 129 | |
| 130 bool LoadSSLHostInfo(); | |
| 131 int DoLoadSSLHostInfo(); | |
| 132 | |
| 133 int DoHandshake(); | 140 int DoHandshake(); |
| 134 | 141 int DoHandshakeComplete(int result); |
| 135 // ImportDBCertAndKey is a helper function for turning a DER-encoded cert and | |
| 136 // key into a CERTCertificate and SECKEYPrivateKey. Returns OK upon success | |
| 137 // and an error code otherwise. | |
| 138 // Requires |domain_bound_private_key_| and |domain_bound_cert_| to have been | |
| 139 // set by a call to ServerBoundCertService->GetDomainBoundCert. The caller | |
| 140 // takes ownership of the |*cert| and |*key|. | |
| 141 int ImportDBCertAndKey(CERTCertificate** cert, SECKEYPrivateKey** key); | |
| 142 int DoGetDBCertComplete(int result); | |
| 143 int DoVerifyDNSSEC(int result); | 142 int DoVerifyDNSSEC(int result); |
| 144 int DoVerifyCert(int result); | 143 int DoVerifyCert(int result); |
| 145 int DoVerifyCertComplete(int result); | 144 int DoVerifyCertComplete(int result); |
| 146 int DoPayloadRead(); | |
| 147 int DoPayloadWrite(); | |
| 148 void LogConnectionTypeMetrics() const; | |
| 149 void SaveSSLHostInfo(); | 145 void SaveSSLHostInfo(); |
| 150 | 146 |
| 151 bool DoTransportIO(); | 147 void LogConnectionTypeMetrics() const; |
| 152 int BufferSend(); | |
| 153 void BufferSendComplete(int result); | |
| 154 int BufferRecv(); | |
| 155 void BufferRecvComplete(int result); | |
| 156 | |
| 157 // Handles an NSS error generated while handshaking or performing IO. | |
| 158 // Returns a network error code mapped from the original NSS error. | |
| 159 int HandleNSSError(PRErrorCode error, bool handshake_error); | |
| 160 | |
| 161 // NSS calls this when checking certificates. We pass 'this' as the first | |
| 162 // argument. | |
| 163 static SECStatus OwnAuthCertHandler(void* arg, PRFileDesc* socket, | |
| 164 PRBool checksig, PRBool is_server); | |
| 165 // Returns true if connection negotiated the domain bound cert extension. | |
| 166 static bool DomainBoundCertNegotiated(PRFileDesc* socket); | |
| 167 // Domain bound cert client auth handler. | |
| 168 // Returns the value the ClientAuthHandler function should return. | |
| 169 SECStatus DomainBoundClientAuthHandler( | |
| 170 const SECItem* cert_types, | |
| 171 CERTCertificate** result_certificate, | |
| 172 SECKEYPrivateKey** result_private_key); | |
| 173 #if defined(NSS_PLATFORM_CLIENT_AUTH) | |
| 174 // On platforms where we use the native certificate store, NSS calls this | |
| 175 // instead when client authentication is requested. At most one of | |
| 176 // (result_certs, result_private_key) or | |
| 177 // (result_nss_certificate, result_nss_private_key) should be set. | |
| 178 static SECStatus PlatformClientAuthHandler( | |
| 179 void* arg, | |
| 180 PRFileDesc* socket, | |
| 181 CERTDistNames* ca_names, | |
| 182 CERTCertList** result_certs, | |
| 183 void** result_private_key, | |
| 184 CERTCertificate** result_nss_certificate, | |
| 185 SECKEYPrivateKey** result_nss_private_key); | |
| 186 #else | |
| 187 // NSS calls this when client authentication is requested. | |
| 188 static SECStatus ClientAuthHandler(void* arg, | |
| 189 PRFileDesc* socket, | |
| 190 CERTDistNames* ca_names, | |
| 191 CERTCertificate** result_certificate, | |
| 192 SECKEYPrivateKey** result_private_key); | |
| 193 #endif | |
| 194 // Record histograms for DBC support. The histogram will only be updated if | |
| 195 // this socket did a full handshake. | |
| 196 void RecordDomainBoundCertSupport() const; | |
| 197 | |
| 198 // NSS calls this when handshake is completed. We pass 'this' as the second | |
| 199 // argument. | |
| 200 static void HandshakeCallback(PRFileDesc* socket, void* arg); | |
| 201 | |
| 202 static SECStatus NextProtoCallback(void* arg, | |
| 203 PRFileDesc* fd, | |
| 204 const unsigned char* protos, | |
| 205 unsigned int protos_len, | |
| 206 unsigned char* proto_out, | |
| 207 unsigned int* proto_out_len, | |
| 208 unsigned int proto_max_len); | |
| 209 | 148 |
| 210 // The following methods are for debugging bug 65948. Will remove this code | 149 // The following methods are for debugging bug 65948. Will remove this code |
| 211 // after fixing bug 65948. | 150 // after fixing bug 65948. |
| 212 void EnsureThreadIdAssigned() const; | 151 void EnsureThreadIdAssigned() const; |
| 213 bool CalledOnValidThread() const; | 152 bool CalledOnValidThread() const; |
| 214 | 153 |
| 215 bool transport_send_busy_; | 154 // The task runner used to perform NSS operations. |
| 216 bool transport_recv_busy_; | 155 scoped_refptr<base::SingleThreadTaskRunner> nss_task_runner_; |
|
willchan no longer on Chromium
2012/06/04 16:50:38
const?
Ryan Sleevi
2012/06/04 21:51:51
Is this a new thing, trying to document const poin
willchan no longer on Chromium
2012/06/04 21:55:43
There's no One True Way. My stylistic preference i
| |
| 217 bool transport_recv_eof_; | |
| 218 scoped_refptr<IOBuffer> recv_buffer_; | |
| 219 | |
| 220 scoped_ptr<ClientSocketHandle> transport_; | 156 scoped_ptr<ClientSocketHandle> transport_; |
| 221 HostPortPair host_and_port_; | 157 HostPortPair host_and_port_; |
| 222 SSLConfig ssl_config_; | 158 SSLConfig ssl_config_; |
| 223 | 159 |
| 160 scoped_refptr<Core> core_; | |
|
willchan no longer on Chromium
2012/06/04 16:50:38
const?
Ryan Sleevi
2012/06/04 21:51:51
This is not const - we do reset on Disconnect()
| |
| 161 | |
| 224 CompletionCallback user_connect_callback_; | 162 CompletionCallback user_connect_callback_; |
| 225 CompletionCallback user_read_callback_; | |
| 226 CompletionCallback user_write_callback_; | |
| 227 | 163 |
| 228 // Used by Read function. | |
| 229 scoped_refptr<IOBuffer> user_read_buf_; | |
| 230 int user_read_buf_len_; | |
| 231 | |
| 232 // Used by Write function. | |
| 233 scoped_refptr<IOBuffer> user_write_buf_; | |
| 234 int user_write_buf_len_; | |
| 235 | |
| 236 // Set when handshake finishes. The server certificate is first received | |
| 237 // from NSS as an NSS certificate handle (server_cert_nss_), and then | |
| 238 // converted into an X509Certificate object (server_cert_). | |
| 239 scoped_refptr<X509Certificate> server_cert_; | |
| 240 CERTCertificate* server_cert_nss_; | |
| 241 // |server_cert_verify_result_| points at the verification result, which may, | 164 // |server_cert_verify_result_| points at the verification result, which may, |
| 242 // or may not be, |&local_server_cert_verify_result_|, depending on whether | 165 // or may not be, |&local_server_cert_verify_result_|, depending on whether |
| 243 // we used an SSLHostInfo's verification. | 166 // we used an SSLHostInfo's verification. |
| 244 const CertVerifyResult* server_cert_verify_result_; | 167 const CertVerifyResult* server_cert_verify_result_; |
| 245 CertVerifyResult local_server_cert_verify_result_; | 168 CertVerifyResult local_server_cert_verify_result_; |
| 246 std::vector<SHA1Fingerprint> side_pinned_public_keys_; | 169 std::vector<SHA1Fingerprint> side_pinned_public_keys_; |
| 247 int ssl_connection_status_; | |
| 248 | |
| 249 // Stores client authentication information between ClientAuthHandler and | |
| 250 // GetSSLCertRequestInfo calls. | |
| 251 std::vector<scoped_refptr<X509Certificate> > client_certs_; | |
| 252 bool client_auth_cert_needed_; | |
| 253 | 170 |
| 254 CertVerifier* const cert_verifier_; | 171 CertVerifier* const cert_verifier_; |
| 255 scoped_ptr<SingleRequestCertVerifier> verifier_; | 172 scoped_ptr<SingleRequestCertVerifier> verifier_; |
| 256 | 173 |
| 257 // For domain bound certificates in client auth. | 174 // For domain bound certificates in client auth. |
| 258 bool domain_bound_cert_xtn_negotiated_; | |
| 259 ServerBoundCertService* server_bound_cert_service_; | 175 ServerBoundCertService* server_bound_cert_service_; |
| 260 SSLClientCertType domain_bound_cert_type_; | |
| 261 std::string domain_bound_private_key_; | |
| 262 std::string domain_bound_cert_; | |
| 263 ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_; | |
| 264 | |
| 265 // True if NSS has called HandshakeCallback. | |
| 266 bool handshake_callback_called_; | |
| 267 | |
| 268 // True if the SSL handshake has been completed. | |
| 269 bool completed_handshake_; | |
| 270 | 176 |
| 271 // ssl_session_cache_shard_ is an opaque string that partitions the SSL | 177 // ssl_session_cache_shard_ is an opaque string that partitions the SSL |
| 272 // session cache. i.e. sessions created with one value will not attempt to | 178 // session cache. i.e. sessions created with one value will not attempt to |
| 273 // resume on the socket with a different value. | 179 // resume on the socket with a different value. |
| 274 const std::string ssl_session_cache_shard_; | 180 const std::string ssl_session_cache_shard_; |
| 275 | 181 |
| 276 // True iff |ssl_host_info_| contained a predicted certificate chain and | 182 // True if the SSL handshake has been completed. |
| 277 // that we found the prediction to be correct. | 183 bool completed_handshake_; |
| 278 bool predicted_cert_chain_correct_; | |
| 279 | 184 |
| 280 State next_handshake_state_; | 185 State next_handshake_state_; |
| 281 | 186 |
| 282 // The NSS SSL state machine | 187 // The NSS SSL state machine. This is owned by |core_|. |
| 188 // TODO(rsleevi): http://crbug.com/130616 - Remove this member once | |
| 189 // ExportKeyingMaterial is updated to be asynchronous. | |
| 283 PRFileDesc* nss_fd_; | 190 PRFileDesc* nss_fd_; |
| 284 | 191 |
| 285 // Buffers for the network end of the SSL state machine | |
| 286 memio_Private* nss_bufs_; | |
| 287 | |
| 288 BoundNetLog net_log_; | 192 BoundNetLog net_log_; |
| 289 | 193 |
| 290 base::TimeTicks start_cert_verification_time_; | 194 base::TimeTicks start_cert_verification_time_; |
| 291 | 195 |
| 292 scoped_ptr<SSLHostInfo> ssl_host_info_; | 196 scoped_ptr<SSLHostInfo> ssl_host_info_; |
| 293 | 197 |
| 294 TransportSecurityState* transport_security_state_; | 198 TransportSecurityState* transport_security_state_; |
| 295 | 199 |
| 296 // next_proto_ is the protocol that we selected by NPN. | |
| 297 std::string next_proto_; | |
| 298 NextProtoStatus next_proto_status_; | |
| 299 // Server's NPN advertised protocols. | |
| 300 std::string server_protos_; | |
| 301 | |
| 302 // The following two variables are added for debugging bug 65948. Will | 200 // The following two variables are added for debugging bug 65948. Will |
| 303 // remove this code after fixing bug 65948. | 201 // remove this code after fixing bug 65948. |
| 304 // Added the following code Debugging in release mode. | 202 // Added the following code Debugging in release mode. |
| 305 mutable base::Lock lock_; | 203 mutable base::Lock lock_; |
| 306 // This is mutable so that CalledOnValidThread can set it. | 204 // This is mutable so that CalledOnValidThread can set it. |
| 307 // It's guarded by |lock_|. | 205 // It's guarded by |lock_|. |
| 308 mutable base::PlatformThreadId valid_thread_id_; | 206 mutable base::PlatformThreadId valid_thread_id_; |
| 309 }; | 207 }; |
| 310 | 208 |
| 311 } // namespace net | 209 } // namespace net |
| 312 | 210 |
| 313 #endif // NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ | 211 #endif // NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ |
| OLD | NEW |