1 // Copyright (c) 2011 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_CLIENT_SOCKET_NSS_H_ 6 #define NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ 7 #pragma once 8 9 #include <certt.h> 10 #include <keyt.h> 11 #include <nspr.h> 12 #include <nss.h> 13 14 #include <string> 15 #include <vector> 16 17 #include "base/memory/scoped_ptr.h" 18 #include "base/synchronization/lock.h" 19 #include "base/threading/platform_thread.h" 20 #include "base/time.h" 21 #include "base/timer.h" 22 #include "net/base/cert_verify_result.h" 23 #include "net/base/completion_callback.h" 24 #include "net/base/host_port_pair.h" 25 #include "net/base/net_log.h" 26 #include "net/base/nss_memio.h" 27 #include "net/base/ssl_config_service.h" 28 #include "net/base/x509_certificate.h" 29 #include "net/socket/ssl_client_socket.h" 30 31 namespace net { 32 33 class BoundNetLog; 34 class CertVerifier; 35 class ClientSocketHandle; 36 class DnsCertProvenanceChecker; 37 class SingleRequestCertVerifier; 38 class SSLHostInfo; 39 class X509Certificate; 40 41 // An SSL client socket implemented with Mozilla NSS. 42 class SSLClientSocketNSS : public SSLClientSocket { 43 public: 44 // Takes ownership of the |transport_socket|, which must already be connected. 45 // The hostname specified in |host_and_port| will be compared with the name(s) 46 // in the server's certificate during the SSL handshake. If SSL client 47 // authentication is requested, the host_and_port field of SSLCertRequestInfo 48 // will be populated with |host_and_port|. |ssl_config| specifies 49 // the SSL settings. 50 SSLClientSocketNSS(ClientSocketHandle* transport_socket, 51 const HostPortPair& host_and_port, 52 const SSLConfig& ssl_config, 53 SSLHostInfo* ssl_host_info, 54 CertVerifier* cert_verifier, 55 DnsCertProvenanceChecker* dnsrr_resolver); 56 ~SSLClientSocketNSS(); 57 58 // For tests 59 static void ClearSessionCache(); 60 61 // SSLClientSocket methods: 62 virtual void GetSSLInfo(SSLInfo* ssl_info); 63 virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); 64 virtual NextProtoStatus GetNextProto(std::string* proto); 65 virtual void UseDNSSEC(DNSSECProvider* provider); 66 67 // ClientSocket methods: 68 virtual int Connect(CompletionCallback* callback 69 #ifdef ANDROID 70 , bool wait_for_connect 71 #endif 72 ); 73 virtual void Disconnect(); 74 virtual bool IsConnected() const; 75 virtual bool IsConnectedAndIdle() const; 76 virtual int GetPeerAddress(AddressList* address) const; 77 virtual int GetLocalAddress(IPEndPoint* address) const; 78 virtual const BoundNetLog& NetLog() const; 79 virtual void SetSubresourceSpeculation(); 80 virtual void SetOmniboxSpeculation(); 81 virtual bool WasEverUsed() const; 82 virtual bool UsingTCPFastOpen() const; 83 84 // Socket methods: 85 virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback); 86 virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback); 87 virtual bool SetReceiveBufferSize(int32 size); 88 virtual bool SetSendBufferSize(int32 size); 89 90 private: 91 enum State { 92 STATE_NONE, 93 STATE_HANDSHAKE, 94 STATE_VERIFY_DNSSEC, 95 STATE_VERIFY_DNSSEC_COMPLETE, 96 STATE_VERIFY_CERT, 97 STATE_VERIFY_CERT_COMPLETE, 98 }; 99 100 int Init(); 101 102 // Initializes NSS SSL options. Returns a net error code. 103 int InitializeSSLOptions(); 104 105 // Initializes the socket peer name in SSL. Returns a net error code. 106 int InitializeSSLPeerName(); 107 108 #if defined(OS_MACOSX) || defined(OS_WIN) 109 // Creates an OS certificate from a DER-encoded certificate. 110 static X509Certificate::OSCertHandle CreateOSCert(const SECItem& der_cert); 111 #endif 112 X509Certificate* UpdateServerCert(); 113 void UpdateConnectionStatus(); 114 void DoReadCallback(int result); 115 void DoWriteCallback(int result); 116 void DoConnectCallback(int result); 117 void OnHandshakeIOComplete(int result); 118 void OnSendComplete(int result); 119 void OnRecvComplete(int result); 120 121 int DoHandshakeLoop(int last_io_result); 122 int DoReadLoop(int result); 123 int DoWriteLoop(int result); 124 125 int DoHandshake(); 126 127 int DoVerifyDNSSEC(int result); 128 int DoVerifyDNSSECComplete(int result); 129 int DoVerifyCert(int result); 130 int DoVerifyCertComplete(int result); 131 int DoPayloadRead(); 132 int DoPayloadWrite(); 133 void LogConnectionTypeMetrics() const; 134 void SaveSSLHostInfo(); 135 void UncorkAfterTimeout(); 136 137 bool DoTransportIO(); 138 int BufferSend(void); 139 void BufferSendComplete(int result); 140 int BufferRecv(void); 141 void BufferRecvComplete(int result); 142 143 // Handles an NSS error generated while handshaking or performing IO. 144 // Returns a network error code mapped from the original NSS error. 145 int HandleNSSError(PRErrorCode error, bool handshake_error); 146 147 // NSS calls this when checking certificates. We pass 'this' as the first 148 // argument. 149 static SECStatus OwnAuthCertHandler(void* arg, PRFileDesc* socket, 150 PRBool checksig, PRBool is_server); 151 // NSS calls this when client authentication is requested. 152 #if defined(NSS_PLATFORM_CLIENT_AUTH) 153 static SECStatus PlatformClientAuthHandler(void* arg, 154 PRFileDesc* socket, 155 CERTDistNames* ca_names, 156 CERTCertList** result_certs, 157 void** result_private_key); 158 #else 159 static SECStatus ClientAuthHandler(void* arg, 160 PRFileDesc* socket, 161 CERTDistNames* ca_names, 162 CERTCertificate** result_certificate, 163 SECKEYPrivateKey** result_private_key); 164 #endif 165 // NSS calls this when handshake is completed. We pass 'this' as the second 166 // argument. 167 static void HandshakeCallback(PRFileDesc* socket, void* arg); 168 169 // The following methods are for debugging bug 65948. Will remove this code 170 // after fixing bug 65948. 171 void EnsureThreadIdAssigned() const; 172 bool CalledOnValidThread() const; 173 174 CompletionCallbackImpl<SSLClientSocketNSS> buffer_send_callback_; 175 CompletionCallbackImpl<SSLClientSocketNSS> buffer_recv_callback_; 176 bool transport_send_busy_; 177 bool transport_recv_busy_; 178 // corked_ is true if we are currently suspending writes to the network. This 179 // is named after the similar kernel flag, TCP_CORK. 180 bool corked_; 181 // uncork_timer_ is used to limit the amount of time that we'll delay the 182 // Finished message while waiting for a Write. 183 base::OneShotTimer<SSLClientSocketNSS> uncork_timer_; 184 scoped_refptr<IOBuffer> recv_buffer_; 185 186 CompletionCallbackImpl<SSLClientSocketNSS> handshake_io_callback_; 187 scoped_ptr<ClientSocketHandle> transport_; 188 HostPortPair host_and_port_; 189 SSLConfig ssl_config_; 190 191 CompletionCallback* user_connect_callback_; 192 CompletionCallback* user_read_callback_; 193 CompletionCallback* user_write_callback_; 194 195 // Used by Read function. 196 scoped_refptr<IOBuffer> user_read_buf_; 197 int user_read_buf_len_; 198 199 // Used by Write function. 200 scoped_refptr<IOBuffer> user_write_buf_; 201 int user_write_buf_len_; 202 203 // Set when handshake finishes. The server certificate is first received 204 // from NSS as an NSS certificate handle (server_cert_nss_), and then 205 // converted into an X509Certificate object (server_cert_). 206 scoped_refptr<X509Certificate> server_cert_; 207 CERTCertificate* server_cert_nss_; 208 // |server_cert_verify_result_| points at the verification result, which may, 209 // or may not be, |&local_server_cert_verify_result_|, depending on whether 210 // we used an SSLHostInfo's verification. 211 const CertVerifyResult* server_cert_verify_result_; 212 CertVerifyResult local_server_cert_verify_result_; 213 int ssl_connection_status_; 214 215 // Stores client authentication information between ClientAuthHandler and 216 // GetSSLCertRequestInfo calls. 217 std::vector<scoped_refptr<X509Certificate> > client_certs_; 218 bool client_auth_cert_needed_; 219 220 CertVerifier* const cert_verifier_; 221 scoped_ptr<SingleRequestCertVerifier> verifier_; 222 223 // True if NSS has called HandshakeCallback. 224 bool handshake_callback_called_; 225 226 // True if the SSL handshake has been completed. 227 bool completed_handshake_; 228 229 // True iff we believe that the user has an ESET product intercepting our 230 // HTTPS connections. 231 bool eset_mitm_detected_; 232 233 // True iff |ssl_host_info_| contained a predicted certificate chain and 234 // that we found the prediction to be correct. 235 bool predicted_cert_chain_correct_; 236 237 // True if the peer name has been initialized. 238 bool peername_initialized_; 239 240 // This pointer is owned by the caller of UseDNSSEC. 241 DNSSECProvider* dnssec_provider_; 242 // The time when we started waiting for DNSSEC records. 243 base::Time dnssec_wait_start_time_; 244 245 State next_handshake_state_; 246 247 // The NSS SSL state machine 248 PRFileDesc* nss_fd_; 249 250 // Buffers for the network end of the SSL state machine 251 memio_Private* nss_bufs_; 252 253 BoundNetLog net_log_; 254 255 base::TimeTicks start_cert_verification_time_; 256 257 scoped_ptr<SSLHostInfo> ssl_host_info_; 258 DnsCertProvenanceChecker* const dns_cert_checker_; 259 260 // The following two variables are added for debugging bug 65948. Will 261 // remove this code after fixing bug 65948. 262 // Added the following code Debugging in release mode. 263 mutable base::Lock lock_; 264 // This is mutable so that CalledOnValidThread can set it. 265 // It's guarded by |lock_|. 266 mutable base::PlatformThreadId valid_thread_id_; 267 }; 268 269 } // namespace net 270 271 #endif // NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ 272