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