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_WIN_H_ 6 #define NET_SOCKET_SSL_CLIENT_SOCKET_WIN_H_ 7 #pragma once 8 9 #define SECURITY_WIN32 // Needs to be defined before including security.h 10 11 #include <windows.h> 12 #include <wincrypt.h> 13 #include <security.h> 14 15 #include <string> 16 17 #include "base/memory/scoped_ptr.h" 18 #include "net/base/cert_verify_result.h" 19 #include "net/base/completion_callback.h" 20 #include "net/base/host_port_pair.h" 21 #include "net/base/net_log.h" 22 #include "net/base/ssl_config_service.h" 23 #include "net/socket/ssl_client_socket.h" 24 25 namespace net { 26 27 class BoundNetLog; 28 class CertVerifier; 29 class ClientSocketHandle; 30 class HostPortPair; 31 class SingleRequestCertVerifier; 32 33 // An SSL client socket implemented with the Windows Schannel. 34 class SSLClientSocketWin : public SSLClientSocket { 35 public: 36 // Takes ownership of the |transport_socket|, which must already be connected. 37 // The hostname specified in |host_and_port| will be compared with the name(s) 38 // in the server's certificate during the SSL handshake. If SSL client 39 // authentication is requested, the host_and_port field of SSLCertRequestInfo 40 // will be populated with |host_and_port|. |ssl_config| specifies 41 // the SSL settings. 42 SSLClientSocketWin(ClientSocketHandle* transport_socket, 43 const HostPortPair& host_and_port, 44 const SSLConfig& ssl_config, 45 CertVerifier* cert_verifier); 46 ~SSLClientSocketWin(); 47 48 // SSLClientSocket methods: 49 virtual void GetSSLInfo(SSLInfo* ssl_info); 50 virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); 51 virtual NextProtoStatus GetNextProto(std::string* proto); 52 53 // ClientSocket methods: 54 virtual int Connect(CompletionCallback* callback 55 #ifdef ANDROID 56 , bool wait_for_connect 57 #endif 58 ); 59 virtual void Disconnect(); 60 virtual bool IsConnected() const; 61 virtual bool IsConnectedAndIdle() const; 62 virtual int GetPeerAddress(AddressList* address) const; 63 virtual int GetLocalAddress(IPEndPoint* address) const; 64 virtual const BoundNetLog& NetLog() const { return net_log_; } 65 virtual void SetSubresourceSpeculation(); 66 virtual void SetOmniboxSpeculation(); 67 virtual bool WasEverUsed() const; 68 virtual bool UsingTCPFastOpen() const; 69 70 // Socket methods: 71 virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback); 72 virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback); 73 74 virtual bool SetReceiveBufferSize(int32 size); 75 virtual bool SetSendBufferSize(int32 size); 76 77 private: 78 bool completed_handshake() const { 79 return next_state_ == STATE_COMPLETED_HANDSHAKE; 80 } 81 82 // Initializes the SSL options and security context. Returns a net error code. 83 int InitializeSSLContext(); 84 85 void OnHandshakeIOComplete(int result); 86 void OnReadComplete(int result); 87 void OnWriteComplete(int result); 88 89 int DoLoop(int last_io_result); 90 int DoHandshakeRead(); 91 int DoHandshakeReadComplete(int result); 92 int DoHandshakeWrite(); 93 int DoHandshakeWriteComplete(int result); 94 int DoVerifyCert(); 95 int DoVerifyCertComplete(int result); 96 97 int DoPayloadRead(); 98 int DoPayloadReadComplete(int result); 99 int DoPayloadDecrypt(); 100 int DoPayloadEncrypt(); 101 int DoPayloadWrite(); 102 int DoPayloadWriteComplete(int result); 103 int DoCompletedRenegotiation(int result); 104 105 int DidCallInitializeSecurityContext(); 106 int DidCompleteHandshake(); 107 void DidCompleteRenegotiation(); 108 void LogConnectionTypeMetrics() const; 109 void FreeSendBuffer(); 110 111 // Internal callbacks as async operations complete. 112 CompletionCallbackImpl<SSLClientSocketWin> handshake_io_callback_; 113 CompletionCallbackImpl<SSLClientSocketWin> read_callback_; 114 CompletionCallbackImpl<SSLClientSocketWin> write_callback_; 115 116 scoped_ptr<ClientSocketHandle> transport_; 117 HostPortPair host_and_port_; 118 SSLConfig ssl_config_; 119 120 // User function to callback when the Connect() completes. 121 CompletionCallback* user_connect_callback_; 122 123 // User function to callback when a Read() completes. 124 CompletionCallback* user_read_callback_; 125 scoped_refptr<IOBuffer> user_read_buf_; 126 int user_read_buf_len_; 127 128 // User function to callback when a Write() completes. 129 CompletionCallback* user_write_callback_; 130 scoped_refptr<IOBuffer> user_write_buf_; 131 int user_write_buf_len_; 132 133 // Used to Read and Write using transport_. 134 scoped_refptr<IOBuffer> transport_read_buf_; 135 scoped_refptr<IOBuffer> transport_write_buf_; 136 137 enum State { 138 STATE_NONE, 139 STATE_HANDSHAKE_READ, 140 STATE_HANDSHAKE_READ_COMPLETE, 141 STATE_HANDSHAKE_WRITE, 142 STATE_HANDSHAKE_WRITE_COMPLETE, 143 STATE_VERIFY_CERT, 144 STATE_VERIFY_CERT_COMPLETE, 145 STATE_COMPLETED_RENEGOTIATION, 146 STATE_COMPLETED_HANDSHAKE 147 // After the handshake, the socket remains 148 // in the STATE_COMPLETED_HANDSHAKE state, 149 // unless a renegotiate handshake occurs. 150 }; 151 State next_state_; 152 153 SecPkgContext_StreamSizes stream_sizes_; 154 scoped_refptr<X509Certificate> server_cert_; 155 CertVerifier* const cert_verifier_; 156 scoped_ptr<SingleRequestCertVerifier> verifier_; 157 CertVerifyResult server_cert_verify_result_; 158 159 CredHandle* creds_; 160 CtxtHandle ctxt_; 161 SecBuffer in_buffers_[2]; // Input buffers for InitializeSecurityContext. 162 SecBuffer send_buffer_; // Output buffer for InitializeSecurityContext. 163 SECURITY_STATUS isc_status_; // Return value of InitializeSecurityContext. 164 scoped_array<char> payload_send_buffer_; 165 int payload_send_buffer_len_; 166 int bytes_sent_; 167 168 // recv_buffer_ holds the received ciphertext. Since Schannel decrypts 169 // data in place, sometimes recv_buffer_ may contain decrypted plaintext and 170 // any undecrypted ciphertext. (Ciphertext is decrypted one full SSL record 171 // at a time.) 172 // 173 // If bytes_decrypted_ is 0, the received ciphertext is at the beginning of 174 // recv_buffer_, ready to be passed to DecryptMessage. 175 scoped_array<char> recv_buffer_; 176 char* decrypted_ptr_; // Points to the decrypted plaintext in recv_buffer_ 177 int bytes_decrypted_; // The number of bytes of decrypted plaintext. 178 char* received_ptr_; // Points to the received ciphertext in recv_buffer_ 179 int bytes_received_; // The number of bytes of received ciphertext. 180 181 // True if we're writing the first token (handshake message) to the server, 182 // false if we're writing a subsequent token. After we have written a token 183 // successfully, DoHandshakeWriteComplete checks this member to set the next 184 // state. 185 bool writing_first_token_; 186 187 // Only used in the STATE_HANDSHAKE_READ_COMPLETE and 188 // STATE_PAYLOAD_READ_COMPLETE states. True if a 'result' argument of OK 189 // should be ignored, to prevent it from being interpreted as EOF. 190 // 191 // The reason we need this flag is that OK means not only "0 bytes of data 192 // were read" but also EOF. We set ignore_ok_result_ to true when we need 193 // to continue processing previously read data without reading more data. 194 // We have to pass a 'result' of OK to the DoLoop method, and don't want it 195 // to be interpreted as EOF. 196 bool ignore_ok_result_; 197 198 // Renegotiation is in progress. 199 bool renegotiating_; 200 201 // True when the decrypter needs more data in order to decrypt. 202 bool need_more_data_; 203 204 BoundNetLog net_log_; 205 }; 206 207 } // namespace net 208 209 #endif // NET_SOCKET_SSL_CLIENT_SOCKET_WIN_H_ 210