• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
NetLog()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:
completed_handshake()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