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
25namespace net {
26
27class BoundNetLog;
28class CertVerifier;
29class ClientSocketHandle;
30class HostPortPair;
31class SingleRequestCertVerifier;
32
33// An SSL client socket implemented with the Windows Schannel.
34class 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