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 #include "net/socket/ssl_client_socket_win.h"
      6 
      7 #include <schnlsp.h>
      8 
      9 #include "base/compiler_specific.h"
     10 #include "base/lock.h"
     11 #include "base/singleton.h"
     12 #include "base/stl_util-inl.h"
     13 #include "base/string_util.h"
     14 #include "net/base/cert_verifier.h"
     15 #include "net/base/connection_type_histograms.h"
     16 #include "net/base/io_buffer.h"
     17 #include "net/base/load_log.h"
     18 #include "net/base/net_errors.h"
     19 #include "net/base/ssl_cert_request_info.h"
     20 #include "net/base/ssl_info.h"
     21 
     22 #pragma comment(lib, "secur32.lib")
     23 
     24 namespace net {
     25 
     26 //-----------------------------------------------------------------------------
     27 
     28 // TODO(wtc): See http://msdn.microsoft.com/en-us/library/aa377188(VS.85).aspx
     29 // for the other error codes we may need to map.
     30 static int MapSecurityError(SECURITY_STATUS err) {
     31   // There are numerous security error codes, but these are the ones we thus
     32   // far find interesting.
     33   switch (err) {
     34     case SEC_E_WRONG_PRINCIPAL:  // Schannel
     35     case CERT_E_CN_NO_MATCH:  // CryptoAPI
     36       return ERR_CERT_COMMON_NAME_INVALID;
     37     case SEC_E_UNTRUSTED_ROOT:  // Schannel
     38     case CERT_E_UNTRUSTEDROOT:  // CryptoAPI
     39       return ERR_CERT_AUTHORITY_INVALID;
     40     case SEC_E_CERT_EXPIRED:  // Schannel
     41     case CERT_E_EXPIRED:  // CryptoAPI
     42       return ERR_CERT_DATE_INVALID;
     43     case CRYPT_E_NO_REVOCATION_CHECK:
     44       return ERR_CERT_NO_REVOCATION_MECHANISM;
     45     case CRYPT_E_REVOCATION_OFFLINE:
     46       return ERR_CERT_UNABLE_TO_CHECK_REVOCATION;
     47     case CRYPT_E_REVOKED:  // Schannel and CryptoAPI
     48       return ERR_CERT_REVOKED;
     49     case SEC_E_CERT_UNKNOWN:
     50     case CERT_E_ROLE:
     51       return ERR_CERT_INVALID;
     52     // We received one of the following alert messages from the server:
     53     //   handshake_failure
     54     //   illegal_parameter
     55     //   unexpected_message
     56     case SEC_E_ILLEGAL_MESSAGE:
     57       return ERR_SSL_PROTOCOL_ERROR;
     58     case SEC_E_ALGORITHM_MISMATCH:
     59       return ERR_SSL_VERSION_OR_CIPHER_MISMATCH;
     60     case SEC_E_INVALID_HANDLE:
     61       return ERR_UNEXPECTED;
     62     case SEC_E_OK:
     63       return OK;
     64     default:
     65       LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED";
     66       return ERR_FAILED;
     67   }
     68 }
     69 
     70 // Returns true if the two CERT_CONTEXTs contain the same certificate.
     71 bool SameCert(PCCERT_CONTEXT a, PCCERT_CONTEXT b) {
     72   return a == b ||
     73          (a->cbCertEncoded == b->cbCertEncoded &&
     74          memcmp(a->pbCertEncoded, b->pbCertEncoded, b->cbCertEncoded) == 0);
     75 }
     76 
     77 //-----------------------------------------------------------------------------
     78 
     79 // A bitmask consisting of these bit flags encodes which versions of the SSL
     80 // protocol (SSL 2.0, SSL 3.0, and TLS 1.0) are enabled.
     81 enum {
     82   SSL2 = 1 << 0,
     83   SSL3 = 1 << 1,
     84   TLS1 = 1 << 2,
     85   SSL_VERSION_MASKS = 1 << 3  // The number of SSL version bitmasks.
     86 };
     87 
     88 // CredHandleClass simply gives a default constructor and a destructor to
     89 // SSPI's CredHandle type (a C struct).
     90 class CredHandleClass : public CredHandle {
     91  public:
     92   CredHandleClass() {
     93     dwLower = 0;
     94     dwUpper = 0;
     95   }
     96 
     97   ~CredHandleClass() {
     98     if (dwLower || dwUpper) {
     99       SECURITY_STATUS status = FreeCredentialsHandle(this);
    100       DCHECK(status == SEC_E_OK);
    101     }
    102   }
    103 };
    104 
    105 // A table of CredHandles.
    106 class CredHandleTable {
    107  public:
    108   CredHandleTable() {}
    109 
    110   ~CredHandleTable() {
    111     STLDeleteContainerPairSecondPointers(client_cert_creds_.begin(),
    112                                          client_cert_creds_.end());
    113   }
    114 
    115   CredHandle* GetHandle(PCCERT_CONTEXT client_cert, int ssl_version_mask) {
    116     DCHECK(0 < ssl_version_mask &&
    117            ssl_version_mask < arraysize(anonymous_creds_));
    118     CredHandleClass* handle;
    119     AutoLock lock(lock_);
    120     if (client_cert) {
    121       CredHandleMapKey key = std::make_pair(client_cert, ssl_version_mask);
    122       CredHandleMap::const_iterator it = client_cert_creds_.find(key);
    123       if (it == client_cert_creds_.end()) {
    124         handle = new CredHandleClass;
    125         client_cert_creds_[key] = handle;
    126       } else {
    127         handle = it->second;
    128       }
    129     } else {
    130       handle = &anonymous_creds_[ssl_version_mask];
    131     }
    132     if (!handle->dwLower && !handle->dwUpper)
    133       InitializeHandle(handle, client_cert, ssl_version_mask);
    134     return handle;
    135   }
    136 
    137  private:
    138   // CredHandleMapKey is a std::pair consisting of these two components:
    139   //   PCCERT_CONTEXT client_cert
    140   //   int ssl_version_mask
    141   typedef std::pair<PCCERT_CONTEXT, int> CredHandleMapKey;
    142 
    143   typedef std::map<CredHandleMapKey, CredHandleClass*> CredHandleMap;
    144 
    145   static void InitializeHandle(CredHandle* handle,
    146                                PCCERT_CONTEXT client_cert,
    147                                int ssl_version_mask);
    148 
    149   Lock lock_;
    150 
    151   // Anonymous (no client certificate) CredHandles for all possible
    152   // combinations of SSL versions.  Defined as an array for fast lookup.
    153   CredHandleClass anonymous_creds_[SSL_VERSION_MASKS];
    154 
    155   // CredHandles that use a client certificate.
    156   CredHandleMap client_cert_creds_;
    157 };
    158 
    159 // static
    160 void CredHandleTable::InitializeHandle(CredHandle* handle,
    161                                        PCCERT_CONTEXT client_cert,
    162                                        int ssl_version_mask) {
    163   SCHANNEL_CRED schannel_cred = {0};
    164   schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
    165   if (client_cert) {
    166     schannel_cred.cCreds = 1;
    167     schannel_cred.paCred = &client_cert;
    168     // Schannel will make its own copy of client_cert.
    169   }
    170 
    171   // The global system registry settings take precedence over the value of
    172   // schannel_cred.grbitEnabledProtocols.
    173   schannel_cred.grbitEnabledProtocols = 0;
    174   if (ssl_version_mask & SSL2)
    175     schannel_cred.grbitEnabledProtocols |= SP_PROT_SSL2;
    176   if (ssl_version_mask & SSL3)
    177     schannel_cred.grbitEnabledProtocols |= SP_PROT_SSL3;
    178   if (ssl_version_mask & TLS1)
    179     schannel_cred.grbitEnabledProtocols |= SP_PROT_TLS1;
    180 
    181   // The default session lifetime is 36000000 milliseconds (ten hours).  Set
    182   // schannel_cred.dwSessionLifespan to change the number of milliseconds that
    183   // Schannel keeps the session in its session cache.
    184 
    185   // We can set the key exchange algorithms (RSA or DH) in
    186   // schannel_cred.{cSupportedAlgs,palgSupportedAlgs}.
    187 
    188   // Although SCH_CRED_AUTO_CRED_VALIDATION is convenient, we have to use
    189   // SCH_CRED_MANUAL_CRED_VALIDATION for three reasons.
    190   // 1. SCH_CRED_AUTO_CRED_VALIDATION doesn't allow us to get the certificate
    191   //    context if the certificate validation fails.
    192   // 2. SCH_CRED_AUTO_CRED_VALIDATION returns only one error even if the
    193   //    certificate has multiple errors.
    194   // 3. SCH_CRED_AUTO_CRED_VALIDATION doesn't allow us to ignore untrusted CA
    195   //    and expired certificate errors.  There are only flags to ignore the
    196   //    name mismatch and unable-to-check-revocation errors.
    197   //
    198   // We specify SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT to cause the TLS
    199   // certificate status request extension (commonly known as OCSP stapling)
    200   // to be sent on Vista or later.  This flag matches the
    201   // CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT flag that we pass to the
    202   // CertGetCertificateChain calls.  Note: we specify this flag even when
    203   // revocation checking is disabled to avoid doubling the number of
    204   // credentials handles we need to acquire.
    205   //
    206   // TODO(wtc): Look into undocumented or poorly documented flags:
    207   //   SCH_CRED_RESTRICTED_ROOTS
    208   //   SCH_CRED_REVOCATION_CHECK_CACHE_ONLY
    209   //   SCH_CRED_CACHE_ONLY_URL_RETRIEVAL
    210   //   SCH_CRED_MEMORY_STORE_CERT
    211   schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS |
    212                            SCH_CRED_MANUAL_CRED_VALIDATION |
    213                            SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT;
    214   TimeStamp expiry;
    215   SECURITY_STATUS status;
    216 
    217   status = AcquireCredentialsHandle(
    218       NULL,  // Not used
    219       UNISP_NAME,  // Microsoft Unified Security Protocol Provider
    220       SECPKG_CRED_OUTBOUND,
    221       NULL,  // Not used
    222       &schannel_cred,
    223       NULL,  // Not used
    224       NULL,  // Not used
    225       handle,
    226       &expiry);  // Optional
    227   if (status != SEC_E_OK) {
    228     DLOG(ERROR) << "AcquireCredentialsHandle failed: " << status;
    229     // GetHandle will return a pointer to an uninitialized CredHandle, which
    230     // will cause InitializeSecurityContext to fail with SEC_E_INVALID_HANDLE.
    231   }
    232 }
    233 
    234 // For the SSL sockets to share SSL sessions by session resumption handshakes,
    235 // they need to use the same CredHandle.  The GetCredHandle function creates
    236 // and returns a shared CredHandle.
    237 //
    238 // The versions of the SSL protocol enabled are a property of the CredHandle.
    239 // So we need a separate CredHandle for each combination of SSL versions.
    240 // Most of the time Chromium will use only one or two combinations of SSL
    241 // versions (for example, SSL3 | TLS1 for normal use, plus SSL3 when visiting
    242 // TLS-intolerant servers).  These CredHandles are initialized only when
    243 // needed.
    244 
    245 static CredHandle* GetCredHandle(PCCERT_CONTEXT client_cert,
    246                                  int ssl_version_mask) {
    247   // It doesn't matter whether GetCredHandle returns NULL or a pointer to an
    248   // uninitialized CredHandle on failure.  Both of them cause
    249   // InitializeSecurityContext to fail with SEC_E_INVALID_HANDLE.
    250   if (ssl_version_mask <= 0 || ssl_version_mask >= SSL_VERSION_MASKS) {
    251     NOTREACHED();
    252     return NULL;
    253   }
    254   return Singleton<CredHandleTable>::get()->GetHandle(client_cert,
    255                                                       ssl_version_mask);
    256 }
    257 
    258 //-----------------------------------------------------------------------------
    259 
    260 // A memory certificate store for client certificates.  This allows us to
    261 // close the "MY" system certificate store when we finish searching for
    262 // client certificates.
    263 class ClientCertStore {
    264  public:
    265   ClientCertStore() {
    266     store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL);
    267   }
    268 
    269   ~ClientCertStore() {
    270     if (store_) {
    271       BOOL ok = CertCloseStore(store_, CERT_CLOSE_STORE_CHECK_FLAG);
    272       DCHECK(ok);
    273     }
    274   }
    275 
    276   PCCERT_CONTEXT CopyCertContext(PCCERT_CONTEXT client_cert) {
    277     PCCERT_CONTEXT copy;
    278     BOOL ok = CertAddCertificateContextToStore(store_, client_cert,
    279                                                CERT_STORE_ADD_USE_EXISTING,
    280                                                &copy);
    281     DCHECK(ok);
    282     return ok ? copy : NULL;
    283   }
    284 
    285  private:
    286   HCERTSTORE store_;
    287 };
    288 
    289 //-----------------------------------------------------------------------------
    290 
    291 // Size of recv_buffer_
    292 //
    293 // Ciphertext is decrypted one SSL record at a time, so recv_buffer_ needs to
    294 // have room for a full SSL record, with the header and trailer.  Here is the
    295 // breakdown of the size:
    296 //   5: SSL record header
    297 //   16K: SSL record maximum size
    298 //   64: >= SSL record trailer (16 or 20 have been observed)
    299 static const int kRecvBufferSize = (5 + 16*1024 + 64);
    300 
    301 SSLClientSocketWin::SSLClientSocketWin(ClientSocket* transport_socket,
    302                                        const std::string& hostname,
    303                                        const SSLConfig& ssl_config)
    304     : ALLOW_THIS_IN_INITIALIZER_LIST(
    305         handshake_io_callback_(this,
    306                                &SSLClientSocketWin::OnHandshakeIOComplete)),
    307       ALLOW_THIS_IN_INITIALIZER_LIST(
    308         read_callback_(this, &SSLClientSocketWin::OnReadComplete)),
    309       ALLOW_THIS_IN_INITIALIZER_LIST(
    310         write_callback_(this, &SSLClientSocketWin::OnWriteComplete)),
    311       transport_(transport_socket),
    312       hostname_(hostname),
    313       ssl_config_(ssl_config),
    314       user_connect_callback_(NULL),
    315       user_read_callback_(NULL),
    316       user_read_buf_len_(0),
    317       user_write_callback_(NULL),
    318       user_write_buf_len_(0),
    319       next_state_(STATE_NONE),
    320       creds_(NULL),
    321       isc_status_(SEC_E_OK),
    322       payload_send_buffer_len_(0),
    323       bytes_sent_(0),
    324       decrypted_ptr_(NULL),
    325       bytes_decrypted_(0),
    326       received_ptr_(NULL),
    327       bytes_received_(0),
    328       writing_first_token_(false),
    329       ignore_ok_result_(false),
    330       renegotiating_(false),
    331       need_more_data_(false) {
    332   memset(&stream_sizes_, 0, sizeof(stream_sizes_));
    333   memset(in_buffers_, 0, sizeof(in_buffers_));
    334   memset(&send_buffer_, 0, sizeof(send_buffer_));
    335   memset(&ctxt_, 0, sizeof(ctxt_));
    336 }
    337 
    338 SSLClientSocketWin::~SSLClientSocketWin() {
    339   Disconnect();
    340 }
    341 
    342 void SSLClientSocketWin::GetSSLInfo(SSLInfo* ssl_info) {
    343   if (!server_cert_)
    344     return;
    345 
    346   ssl_info->cert = server_cert_;
    347   ssl_info->cert_status = server_cert_verify_result_.cert_status;
    348   SecPkgContext_ConnectionInfo connection_info;
    349   SECURITY_STATUS status = QueryContextAttributes(
    350       &ctxt_, SECPKG_ATTR_CONNECTION_INFO, &connection_info);
    351   if (status == SEC_E_OK) {
    352     // TODO(wtc): compute the overall security strength, taking into account
    353     // dwExchStrength and dwHashStrength.  dwExchStrength needs to be
    354     // normalized.
    355     ssl_info->security_bits = connection_info.dwCipherStrength;
    356   }
    357 }
    358 
    359 void SSLClientSocketWin::GetSSLCertRequestInfo(
    360     SSLCertRequestInfo* cert_request_info) {
    361   cert_request_info->host_and_port = hostname_;  // TODO(wtc): no port!
    362   cert_request_info->client_certs.clear();
    363 
    364   // Get the certificate_authorities field of the CertificateRequest message.
    365   // Schannel doesn't return the certificate_types field of the
    366   // CertificateRequest message to us, so we can't filter the client
    367   // certificates properly. :-(
    368   SecPkgContext_IssuerListInfoEx issuer_list;
    369   SECURITY_STATUS status = QueryContextAttributes(
    370       &ctxt_, SECPKG_ATTR_ISSUER_LIST_EX, &issuer_list);
    371   if (status != SEC_E_OK) {
    372     DLOG(ERROR) << "QueryContextAttributes (issuer list) failed: " << status;
    373     return;
    374   }
    375 
    376   // Client certificates of the user are in the "MY" system certificate store.
    377   HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY");
    378   if (!my_cert_store) {
    379     FreeContextBuffer(issuer_list.aIssuers);
    380     return;
    381   }
    382 
    383   // Enumerate the client certificates.
    384   CERT_CHAIN_FIND_BY_ISSUER_PARA find_by_issuer_para;
    385   memset(&find_by_issuer_para, 0, sizeof(find_by_issuer_para));
    386   find_by_issuer_para.cbSize = sizeof(find_by_issuer_para);
    387   find_by_issuer_para.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH;
    388   find_by_issuer_para.cIssuer = issuer_list.cIssuers;
    389   find_by_issuer_para.rgIssuer = issuer_list.aIssuers;
    390 
    391   PCCERT_CHAIN_CONTEXT chain_context = NULL;
    392 
    393   for (;;) {
    394     // Find a certificate chain.
    395     chain_context = CertFindChainInStore(my_cert_store,
    396                                          X509_ASN_ENCODING,
    397                                          0,
    398                                          CERT_CHAIN_FIND_BY_ISSUER,
    399                                          &find_by_issuer_para,
    400                                          chain_context);
    401     if (!chain_context) {
    402       DWORD err = GetLastError();
    403       if (err != CRYPT_E_NOT_FOUND)
    404         DLOG(ERROR) << "CertFindChainInStore failed: " << err;
    405       break;
    406     }
    407 
    408     // Get the leaf certificate.
    409     PCCERT_CONTEXT cert_context =
    410         chain_context->rgpChain[0]->rgpElement[0]->pCertContext;
    411     // Copy it to our own certificate store, so that we can close the "MY"
    412     // certificate store before returning from this function.
    413     PCCERT_CONTEXT cert_context2 =
    414         Singleton<ClientCertStore>::get()->CopyCertContext(cert_context);
    415     if (!cert_context2) {
    416       NOTREACHED();
    417       continue;
    418     }
    419     scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
    420         cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT);
    421     cert_request_info->client_certs.push_back(cert);
    422   }
    423 
    424   FreeContextBuffer(issuer_list.aIssuers);
    425 
    426   BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG);
    427   DCHECK(ok);
    428 }
    429 
    430 SSLClientSocket::NextProtoStatus
    431 SSLClientSocketWin::GetNextProto(std::string* proto) {
    432   proto->clear();
    433   return kNextProtoUnsupported;
    434 }
    435 
    436 int SSLClientSocketWin::Connect(CompletionCallback* callback,
    437                                 LoadLog* load_log) {
    438   DCHECK(transport_.get());
    439   DCHECK(next_state_ == STATE_NONE);
    440   DCHECK(!user_connect_callback_);
    441 
    442   LoadLog::BeginEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
    443 
    444   int rv = InitializeSSLContext();
    445   if (rv != OK) {
    446     LoadLog::EndEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
    447     return rv;
    448   }
    449 
    450   writing_first_token_ = true;
    451   next_state_ = STATE_HANDSHAKE_WRITE;
    452   rv = DoLoop(OK);
    453   if (rv == ERR_IO_PENDING) {
    454     user_connect_callback_ = callback;
    455     load_log_ = load_log;
    456   } else {
    457     LoadLog::EndEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
    458   }
    459   return rv;
    460 }
    461 
    462 int SSLClientSocketWin::InitializeSSLContext() {
    463   int ssl_version_mask = 0;
    464   if (ssl_config_.ssl2_enabled)
    465     ssl_version_mask |= SSL2;
    466   if (ssl_config_.ssl3_enabled)
    467     ssl_version_mask |= SSL3;
    468   if (ssl_config_.tls1_enabled)
    469     ssl_version_mask |= TLS1;
    470   // If we pass 0 to GetCredHandle, we will let Schannel select the protocols,
    471   // rather than enabling no protocols.  So we have to fail here.
    472   if (ssl_version_mask == 0)
    473     return ERR_NO_SSL_VERSIONS_ENABLED;
    474   PCCERT_CONTEXT cert_context = NULL;
    475   if (ssl_config_.client_cert)
    476     cert_context = ssl_config_.client_cert->os_cert_handle();
    477   creds_ = GetCredHandle(cert_context, ssl_version_mask);
    478 
    479   memset(&ctxt_, 0, sizeof(ctxt_));
    480 
    481   SecBufferDesc buffer_desc;
    482   DWORD out_flags;
    483   DWORD flags = ISC_REQ_SEQUENCE_DETECT   |
    484                 ISC_REQ_REPLAY_DETECT     |
    485                 ISC_REQ_CONFIDENTIALITY   |
    486                 ISC_RET_EXTENDED_ERROR    |
    487                 ISC_REQ_ALLOCATE_MEMORY   |
    488                 ISC_REQ_STREAM;
    489 
    490   send_buffer_.pvBuffer = NULL;
    491   send_buffer_.BufferType = SECBUFFER_TOKEN;
    492   send_buffer_.cbBuffer = 0;
    493 
    494   buffer_desc.cBuffers = 1;
    495   buffer_desc.pBuffers = &send_buffer_;
    496   buffer_desc.ulVersion = SECBUFFER_VERSION;
    497 
    498   TimeStamp expiry;
    499   SECURITY_STATUS status;
    500 
    501   status = InitializeSecurityContext(
    502       creds_,
    503       NULL,  // NULL on the first call
    504       const_cast<wchar_t*>(ASCIIToWide(hostname_).c_str()),
    505       flags,
    506       0,  // Reserved
    507       SECURITY_NATIVE_DREP,  // TODO(wtc): MSDN says this should be set to 0.
    508       NULL,  // NULL on the first call
    509       0,  // Reserved
    510       &ctxt_,  // Receives the new context handle
    511       &buffer_desc,
    512       &out_flags,
    513       &expiry);
    514   if (status != SEC_I_CONTINUE_NEEDED) {
    515     DLOG(ERROR) << "InitializeSecurityContext failed: " << status;
    516     return MapSecurityError(status);
    517   }
    518 
    519   return OK;
    520 }
    521 
    522 
    523 void SSLClientSocketWin::Disconnect() {
    524   // TODO(wtc): Send SSL close_notify alert.
    525   next_state_ = STATE_NONE;
    526 
    527   // Shut down anything that may call us back.
    528   verifier_.reset();
    529   transport_->Disconnect();
    530 
    531   if (send_buffer_.pvBuffer)
    532     FreeSendBuffer();
    533   if (ctxt_.dwLower || ctxt_.dwUpper) {
    534     DeleteSecurityContext(&ctxt_);
    535     memset(&ctxt_, 0, sizeof(ctxt_));
    536   }
    537   if (server_cert_)
    538     server_cert_ = NULL;
    539 
    540   // TODO(wtc): reset more members?
    541   bytes_decrypted_ = 0;
    542   bytes_received_ = 0;
    543   writing_first_token_ = false;
    544   renegotiating_ = false;
    545   need_more_data_ = false;
    546 }
    547 
    548 bool SSLClientSocketWin::IsConnected() const {
    549   // Ideally, we should also check if we have received the close_notify alert
    550   // message from the server, and return false in that case.  We're not doing
    551   // that, so this function may return a false positive.  Since the upper
    552   // layer (HttpNetworkTransaction) needs to handle a persistent connection
    553   // closed by the server when we send a request anyway, a false positive in
    554   // exchange for simpler code is a good trade-off.
    555   return completed_handshake() && transport_->IsConnected();
    556 }
    557 
    558 bool SSLClientSocketWin::IsConnectedAndIdle() const {
    559   // Unlike IsConnected, this method doesn't return a false positive.
    560   //
    561   // Strictly speaking, we should check if we have received the close_notify
    562   // alert message from the server, and return false in that case.  Although
    563   // the close_notify alert message means EOF in the SSL layer, it is just
    564   // bytes to the transport layer below, so transport_->IsConnectedAndIdle()
    565   // returns the desired false when we receive close_notify.
    566   return completed_handshake() && transport_->IsConnectedAndIdle();
    567 }
    568 
    569 int SSLClientSocketWin::GetPeerName(struct sockaddr* name, socklen_t* namelen) {
    570   return transport_->GetPeerName(name, namelen);
    571 }
    572 
    573 int SSLClientSocketWin::Read(IOBuffer* buf, int buf_len,
    574                              CompletionCallback* callback) {
    575   DCHECK(completed_handshake());
    576   DCHECK(!user_read_callback_);
    577 
    578   // If we have surplus decrypted plaintext, satisfy the Read with it without
    579   // reading more ciphertext from the transport socket.
    580   if (bytes_decrypted_ != 0) {
    581     int len = std::min(buf_len, bytes_decrypted_);
    582     memcpy(buf->data(), decrypted_ptr_, len);
    583     decrypted_ptr_ += len;
    584     bytes_decrypted_ -= len;
    585     if (bytes_decrypted_ == 0) {
    586       decrypted_ptr_ = NULL;
    587       if (bytes_received_ != 0) {
    588         memmove(recv_buffer_.get(), received_ptr_, bytes_received_);
    589         received_ptr_ = recv_buffer_.get();
    590       }
    591     }
    592     return len;
    593   }
    594 
    595   DCHECK(!user_read_buf_);
    596   // http://crbug.com/16371: We're seeing |buf->data()| return NULL.  See if the
    597   // user is passing in an IOBuffer with a NULL |data_|.
    598   CHECK(buf);
    599   CHECK(buf->data());
    600   user_read_buf_ = buf;
    601   user_read_buf_len_ = buf_len;
    602 
    603   int rv = DoPayloadRead();
    604   if (rv == ERR_IO_PENDING) {
    605     user_read_callback_ = callback;
    606   } else {
    607     user_read_buf_ = NULL;
    608     user_read_buf_len_ = 0;
    609   }
    610   return rv;
    611 }
    612 
    613 int SSLClientSocketWin::Write(IOBuffer* buf, int buf_len,
    614                               CompletionCallback* callback) {
    615   DCHECK(completed_handshake());
    616   DCHECK(!user_write_callback_);
    617 
    618   DCHECK(!user_write_buf_);
    619   user_write_buf_ = buf;
    620   user_write_buf_len_ = buf_len;
    621 
    622   int rv = DoPayloadEncrypt();
    623   if (rv != OK)
    624     return rv;
    625 
    626   rv = DoPayloadWrite();
    627   if (rv == ERR_IO_PENDING) {
    628     user_write_callback_ = callback;
    629   } else {
    630     user_write_buf_ = NULL;
    631     user_write_buf_len_ = 0;
    632   }
    633   return rv;
    634 }
    635 
    636 bool SSLClientSocketWin::SetReceiveBufferSize(int32 size) {
    637   return transport_->SetReceiveBufferSize(size);
    638 }
    639 
    640 bool SSLClientSocketWin::SetSendBufferSize(int32 size) {
    641   return transport_->SetSendBufferSize(size);
    642 }
    643 
    644 void SSLClientSocketWin::OnHandshakeIOComplete(int result) {
    645   int rv = DoLoop(result);
    646 
    647   // The SSL handshake has some round trips.  Any error, other than waiting
    648   // for IO, means that we've failed and need to notify the caller.
    649   if (rv != ERR_IO_PENDING) {
    650     LoadLog::EndEvent(load_log_, LoadLog::TYPE_SSL_CONNECT);
    651     load_log_ = NULL;
    652 
    653     // If there is no connect callback available to call, it had better be
    654     // because we are renegotiating (which occurs because we are in the middle
    655     // of a Read when the renegotiation process starts).  We need to inform the
    656     // caller of the SSL error, so we complete the Read here.
    657     if (!user_connect_callback_) {
    658       DCHECK(renegotiating_);
    659       CompletionCallback* c = user_read_callback_;
    660       user_read_callback_ = NULL;
    661       user_read_buf_ = NULL;
    662       user_read_buf_len_ = 0;
    663       c->Run(rv);
    664       return;
    665     }
    666     CompletionCallback* c = user_connect_callback_;
    667     user_connect_callback_ = NULL;
    668     c->Run(rv);
    669   }
    670 }
    671 
    672 void SSLClientSocketWin::OnReadComplete(int result) {
    673   DCHECK(completed_handshake());
    674 
    675   result = DoPayloadReadComplete(result);
    676   if (result > 0)
    677     result = DoPayloadDecrypt();
    678   if (result != ERR_IO_PENDING) {
    679     DCHECK(user_read_callback_);
    680     CompletionCallback* c = user_read_callback_;
    681     user_read_callback_ = NULL;
    682     user_read_buf_ = NULL;
    683     user_read_buf_len_ = 0;
    684     c->Run(result);
    685   }
    686 }
    687 
    688 void SSLClientSocketWin::OnWriteComplete(int result) {
    689   DCHECK(completed_handshake());
    690 
    691   int rv = DoPayloadWriteComplete(result);
    692   if (rv != ERR_IO_PENDING) {
    693     DCHECK(user_write_callback_);
    694     CompletionCallback* c = user_write_callback_;
    695     user_write_callback_ = NULL;
    696     user_write_buf_ = NULL;
    697     user_write_buf_len_ = 0;
    698     c->Run(rv);
    699   }
    700 }
    701 
    702 
    703 int SSLClientSocketWin::DoLoop(int last_io_result) {
    704   DCHECK(next_state_ != STATE_NONE);
    705   int rv = last_io_result;
    706   do {
    707     State state = next_state_;
    708     next_state_ = STATE_NONE;
    709     switch (state) {
    710       case STATE_HANDSHAKE_READ:
    711         rv = DoHandshakeRead();
    712         break;
    713       case STATE_HANDSHAKE_READ_COMPLETE:
    714         rv = DoHandshakeReadComplete(rv);
    715         break;
    716       case STATE_HANDSHAKE_WRITE:
    717         rv = DoHandshakeWrite();
    718         break;
    719       case STATE_HANDSHAKE_WRITE_COMPLETE:
    720         rv = DoHandshakeWriteComplete(rv);
    721         break;
    722       case STATE_VERIFY_CERT:
    723         rv = DoVerifyCert();
    724         break;
    725       case STATE_VERIFY_CERT_COMPLETE:
    726         rv = DoVerifyCertComplete(rv);
    727         break;
    728       case STATE_COMPLETED_RENEGOTIATION:
    729         rv = DoCompletedRenegotiation(rv);
    730         break;
    731       case STATE_COMPLETED_HANDSHAKE:
    732         next_state_ = STATE_COMPLETED_HANDSHAKE;
    733         // This is the end of our state machine, so return.
    734         return rv;
    735       default:
    736         rv = ERR_UNEXPECTED;
    737         NOTREACHED() << "unexpected state";
    738         break;
    739     }
    740   } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
    741   return rv;
    742 }
    743 
    744 int SSLClientSocketWin::DoHandshakeRead() {
    745   next_state_ = STATE_HANDSHAKE_READ_COMPLETE;
    746 
    747   if (!recv_buffer_.get())
    748     recv_buffer_.reset(new char[kRecvBufferSize]);
    749 
    750   int buf_len = kRecvBufferSize - bytes_received_;
    751 
    752   if (buf_len <= 0) {
    753     NOTREACHED() << "Receive buffer is too small!";
    754     return ERR_UNEXPECTED;
    755   }
    756 
    757   DCHECK(!transport_read_buf_);
    758   transport_read_buf_ = new IOBuffer(buf_len);
    759 
    760   return transport_->Read(transport_read_buf_, buf_len,
    761                           &handshake_io_callback_);
    762 }
    763 
    764 int SSLClientSocketWin::DoHandshakeReadComplete(int result) {
    765   if (result < 0) {
    766     transport_read_buf_ = NULL;
    767     return result;
    768   }
    769 
    770   if (transport_read_buf_) {
    771     // A transition to STATE_HANDSHAKE_READ_COMPLETE is set in multiple places,
    772     // not only in DoHandshakeRead(), so we may not have a transport_read_buf_.
    773     DCHECK_LE(result, kRecvBufferSize - bytes_received_);
    774     char* buf = recv_buffer_.get() + bytes_received_;
    775     memcpy(buf, transport_read_buf_->data(), result);
    776     transport_read_buf_ = NULL;
    777   }
    778 
    779   if (result == 0 && !ignore_ok_result_)
    780     return ERR_SSL_PROTOCOL_ERROR;  // Incomplete response :(
    781 
    782   ignore_ok_result_ = false;
    783 
    784   bytes_received_ += result;
    785 
    786   // Process the contents of recv_buffer_.
    787   TimeStamp expiry;
    788   DWORD out_flags;
    789 
    790   DWORD flags = ISC_REQ_SEQUENCE_DETECT |
    791                 ISC_REQ_REPLAY_DETECT |
    792                 ISC_REQ_CONFIDENTIALITY |
    793                 ISC_RET_EXTENDED_ERROR |
    794                 ISC_REQ_ALLOCATE_MEMORY |
    795                 ISC_REQ_STREAM;
    796 
    797   if (ssl_config_.send_client_cert)
    798     flags |= ISC_REQ_USE_SUPPLIED_CREDS;
    799 
    800   SecBufferDesc in_buffer_desc, out_buffer_desc;
    801 
    802   in_buffer_desc.cBuffers = 2;
    803   in_buffer_desc.pBuffers = in_buffers_;
    804   in_buffer_desc.ulVersion = SECBUFFER_VERSION;
    805 
    806   in_buffers_[0].pvBuffer = recv_buffer_.get();
    807   in_buffers_[0].cbBuffer = bytes_received_;
    808   in_buffers_[0].BufferType = SECBUFFER_TOKEN;
    809 
    810   in_buffers_[1].pvBuffer = NULL;
    811   in_buffers_[1].cbBuffer = 0;
    812   in_buffers_[1].BufferType = SECBUFFER_EMPTY;
    813 
    814   out_buffer_desc.cBuffers = 1;
    815   out_buffer_desc.pBuffers = &send_buffer_;
    816   out_buffer_desc.ulVersion = SECBUFFER_VERSION;
    817 
    818   send_buffer_.pvBuffer = NULL;
    819   send_buffer_.BufferType = SECBUFFER_TOKEN;
    820   send_buffer_.cbBuffer = 0;
    821 
    822   isc_status_ = InitializeSecurityContext(
    823       creds_,
    824       &ctxt_,
    825       NULL,
    826       flags,
    827       0,
    828       SECURITY_NATIVE_DREP,
    829       &in_buffer_desc,
    830       0,
    831       NULL,
    832       &out_buffer_desc,
    833       &out_flags,
    834       &expiry);
    835 
    836   if (send_buffer_.cbBuffer != 0 &&
    837       (isc_status_ == SEC_E_OK ||
    838        isc_status_ == SEC_I_CONTINUE_NEEDED ||
    839       (FAILED(isc_status_) && (out_flags & ISC_RET_EXTENDED_ERROR)))) {
    840     next_state_ = STATE_HANDSHAKE_WRITE;
    841     return OK;
    842   }
    843   return DidCallInitializeSecurityContext();
    844 }
    845 
    846 int SSLClientSocketWin::DidCallInitializeSecurityContext() {
    847   if (isc_status_ == SEC_E_INCOMPLETE_MESSAGE) {
    848     next_state_ = STATE_HANDSHAKE_READ;
    849     return OK;
    850   }
    851 
    852   if (isc_status_ == SEC_E_OK) {
    853     if (in_buffers_[1].BufferType == SECBUFFER_EXTRA) {
    854       // Save this data for later.
    855       memmove(recv_buffer_.get(),
    856               recv_buffer_.get() + (bytes_received_ - in_buffers_[1].cbBuffer),
    857               in_buffers_[1].cbBuffer);
    858       bytes_received_ = in_buffers_[1].cbBuffer;
    859     } else {
    860       bytes_received_ = 0;
    861     }
    862     return DidCompleteHandshake();
    863   }
    864 
    865   if (FAILED(isc_status_)) {
    866     int result = MapSecurityError(isc_status_);
    867     // We told Schannel to not verify the server certificate
    868     // (SCH_CRED_MANUAL_CRED_VALIDATION), so any certificate error returned by
    869     // InitializeSecurityContext must be referring to the bad or missing
    870     // client certificate.
    871     if (IsCertificateError(result)) {
    872       // TODO(wtc): Add new error codes for client certificate errors reported
    873       // by the server using SSL/TLS alert messages.  See the MSDN page
    874       // "Schannel Error Codes for TLS and SSL Alerts", which maps TLS alert
    875       // messages to Windows error codes:
    876       // http://msdn.microsoft.com/en-us/library/dd721886%28VS.85%29.aspx
    877       return ERR_BAD_SSL_CLIENT_AUTH_CERT;
    878     }
    879     return result;
    880   }
    881 
    882   if (isc_status_ == SEC_I_INCOMPLETE_CREDENTIALS)
    883     return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
    884 
    885   DCHECK(isc_status_ == SEC_I_CONTINUE_NEEDED);
    886   if (in_buffers_[1].BufferType == SECBUFFER_EXTRA) {
    887     memmove(recv_buffer_.get(),
    888             recv_buffer_.get() + (bytes_received_ - in_buffers_[1].cbBuffer),
    889             in_buffers_[1].cbBuffer);
    890     bytes_received_ = in_buffers_[1].cbBuffer;
    891     next_state_ = STATE_HANDSHAKE_READ_COMPLETE;
    892     ignore_ok_result_ = true;  // OK doesn't mean EOF.
    893     return OK;
    894   }
    895 
    896   bytes_received_ = 0;
    897   next_state_ = STATE_HANDSHAKE_READ;
    898   return OK;
    899 }
    900 
    901 int SSLClientSocketWin::DoHandshakeWrite() {
    902   next_state_ = STATE_HANDSHAKE_WRITE_COMPLETE;
    903 
    904   // We should have something to send.
    905   DCHECK(send_buffer_.pvBuffer);
    906   DCHECK(send_buffer_.cbBuffer > 0);
    907   DCHECK(!transport_write_buf_);
    908 
    909   const char* buf = static_cast<char*>(send_buffer_.pvBuffer) + bytes_sent_;
    910   int buf_len = send_buffer_.cbBuffer - bytes_sent_;
    911   transport_write_buf_ = new IOBuffer(buf_len);
    912   memcpy(transport_write_buf_->data(), buf, buf_len);
    913 
    914   return transport_->Write(transport_write_buf_, buf_len,
    915                            &handshake_io_callback_);
    916 }
    917 
    918 int SSLClientSocketWin::DoHandshakeWriteComplete(int result) {
    919   DCHECK(transport_write_buf_);
    920   transport_write_buf_ = NULL;
    921   if (result < 0)
    922     return result;
    923 
    924   DCHECK(result != 0);
    925 
    926   bytes_sent_ += result;
    927   DCHECK(bytes_sent_ <= static_cast<int>(send_buffer_.cbBuffer));
    928 
    929   if (bytes_sent_ >= static_cast<int>(send_buffer_.cbBuffer)) {
    930     bool overflow = (bytes_sent_ > static_cast<int>(send_buffer_.cbBuffer));
    931     FreeSendBuffer();
    932     bytes_sent_ = 0;
    933     if (overflow)  // Bug!
    934       return ERR_UNEXPECTED;
    935     if (writing_first_token_) {
    936       writing_first_token_ = false;
    937       DCHECK(bytes_received_ == 0);
    938       next_state_ = STATE_HANDSHAKE_READ;
    939       return OK;
    940     }
    941     return DidCallInitializeSecurityContext();
    942   }
    943 
    944   // Send the remaining bytes.
    945   next_state_ = STATE_HANDSHAKE_WRITE;
    946   return OK;
    947 }
    948 
    949 // Set server_cert_status_ and return OK or a network error.
    950 int SSLClientSocketWin::DoVerifyCert() {
    951   next_state_ = STATE_VERIFY_CERT_COMPLETE;
    952 
    953   DCHECK(server_cert_);
    954 
    955   int flags = 0;
    956   if (ssl_config_.rev_checking_enabled)
    957     flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
    958   if (ssl_config_.verify_ev_cert)
    959     flags |= X509Certificate::VERIFY_EV_CERT;
    960   verifier_.reset(new CertVerifier);
    961   return verifier_->Verify(server_cert_, hostname_, flags,
    962                            &server_cert_verify_result_,
    963                            &handshake_io_callback_);
    964 }
    965 
    966 int SSLClientSocketWin::DoVerifyCertComplete(int result) {
    967   DCHECK(verifier_.get());
    968   verifier_.reset();
    969 
    970   // If we have been explicitly told to accept this certificate, override the
    971   // result of verifier_.Verify.
    972   // Eventually, we should cache the cert verification results so that we don't
    973   // need to call verifier_.Verify repeatedly. But for now we need to do this.
    974   // Alternatively, we could use the cert's status that we stored along with
    975   // the cert in the allowed_bad_certs vector.
    976   if (IsCertificateError(result) &&
    977       ssl_config_.IsAllowedBadCert(server_cert_))
    978     result = OK;
    979 
    980   LogConnectionTypeMetrics(result >= 0);
    981   if (renegotiating_) {
    982     DidCompleteRenegotiation();
    983     return result;
    984   }
    985 
    986   // The initial handshake has completed.
    987   next_state_ = STATE_COMPLETED_HANDSHAKE;
    988   return result;
    989 }
    990 
    991 int SSLClientSocketWin::DoPayloadRead() {
    992   DCHECK(recv_buffer_.get());
    993 
    994   int buf_len = kRecvBufferSize - bytes_received_;
    995 
    996   if (buf_len <= 0) {
    997     NOTREACHED() << "Receive buffer is too small!";
    998     return ERR_FAILED;
    999   }
   1000 
   1001   int rv;
   1002   // If bytes_received_, we have some data from a previous read still ready
   1003   // for decoding.  Otherwise, we need to issue a real read.
   1004   if (!bytes_received_ || need_more_data_) {
   1005     DCHECK(!transport_read_buf_);
   1006     transport_read_buf_ = new IOBuffer(buf_len);
   1007 
   1008     rv = transport_->Read(transport_read_buf_, buf_len, &read_callback_);
   1009     if (rv != ERR_IO_PENDING)
   1010       rv = DoPayloadReadComplete(rv);
   1011     if (rv <= 0)
   1012       return rv;
   1013   }
   1014 
   1015   // Decode what we've read.  If there is not enough data to decode yet,
   1016   // this may return ERR_IO_PENDING still.
   1017   return DoPayloadDecrypt();
   1018 }
   1019 
   1020 // result is the number of bytes that have been read; it should not be
   1021 // less than zero; a value of zero means that no additional bytes have
   1022 // been read.
   1023 int SSLClientSocketWin::DoPayloadReadComplete(int result) {
   1024   DCHECK(completed_handshake());
   1025 
   1026   // If IO Pending, there is nothing to do here.
   1027   if (result == ERR_IO_PENDING)
   1028     return result;
   1029 
   1030   // We completed a Read, so reset the need_more_data_ flag.
   1031   need_more_data_ = false;
   1032 
   1033   // Check for error
   1034   if (result <= 0) {
   1035     transport_read_buf_ = NULL;
   1036     if (result == 0 && bytes_received_ != 0) {
   1037       // TODO(wtc): Unless we have received the close_notify alert, we need
   1038       // to return an error code indicating that the SSL connection ended
   1039       // uncleanly, a potential truncation attack.  See
   1040       // http://crbug.com/18586.
   1041       return ERR_SSL_PROTOCOL_ERROR;
   1042     }
   1043     return result;
   1044   }
   1045 
   1046   // Transfer the data from transport_read_buf_ to recv_buffer_.
   1047   if (transport_read_buf_) {
   1048     DCHECK_LE(result, kRecvBufferSize - bytes_received_);
   1049     char* buf = recv_buffer_.get() + bytes_received_;
   1050     memcpy(buf, transport_read_buf_->data(), result);
   1051     transport_read_buf_ = NULL;
   1052   }
   1053 
   1054   bytes_received_ += result;
   1055 
   1056   return result;
   1057 }
   1058 
   1059 int SSLClientSocketWin::DoPayloadDecrypt() {
   1060   // Process the contents of recv_buffer_.
   1061   int len = 0;  // the number of bytes we've copied to the user buffer.
   1062   while (bytes_received_) {
   1063     SecBuffer buffers[4];
   1064     buffers[0].pvBuffer = recv_buffer_.get();
   1065     buffers[0].cbBuffer = bytes_received_;
   1066     buffers[0].BufferType = SECBUFFER_DATA;
   1067 
   1068     buffers[1].BufferType = SECBUFFER_EMPTY;
   1069     buffers[2].BufferType = SECBUFFER_EMPTY;
   1070     buffers[3].BufferType = SECBUFFER_EMPTY;
   1071 
   1072     SecBufferDesc buffer_desc;
   1073     buffer_desc.cBuffers = 4;
   1074     buffer_desc.pBuffers = buffers;
   1075     buffer_desc.ulVersion = SECBUFFER_VERSION;
   1076 
   1077     SECURITY_STATUS status;
   1078     status = DecryptMessage(&ctxt_, &buffer_desc, 0, NULL);
   1079 
   1080     if (status == SEC_E_INCOMPLETE_MESSAGE) {
   1081       need_more_data_ = true;
   1082       return DoPayloadRead();
   1083     }
   1084 
   1085     if (status == SEC_I_CONTEXT_EXPIRED) {
   1086       // Received the close_notify alert.
   1087       bytes_received_ = 0;
   1088       return OK;
   1089     }
   1090 
   1091     if (status != SEC_E_OK && status != SEC_I_RENEGOTIATE) {
   1092       DCHECK(status != SEC_E_MESSAGE_ALTERED);
   1093       return MapSecurityError(status);
   1094     }
   1095 
   1096     // The received ciphertext was decrypted in place in recv_buffer_.  Remember
   1097     // the location and length of the decrypted plaintext and any unused
   1098     // ciphertext.
   1099     decrypted_ptr_ = NULL;
   1100     bytes_decrypted_ = 0;
   1101     received_ptr_ = NULL;
   1102     bytes_received_ = 0;
   1103     for (int i = 1; i < 4; i++) {
   1104       switch (buffers[i].BufferType) {
   1105         case SECBUFFER_DATA:
   1106           DCHECK(!decrypted_ptr_ && bytes_decrypted_ == 0);
   1107           decrypted_ptr_ = static_cast<char*>(buffers[i].pvBuffer);
   1108           bytes_decrypted_ = buffers[i].cbBuffer;
   1109           break;
   1110         case SECBUFFER_EXTRA:
   1111           DCHECK(!received_ptr_ && bytes_received_ == 0);
   1112           received_ptr_ = static_cast<char*>(buffers[i].pvBuffer);
   1113           bytes_received_ = buffers[i].cbBuffer;
   1114           break;
   1115         default:
   1116           break;
   1117       }
   1118     }
   1119 
   1120     DCHECK(len == 0);
   1121     if (bytes_decrypted_ != 0) {
   1122       len = std::min(user_read_buf_len_, bytes_decrypted_);
   1123       memcpy(user_read_buf_->data(), decrypted_ptr_, len);
   1124       decrypted_ptr_ += len;
   1125       bytes_decrypted_ -= len;
   1126     }
   1127     if (bytes_decrypted_ == 0) {
   1128       decrypted_ptr_ = NULL;
   1129       if (bytes_received_ != 0) {
   1130         memmove(recv_buffer_.get(), received_ptr_, bytes_received_);
   1131         received_ptr_ = recv_buffer_.get();
   1132       }
   1133     }
   1134 
   1135     if (status == SEC_I_RENEGOTIATE) {
   1136       if (bytes_received_ != 0) {
   1137         // The server requested renegotiation, but there are some data yet to
   1138         // be decrypted.  The Platform SDK WebClient.c sample doesn't handle
   1139         // this, so we don't know how to handle this.  Assume this cannot
   1140         // happen.
   1141         LOG(ERROR) << "DecryptMessage returned SEC_I_RENEGOTIATE with a buffer "
   1142                    << "of type SECBUFFER_EXTRA.";
   1143         return ERR_SSL_RENEGOTIATION_REQUESTED;
   1144       }
   1145       if (len != 0) {
   1146         // The server requested renegotiation, but there are some decrypted
   1147         // data.  We can't start renegotiation until we have returned all
   1148         // decrypted data to the caller.
   1149         //
   1150         // This hasn't happened during testing.  Assume this cannot happen even
   1151         // though we know how to handle this.
   1152         LOG(ERROR) << "DecryptMessage returned SEC_I_RENEGOTIATE with a buffer "
   1153                    << "of type SECBUFFER_DATA.";
   1154         return ERR_SSL_RENEGOTIATION_REQUESTED;
   1155       }
   1156       // Jump to the handshake sequence.  Will come back when the rehandshake is
   1157       // done.
   1158       renegotiating_ = true;
   1159       ignore_ok_result_ = true;  // OK doesn't mean EOF.
   1160       // If renegotiation handshake occurred, we need to go back into the
   1161       // handshake state machine.
   1162       next_state_ = STATE_HANDSHAKE_READ_COMPLETE;
   1163       return DoLoop(OK);
   1164     }
   1165 
   1166     // We've already copied data into the user buffer, so quit now.
   1167     // TODO(mbelshe): We really should keep decoding as long as we can.  This
   1168     // break out is causing us to return pretty small chunks of data up to the
   1169     // application, even though more is already buffered and ready to be
   1170     // decoded.
   1171     if (len)
   1172       break;
   1173   }
   1174 
   1175   // If we decrypted 0 bytes, don't report 0 bytes read, which would be
   1176   // mistaken for EOF.  Continue decrypting or read more.
   1177   if (len == 0)
   1178     return DoPayloadRead();
   1179   return len;
   1180 }
   1181 
   1182 int SSLClientSocketWin::DoPayloadEncrypt() {
   1183   DCHECK(completed_handshake());
   1184   DCHECK(user_write_buf_);
   1185   DCHECK(user_write_buf_len_ > 0);
   1186 
   1187   ULONG message_len = std::min(
   1188       stream_sizes_.cbMaximumMessage, static_cast<ULONG>(user_write_buf_len_));
   1189   ULONG alloc_len =
   1190       message_len + stream_sizes_.cbHeader + stream_sizes_.cbTrailer;
   1191   user_write_buf_len_ = message_len;
   1192 
   1193   payload_send_buffer_.reset(new char[alloc_len]);
   1194   memcpy(&payload_send_buffer_[stream_sizes_.cbHeader],
   1195          user_write_buf_->data(), message_len);
   1196 
   1197   SecBuffer buffers[4];
   1198   buffers[0].pvBuffer = payload_send_buffer_.get();
   1199   buffers[0].cbBuffer = stream_sizes_.cbHeader;
   1200   buffers[0].BufferType = SECBUFFER_STREAM_HEADER;
   1201 
   1202   buffers[1].pvBuffer = &payload_send_buffer_[stream_sizes_.cbHeader];
   1203   buffers[1].cbBuffer = message_len;
   1204   buffers[1].BufferType = SECBUFFER_DATA;
   1205 
   1206   buffers[2].pvBuffer = &payload_send_buffer_[stream_sizes_.cbHeader +
   1207                                               message_len];
   1208   buffers[2].cbBuffer = stream_sizes_.cbTrailer;
   1209   buffers[2].BufferType = SECBUFFER_STREAM_TRAILER;
   1210 
   1211   buffers[3].BufferType = SECBUFFER_EMPTY;
   1212 
   1213   SecBufferDesc buffer_desc;
   1214   buffer_desc.cBuffers = 4;
   1215   buffer_desc.pBuffers = buffers;
   1216   buffer_desc.ulVersion = SECBUFFER_VERSION;
   1217 
   1218   SECURITY_STATUS status = EncryptMessage(&ctxt_, 0, &buffer_desc, 0);
   1219 
   1220   if (FAILED(status))
   1221     return MapSecurityError(status);
   1222 
   1223   payload_send_buffer_len_ = buffers[0].cbBuffer +
   1224                              buffers[1].cbBuffer +
   1225                              buffers[2].cbBuffer;
   1226   DCHECK(bytes_sent_ == 0);
   1227   return OK;
   1228 }
   1229 
   1230 int SSLClientSocketWin::DoPayloadWrite() {
   1231   DCHECK(completed_handshake());
   1232 
   1233   // We should have something to send.
   1234   DCHECK(payload_send_buffer_.get());
   1235   DCHECK(payload_send_buffer_len_ > 0);
   1236   DCHECK(!transport_write_buf_);
   1237 
   1238   const char* buf = payload_send_buffer_.get() + bytes_sent_;
   1239   int buf_len = payload_send_buffer_len_ - bytes_sent_;
   1240   transport_write_buf_ = new IOBuffer(buf_len);
   1241   memcpy(transport_write_buf_->data(), buf, buf_len);
   1242 
   1243   int rv = transport_->Write(transport_write_buf_, buf_len, &write_callback_);
   1244   if (rv != ERR_IO_PENDING)
   1245     rv = DoPayloadWriteComplete(rv);
   1246   return rv;
   1247 }
   1248 
   1249 int SSLClientSocketWin::DoPayloadWriteComplete(int result) {
   1250   DCHECK(transport_write_buf_);
   1251   transport_write_buf_ = NULL;
   1252   if (result < 0)
   1253     return result;
   1254 
   1255   DCHECK(result != 0);
   1256 
   1257   bytes_sent_ += result;
   1258   DCHECK(bytes_sent_ <= payload_send_buffer_len_);
   1259 
   1260   if (bytes_sent_ >= payload_send_buffer_len_) {
   1261     bool overflow = (bytes_sent_ > payload_send_buffer_len_);
   1262     payload_send_buffer_.reset();
   1263     payload_send_buffer_len_ = 0;
   1264     bytes_sent_ = 0;
   1265     if (overflow)  // Bug!
   1266       return ERR_UNEXPECTED;
   1267     // Done
   1268     return user_write_buf_len_;
   1269   }
   1270 
   1271   // Send the remaining bytes.
   1272   return DoPayloadWrite();
   1273 }
   1274 
   1275 int SSLClientSocketWin::DoCompletedRenegotiation(int result) {
   1276   // The user had a read in progress, which was usurped by the renegotiation.
   1277   // Restart the read sequence.
   1278   next_state_ = STATE_COMPLETED_HANDSHAKE;
   1279   DCHECK(result == OK);
   1280   return DoPayloadRead();
   1281 }
   1282 
   1283 int SSLClientSocketWin::DidCompleteHandshake() {
   1284   SECURITY_STATUS status = QueryContextAttributes(
   1285       &ctxt_, SECPKG_ATTR_STREAM_SIZES, &stream_sizes_);
   1286   if (status != SEC_E_OK) {
   1287     DLOG(ERROR) << "QueryContextAttributes (stream sizes) failed: " << status;
   1288     return MapSecurityError(status);
   1289   }
   1290   DCHECK(!server_cert_ || renegotiating_);
   1291   PCCERT_CONTEXT server_cert_handle = NULL;
   1292   status = QueryContextAttributes(
   1293       &ctxt_, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &server_cert_handle);
   1294   if (status != SEC_E_OK) {
   1295     DLOG(ERROR) << "QueryContextAttributes (remote cert) failed: " << status;
   1296     return MapSecurityError(status);
   1297   }
   1298   if (renegotiating_ &&
   1299       SameCert(server_cert_->os_cert_handle(), server_cert_handle)) {
   1300     // We already verified the server certificate.  Either it is good or the
   1301     // user has accepted the certificate error.
   1302     CertFreeCertificateContext(server_cert_handle);
   1303     DidCompleteRenegotiation();
   1304   } else {
   1305     server_cert_ = X509Certificate::CreateFromHandle(
   1306         server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK);
   1307 
   1308     next_state_ = STATE_VERIFY_CERT;
   1309   }
   1310   return OK;
   1311 }
   1312 
   1313 // Called when a renegotiation is completed.  |result| is the verification
   1314 // result of the server certificate received during renegotiation.
   1315 void SSLClientSocketWin::DidCompleteRenegotiation() {
   1316   renegotiating_ = false;
   1317   next_state_ = STATE_COMPLETED_RENEGOTIATION;
   1318 }
   1319 
   1320 void SSLClientSocketWin::LogConnectionTypeMetrics(bool success) const {
   1321   UpdateConnectionTypeHistograms(CONNECTION_SSL, success);
   1322   if (server_cert_verify_result_.has_md5)
   1323     UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5, success);
   1324   if (server_cert_verify_result_.has_md2)
   1325     UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2, success);
   1326   if (server_cert_verify_result_.has_md4)
   1327     UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4, success);
   1328   if (server_cert_verify_result_.has_md5_ca)
   1329     UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA, success);
   1330   if (server_cert_verify_result_.has_md2_ca)
   1331     UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA, success);
   1332 }
   1333 
   1334 void SSLClientSocketWin::FreeSendBuffer() {
   1335   SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer);
   1336   DCHECK(status == SEC_E_OK);
   1337   memset(&send_buffer_, 0, sizeof(send_buffer_));
   1338 }
   1339 
   1340 }  // namespace net
   1341