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