Home | History | Annotate | Download | only in socket
      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