// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/socket/ssl_client_socket_mac.h"

#include <CoreServices/CoreServices.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <algorithm>

#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/mac/mac_logging.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/string_util.h"
#include "net/base/address_list.h"
#include "net/base/cert_verifier.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
#include "net/base/single_request_cert_verifier.h"
#include "net/base/ssl_cert_request_info.h"
#include "net/base/ssl_connection_status_flags.h"
#include "net/base/ssl_info.h"
#include "net/base/x509_certificate_net_log_param.h"
#include "net/base/x509_util.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/ssl_error_params.h"

// Welcome to Mac SSL. We've been waiting for you.
//
// The Mac SSL implementation is, like the Windows and NSS implementations, a
// giant state machine. This design constraint is due to the asynchronous nature
// of our underlying transport mechanism. We can call down to read/write on the
// network, but what happens is that either it completes immediately or returns
// saying that we'll get a callback sometime in the future. In that case, we
// have to return to our caller but pick up where we left off when we
// resume. Thus the fun.
//
// On Windows, we use Security Contexts, which are driven by us. We fetch data
// from the network, we call the context to decrypt the data, and so on. On the
// Mac, however, we provide Secure Transport with callbacks to get data from the
// network, and it calls us back to fetch the data from the network for
// it. Therefore, there are different sets of states in our respective state
// machines, fewer on the Mac because Secure Transport keeps a lot of its own
// state. The discussion about what each of the states means lives in comments
// in the DoHandshakeLoop() function.
//
// Secure Transport is designed for use by either blocking or non-blocking
// network I/O. If, for example, you called SSLRead() to fetch data, Secure
// Transport will, unless it has some cached data, issue a read to your network
// callback read function to fetch it some more encrypted data. It's expecting
// one of two things. If your function is hooked up to a blocking source, then
// it'll block pending receipt of the data from the other end. That's fine, as
// when you return with the data, Secure Transport will do its thing. On the
// other hand, suppose that your socket is non-blocking and tells your function
// that it would block. Then you let Secure Transport know, and it'll tell the
// original caller that it would have blocked and that they need to call it
// "later."
//
// When's "later," though? We have fully-asynchronous networking, so we get a
// callback when our data's ready. But Secure Transport has no way for us to
// tell it that data has arrived, so we must re-execute the call that triggered
// the I/O (we rely on our state machine to do this). When we do so Secure
// Transport will ask once again for the data. Chances are that it'll be the
// same request as the previous time, but that's not actually guaranteed. But as
// long as we buffer what we have and keep track of where we were, it works
// quite well.
//
// Except for network writes. They shoot this plan straight to hell.
//
// Faking a blocking connection with an asynchronous connection (theoretically
// more powerful) simply doesn't work for writing. Suppose that Secure Transport
// requests a write of data to the network. With blocking I/O, we'd just block
// until the write completed, and with non-blocking I/O we'd know how many bytes
// we wrote before we would have blocked. But with the asynchronous I/O, the
// transport underneath us can tell us that it'll let us know sometime "later"
// whether or not things succeeded, and how many bytes were written. What do we
// return to Secure Transport? We can't return a byte count, but we can't return
// "later" as we're not guaranteed to be called in the future with the same data
// to write.
//
// So, like in any good relationship, we're forced to lie. Whenever Secure
// Transport asks for data to be written, we take it all and lie about it always
// being written. We spin in a loop (see SSLWriteCallback() and
// OnTransportWriteComplete()) independent of the main state machine writing
// the data to the network, and get the data out. The main consequence of this
// independence from the state machine is that we require a full-duplex
// transport underneath us since we can't use it to keep our reading and
// writing straight. Fortunately, the NSS implementation also has this issue
// to deal with, so we share the same Libevent-based full-duplex TCP socket.
//
// A side comment on return values might be in order. Those who haven't taken
// the time to read the documentation (ahem, header comments) in our various
// files might be a bit surprised to see result values being treated as both
// lengths and errors. Like Shimmer, they are both. In both the case of
// immediate results as well as results returned in callbacks, a negative return
// value indicates an error, a zero return value indicates end-of-stream (for
// reads), and a positive return value indicates the number of bytes read or
// written. Thus, many functions start off with |if (result < 0) return
// result;|. That gets the error condition out of the way, and from that point
// forward the result can be treated as a length.

namespace net {

namespace {

// Pause if we have 2MB of data in flight, resume once we're down below 1MB.
const unsigned int kWriteSizePauseLimit = 2 * 1024 * 1024;
const unsigned int kWriteSizeResumeLimit = 1 * 1024 * 1024;

#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
// When compiled against the Mac OS X 10.5 SDK, define symbolic constants for
// cipher suites added in Mac OS X 10.6.
enum {
  // ECC cipher suites from RFC 4492.
  TLS_ECDH_ECDSA_WITH_NULL_SHA           = 0xC001,
  TLS_ECDH_ECDSA_WITH_RC4_128_SHA        = 0xC002,
  TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA   = 0xC003,
  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA    = 0xC004,
  TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA    = 0xC005,
  TLS_ECDHE_ECDSA_WITH_NULL_SHA          = 0xC006,
  TLS_ECDHE_ECDSA_WITH_RC4_128_SHA       = 0xC007,
  TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA  = 0xC008,
  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA   = 0xC009,
  TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   = 0xC00A,
  TLS_ECDH_RSA_WITH_NULL_SHA             = 0xC00B,
  TLS_ECDH_RSA_WITH_RC4_128_SHA          = 0xC00C,
  TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA     = 0xC00D,
  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA      = 0xC00E,
  TLS_ECDH_RSA_WITH_AES_256_CBC_SHA      = 0xC00F,
  TLS_ECDHE_RSA_WITH_NULL_SHA            = 0xC010,
  TLS_ECDHE_RSA_WITH_RC4_128_SHA         = 0xC011,
  TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA    = 0xC012,
  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA     = 0xC013,
  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA     = 0xC014,
  TLS_ECDH_anon_WITH_NULL_SHA            = 0xC015,
  TLS_ECDH_anon_WITH_RC4_128_SHA         = 0xC016,
  TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA    = 0xC017,
  TLS_ECDH_anon_WITH_AES_128_CBC_SHA     = 0xC018,
  TLS_ECDH_anon_WITH_AES_256_CBC_SHA     = 0xC019,
};
#endif

// For an explanation of the Mac OS X error codes, please refer to:
// http://developer.apple.com/mac/library/documentation/Security/Reference/secureTransportRef/Reference/reference.html
int NetErrorFromOSStatus(OSStatus status) {
  switch (status) {
    case errSSLWouldBlock:
      return ERR_IO_PENDING;
    case paramErr:
    case errSSLBadCipherSuite:
    case errSSLBadConfiguration:
      return ERR_INVALID_ARGUMENT;
    case errSSLClosedNoNotify:
      return ERR_CONNECTION_RESET;
    case errSSLClosedAbort:
      return ERR_CONNECTION_ABORTED;
    case errSSLInternal:
      return ERR_UNEXPECTED;
    case errSSLBadRecordMac:
    case errSSLCrypto:
    case errSSLConnectionRefused:
    case errSSLDecryptionFail:
    case errSSLFatalAlert:
    case errSSLIllegalParam:  // Received an illegal_parameter alert.
    case errSSLPeerDecodeError:  // Received a decode_error alert.
    case errSSLPeerDecryptError:  // Received a decrypt_error alert.
    case errSSLPeerExportRestriction:  // Received an export_restriction alert.
    case errSSLPeerHandshakeFail:  // Received a handshake_failure alert.
    case errSSLPeerNoRenegotiation:  // Received a no_renegotiation alert
    case errSSLPeerUnexpectedMsg:  // Received an unexpected_message alert.
    case errSSLProtocol:
    case errSSLRecordOverflow:
      return ERR_SSL_PROTOCOL_ERROR;
    case errSSLHostNameMismatch:
      return ERR_CERT_COMMON_NAME_INVALID;
    case errSSLCertExpired:
    case errSSLCertNotYetValid:
      return ERR_CERT_DATE_INVALID;
    case errSSLNoRootCert:
    case errSSLUnknownRootCert:
      return ERR_CERT_AUTHORITY_INVALID;
    case errSSLXCertChainInvalid:
    case errSSLBadCert:
      return ERR_CERT_INVALID;

    case errSSLClosedGraceful:
    case noErr:
      return OK;

    // (Note that all errSSLPeer* codes indicate errors reported by the peer,
    // so the cert-related ones refer to my _client_ cert.)
    // TODO(wtc): Add fine-grained error codes for client certificate errors
    // reported by the server using the following SSL/TLS alert messages:
    //   access_denied
    //   bad_certificate
    //   unsupported_certificate
    //   certificate_expired
    //   certificate_revoked
    //   certificate_unknown
    //   unknown_ca
    case errSSLPeerCertUnknown...errSSLPeerBadCert:
    case errSSLPeerUnknownCA:
    case errSSLPeerAccessDenied:
      OSSTATUS_LOG(WARNING, status) << "Server rejected client cert";
      return ERR_BAD_SSL_CLIENT_AUTH_CERT;

    case errSSLNegotiation:
    case errSSLPeerInsufficientSecurity:
    case errSSLPeerProtocolVersion:
      return ERR_SSL_VERSION_OR_CIPHER_MISMATCH;

    case errSSLBufferOverflow:
    case errSSLModuleAttach:
    case errSSLSessionNotFound:
    default:
      OSSTATUS_LOG(WARNING, status)
          << "Unknown error mapped to net::ERR_FAILED";
      return ERR_FAILED;
  }
}

OSStatus OSStatusFromNetError(int net_error) {
  switch (net_error) {
    case ERR_IO_PENDING:
      return errSSLWouldBlock;
    case ERR_INTERNET_DISCONNECTED:
    case ERR_TIMED_OUT:
    case ERR_CONNECTION_ABORTED:
    case ERR_CONNECTION_RESET:
    case ERR_CONNECTION_REFUSED:
    case ERR_ADDRESS_UNREACHABLE:
    case ERR_ADDRESS_INVALID:
      return errSSLClosedAbort;
    case ERR_UNEXPECTED:
      return errSSLInternal;
    case ERR_INVALID_ARGUMENT:
      return paramErr;
    case OK:
      return noErr;
    default:
      LOG(WARNING) << "Unknown error " << net_error << " mapped to paramErr";
      return paramErr;
  }
}

// Converts from a cipher suite to its key size. If the suite is marked with a
// **, it's not actually implemented in Secure Transport and won't be returned
// (but we'll code for it anyway).  The reference here is
// http://www.opensource.apple.com/darwinsource/10.5.5/libsecurity_ssl-32463/lib/cipherSpecs.c
// Seriously, though, there has to be an API for this, but I can't find one.
// Anybody?
int KeySizeOfCipherSuite(SSLCipherSuite suite) {
  switch (suite) {
    // SSL 2 only

    case SSL_RSA_WITH_DES_CBC_MD5:
      return 56;
    case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
      return 112;
    case SSL_RSA_WITH_RC2_CBC_MD5:
    case SSL_RSA_WITH_IDEA_CBC_MD5:              // **
      return 128;
    case SSL_NO_SUCH_CIPHERSUITE:                // **
      return 0;

    // SSL 2, 3, TLS

    case SSL_NULL_WITH_NULL_NULL:
    case SSL_RSA_WITH_NULL_MD5:
    case SSL_RSA_WITH_NULL_SHA:                  // **
    case SSL_FORTEZZA_DMS_WITH_NULL_SHA:         // **
    case TLS_ECDH_ECDSA_WITH_NULL_SHA:
    case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
    case TLS_ECDH_RSA_WITH_NULL_SHA:
    case TLS_ECDHE_RSA_WITH_NULL_SHA:
    case TLS_ECDH_anon_WITH_NULL_SHA:
      return 0;
    case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
    case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
    case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
    case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:   // **
    case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:   // **
    case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
    case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
    case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
    case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
      return 40;
    case SSL_RSA_WITH_DES_CBC_SHA:
    case SSL_DH_DSS_WITH_DES_CBC_SHA:            // **
    case SSL_DH_RSA_WITH_DES_CBC_SHA:            // **
    case SSL_DHE_DSS_WITH_DES_CBC_SHA:
    case SSL_DHE_RSA_WITH_DES_CBC_SHA:
    case SSL_DH_anon_WITH_DES_CBC_SHA:
      return 56;
    case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA: // **
      return 80;
    case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
    case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:       // **
    case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:       // **
    case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
    case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
    case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
    case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
    case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
    case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
    case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
    case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
      return 112;
    case SSL_RSA_WITH_RC4_128_MD5:
    case SSL_RSA_WITH_RC4_128_SHA:
    case SSL_RSA_WITH_IDEA_CBC_SHA:              // **
    case SSL_DH_anon_WITH_RC4_128_MD5:
    case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
    case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
    case TLS_ECDH_RSA_WITH_RC4_128_SHA:
    case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
    case TLS_ECDH_anon_WITH_RC4_128_SHA:
      return 128;

    // TLS AES options (see RFC 3268 and RFC 4492)

    case TLS_RSA_WITH_AES_128_CBC_SHA:
    case TLS_DH_DSS_WITH_AES_128_CBC_SHA:        // **
    case TLS_DH_RSA_WITH_AES_128_CBC_SHA:        // **
    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
    case TLS_DH_anon_WITH_AES_128_CBC_SHA:
    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
    case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
      return 128;
    case TLS_RSA_WITH_AES_256_CBC_SHA:
    case TLS_DH_DSS_WITH_AES_256_CBC_SHA:        // **
    case TLS_DH_RSA_WITH_AES_256_CBC_SHA:        // **
    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
    case TLS_DH_anon_WITH_AES_256_CBC_SHA:
    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
    case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
      return 256;

    default:
      return -1;
  }
}

// Whitelist the cipher suites we want to enable.  We disable the following
// cipher suites.
// - Null encryption cipher suites.
// - Weak cipher suites: < 80 bits of security strength.
// - FORTEZZA cipher suites (obsolete).
// - IDEA cipher suites (RFC 5469 explains why).
// - Anonymous cipher suites.
//
// Why don't we use a blacklist?  A blacklist that isn't updated for a new
// Mac OS X release is a potential security issue because the new release
// may have new null encryption or anonymous cipher suites, whereas a
// whitelist that isn't updated for a new Mac OS X release just means we
// won't support any new cipher suites in that release.
bool ShouldEnableCipherSuite(SSLCipherSuite suite) {
  switch (suite) {
    case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
    case SSL_RSA_WITH_RC2_CBC_MD5:

    case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
    case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:       // **
    case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:       // **
    case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
    case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
    case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
    case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
    case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
    case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:

    case SSL_RSA_WITH_RC4_128_MD5:
    case SSL_RSA_WITH_RC4_128_SHA:
    case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
    case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
    case TLS_ECDH_RSA_WITH_RC4_128_SHA:
    case TLS_ECDHE_RSA_WITH_RC4_128_SHA:

    case TLS_RSA_WITH_AES_128_CBC_SHA:
    case TLS_DH_DSS_WITH_AES_128_CBC_SHA:        // **
    case TLS_DH_RSA_WITH_AES_128_CBC_SHA:        // **
    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:

    case TLS_RSA_WITH_AES_256_CBC_SHA:
    case TLS_DH_DSS_WITH_AES_256_CBC_SHA:        // **
    case TLS_DH_RSA_WITH_AES_256_CBC_SHA:        // **
    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
      return true;

    default:
      return false;
  }
}

// Returns the server's certificate.  The caller must release a reference
// to the return value when done.  Returns NULL on failure.
X509Certificate* GetServerCert(SSLContextRef ssl_context) {
  CFArrayRef certs;
  OSStatus status = SSLCopyPeerCertificates(ssl_context, &certs);
  // SSLCopyPeerCertificates may succeed but return a null |certs|
  // (if we're using an anonymous cipher suite or if we call it
  // before the certificate message has arrived and been parsed).
  if (status != noErr || !certs)
    return NULL;
  base::mac::ScopedCFTypeRef<CFArrayRef> scoped_certs(certs);

  DCHECK_GT(CFArrayGetCount(certs), 0);

  // Add each of the intermediate certificates in the server's chain to the
  // server's X509Certificate object. This makes them available to
  // X509Certificate::Verify() for chain building.
  std::vector<SecCertificateRef> intermediate_ca_certs;
  CFIndex certs_length = CFArrayGetCount(certs);
  for (CFIndex i = 1; i < certs_length; ++i) {
    SecCertificateRef cert_ref = reinterpret_cast<SecCertificateRef>(
        const_cast<void*>(CFArrayGetValueAtIndex(certs, i)));
    intermediate_ca_certs.push_back(cert_ref);
  }

  SecCertificateRef server_cert = static_cast<SecCertificateRef>(
      const_cast<void*>(CFArrayGetValueAtIndex(certs, 0)));
  return X509Certificate::CreateFromHandle(server_cert,
                                           intermediate_ca_certs);
}

// Dynamically look up a pointer to a function exported by a bundle.
template <typename FNTYPE>
FNTYPE LookupFunction(CFStringRef bundleName, CFStringRef fnName) {
  CFBundleRef bundle = CFBundleGetBundleWithIdentifier(bundleName);
  if (!bundle)
    return NULL;
  return reinterpret_cast<FNTYPE>(
      CFBundleGetFunctionPointerForName(bundle, fnName));
}

struct CipherSuiteIsDisabledFunctor {
  explicit CipherSuiteIsDisabledFunctor(
      const std::vector<uint16>& disabled_cipher_suites)
      : disabled_cipher_suites_(disabled_cipher_suites) {}

  // Returns true if the given |cipher_suite| appears within the set of
  // |disabled_cipher_suites|.
  bool operator()(SSLCipherSuite cipher_suite) const {
    return binary_search(disabled_cipher_suites_.begin(),
                         disabled_cipher_suites_.end(),
                         static_cast<uint16>(cipher_suite));
  }

  const std::vector<uint16>& disabled_cipher_suites_;
};

// Class to determine what cipher suites are available and which cipher
// suites should be enabled, based on the overall security policy.
class EnabledCipherSuites {
 public:
  const std::vector<SSLCipherSuite>& ciphers() const { return ciphers_; }

 private:
  friend struct base::DefaultLazyInstanceTraits<EnabledCipherSuites>;
  EnabledCipherSuites();
  ~EnabledCipherSuites() {}

  std::vector<SSLCipherSuite> ciphers_;

  DISALLOW_COPY_AND_ASSIGN(EnabledCipherSuites);
};

static base::LazyInstance<EnabledCipherSuites> g_enabled_cipher_suites =
    LAZY_INSTANCE_INITIALIZER;

EnabledCipherSuites::EnabledCipherSuites() {
  SSLContextRef ssl_context;
  OSStatus status = SSLNewContext(false, &ssl_context);
  if (status != noErr)
    return;

  size_t num_supported_ciphers;
  status = SSLGetNumberSupportedCiphers(ssl_context, &num_supported_ciphers);
  if (status != noErr) {
    SSLDisposeContext(ssl_context);
    return;
  }
  DCHECK_NE(num_supported_ciphers, 0U);

  std::vector<SSLCipherSuite> supported_ciphers(num_supported_ciphers);
  status = SSLGetSupportedCiphers(ssl_context, &supported_ciphers[0],
                                  &num_supported_ciphers);
  SSLDisposeContext(ssl_context);
  if (status != noErr)
    return;

  for (size_t i = 0; i < num_supported_ciphers; ++i) {
    if (ShouldEnableCipherSuite(supported_ciphers[i]))
      ciphers_.push_back(supported_ciphers[i]);
  }
}

}  // namespace

//-----------------------------------------------------------------------------

SSLClientSocketMac::SSLClientSocketMac(ClientSocketHandle* transport_socket,
                                       const HostPortPair& host_and_port,
                                       const SSLConfig& ssl_config,
                                       const SSLClientSocketContext& context)
    : transport_(transport_socket),
      host_and_port_(host_and_port),
      ssl_config_(ssl_config),
      user_read_buf_len_(0),
      user_write_buf_len_(0),
      next_handshake_state_(STATE_NONE),
      cert_verifier_(context.cert_verifier),
      renegotiating_(false),
      client_cert_requested_(false),
      ssl_context_(NULL),
      bytes_read_after_renegotiation_(0),
      pending_send_error_(OK),
      net_log_(transport_socket->socket()->NetLog()) {
  // Sort the list of ciphers to disable, since disabling ciphers on Mac
  // requires subtracting from a list of enabled ciphers while maintaining
  // ordering, as opposed to merely needing to iterate them as with NSS.
  sort(ssl_config_.disabled_cipher_suites.begin(),
       ssl_config_.disabled_cipher_suites.end());
}

SSLClientSocketMac::~SSLClientSocketMac() {
  Disconnect();
}

int SSLClientSocketMac::Connect(const CompletionCallback& callback) {
  DCHECK(transport_.get());
  DCHECK(next_handshake_state_ == STATE_NONE);
  DCHECK(user_connect_callback_.is_null());

  net_log_.BeginEvent(NetLog::TYPE_SSL_CONNECT);

  int rv = InitializeSSLContext();
  if (rv != OK) {
    net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
    return rv;
  }

  next_handshake_state_ = STATE_HANDSHAKE;
  rv = DoHandshakeLoop(OK);
  if (rv == ERR_IO_PENDING) {
    user_connect_callback_ = callback;
  } else {
    net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
  }
  return rv;
}

void SSLClientSocketMac::Disconnect() {
  next_handshake_state_ = STATE_NONE;

  if (ssl_context_) {
    SSLClose(ssl_context_);
    SSLDisposeContext(ssl_context_);
    ssl_context_ = NULL;
    VLOG(1) << "----- Disposed SSLContext";
  }

  // Shut down anything that may call us back.
  verifier_.reset();
  transport_->socket()->Disconnect();
}

bool SSLClientSocketMac::IsConnected() const {
  // Ideally, we should also check if we have received the close_notify alert
  // message from the server, and return false in that case.  We're not doing
  // that, so this function may return a false positive.  Since the upper
  // layer (HttpNetworkTransaction) needs to handle a persistent connection
  // closed by the server when we send a request anyway, a false positive in
  // exchange for simpler code is a good trade-off.
  return completed_handshake() && transport_->socket()->IsConnected();
}

bool SSLClientSocketMac::IsConnectedAndIdle() const {
  // Unlike IsConnected, this method doesn't return a false positive.
  //
  // Strictly speaking, we should check if we have received the close_notify
  // alert message from the server, and return false in that case.  Although
  // the close_notify alert message means EOF in the SSL layer, it is just
  // bytes to the transport layer below, so
  // transport_->socket()->IsConnectedAndIdle() returns the desired false
  // when we receive close_notify.
  return completed_handshake() && transport_->socket()->IsConnectedAndIdle();
}

int SSLClientSocketMac::GetPeerAddress(IPEndPoint* address) const {
  return transport_->socket()->GetPeerAddress(address);
}

int SSLClientSocketMac::GetLocalAddress(IPEndPoint* address) const {
  return transport_->socket()->GetLocalAddress(address);
}

const BoundNetLog& SSLClientSocketMac::NetLog() const {
  return net_log_;
}

void SSLClientSocketMac::SetSubresourceSpeculation() {
  if (transport_.get() && transport_->socket()) {
    transport_->socket()->SetSubresourceSpeculation();
  } else {
    NOTREACHED();
  }
}

void SSLClientSocketMac::SetOmniboxSpeculation() {
  if (transport_.get() && transport_->socket()) {
    transport_->socket()->SetOmniboxSpeculation();
  } else {
    NOTREACHED();
  }
}

bool SSLClientSocketMac::WasEverUsed() const {
  if (transport_.get() && transport_->socket()) {
    return transport_->socket()->WasEverUsed();
  }
  NOTREACHED();
  return false;
}

bool SSLClientSocketMac::UsingTCPFastOpen() const {
  if (transport_.get() && transport_->socket()) {
    return transport_->socket()->UsingTCPFastOpen();
  }
  NOTREACHED();
  return false;
}

int64 SSLClientSocketMac::NumBytesRead() const {
  if (transport_.get() && transport_->socket()) {
    return transport_->socket()->NumBytesRead();
  }
  NOTREACHED();
  return -1;
}

base::TimeDelta SSLClientSocketMac::GetConnectTimeMicros() const {
  if (transport_.get() && transport_->socket()) {
    return transport_->socket()->GetConnectTimeMicros();
  }
  NOTREACHED();
  return base::TimeDelta::FromMicroseconds(-1);
}

int SSLClientSocketMac::Read(IOBuffer* buf, int buf_len,
                             const CompletionCallback& callback) {
  DCHECK(completed_handshake());
  DCHECK(user_read_callback_.is_null());
  DCHECK(!user_read_buf_);

  user_read_buf_ = buf;
  user_read_buf_len_ = buf_len;

  int rv = DoPayloadRead();
  if (rv == ERR_IO_PENDING) {
    user_read_callback_ = callback;
  } else {
    user_read_buf_ = NULL;
    user_read_buf_len_ = 0;
  }
  return rv;
}

int SSLClientSocketMac::Write(IOBuffer* buf, int buf_len,
                              const CompletionCallback& callback) {
  DCHECK(completed_handshake());
  DCHECK(user_write_callback_.is_null());
  DCHECK(!user_write_buf_);

  user_write_buf_ = buf;
  user_write_buf_len_ = buf_len;

  int rv = DoPayloadWrite();
  if (rv == ERR_IO_PENDING) {
    user_write_callback_ = callback;
  } else {
    user_write_buf_ = NULL;
    user_write_buf_len_ = 0;
  }
  return rv;
}

bool SSLClientSocketMac::SetReceiveBufferSize(int32 size) {
  return transport_->socket()->SetReceiveBufferSize(size);
}

bool SSLClientSocketMac::SetSendBufferSize(int32 size) {
  return transport_->socket()->SetSendBufferSize(size);
}

bool SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) {
  ssl_info->Reset();
  if (!server_cert_)
    return false;

  ssl_info->cert = server_cert_verify_result_.verified_cert;
  ssl_info->cert_status = server_cert_verify_result_.cert_status;
  ssl_info->public_key_hashes = server_cert_verify_result_.public_key_hashes;
  ssl_info->is_issued_by_known_root =
      server_cert_verify_result_.is_issued_by_known_root;
  ssl_info->client_cert_sent =
      ssl_config_.send_client_cert && ssl_config_.client_cert;
  ssl_info->channel_id_sent = WasChannelIDSent();

  // security info
  SSLCipherSuite suite;
  OSStatus status = SSLGetNegotiatedCipher(ssl_context_, &suite);
  if (!status) {
    ssl_info->security_bits = KeySizeOfCipherSuite(suite);
    ssl_info->connection_status |=
        (suite & SSL_CONNECTION_CIPHERSUITE_MASK) <<
        SSL_CONNECTION_CIPHERSUITE_SHIFT;
  }

  if (ssl_config_.version_fallback)
    ssl_info->connection_status |= SSL_CONNECTION_VERSION_FALLBACK;

  return true;
}

void SSLClientSocketMac::GetSSLCertRequestInfo(
    SSLCertRequestInfo* cert_request_info) {
  // I'm being asked for available client certs (identities).
  // First, get the cert issuer names allowed by the server.
  std::vector<CertPrincipal> valid_issuers;
  CFArrayRef valid_issuer_names = NULL;
  if (SSLCopyDistinguishedNames(ssl_context_, &valid_issuer_names) == noErr &&
      valid_issuer_names != NULL) {
    VLOG(1) << "Server has " << CFArrayGetCount(valid_issuer_names)
            << " valid issuer names";
    int n = CFArrayGetCount(valid_issuer_names);
    for (int i = 0; i < n; i++) {
      // Parse each name into a CertPrincipal object.
      CFDataRef issuer = reinterpret_cast<CFDataRef>(
          CFArrayGetValueAtIndex(valid_issuer_names, i));
      CertPrincipal p;
      if (p.ParseDistinguishedName(CFDataGetBytePtr(issuer),
                                   CFDataGetLength(issuer))) {
        valid_issuers.push_back(p);
      }
    }
    CFRelease(valid_issuer_names);
  }

  // Now get the available client certs whose issuers are allowed by the server.
  cert_request_info->host_and_port = host_and_port_.ToString();
  cert_request_info->client_certs.clear();
  // TODO(rch):  we should consider passing a host-port pair as the first
  // argument to X509Certificate::GetSSLClientCertificates.
  X509Certificate::GetSSLClientCertificates(host_and_port_.host(),
                                            valid_issuers,
                                            &cert_request_info->client_certs);
  std::sort(cert_request_info->client_certs.begin(),
            cert_request_info->client_certs.end(),
            x509_util::ClientCertSorter());

  VLOG(1) << "Asking user to choose between "
          << cert_request_info->client_certs.size() << " client certs...";
}

int SSLClientSocketMac::ExportKeyingMaterial(const base::StringPiece& label,
                                             bool has_context,
                                             const base::StringPiece& context,
                                             unsigned char* out,
                                             unsigned int outlen) {
  return ERR_NOT_IMPLEMENTED;
}

int SSLClientSocketMac::GetTLSUniqueChannelBinding(std::string* out) {
  return ERR_NOT_IMPLEMENTED;
}

SSLClientSocket::NextProtoStatus
SSLClientSocketMac::GetNextProto(std::string* proto,
                                 std::string* server_protos) {
  proto->clear();
  server_protos->clear();
  return kNextProtoUnsupported;
}

ServerBoundCertService* SSLClientSocketMac::GetServerBoundCertService() const {
  return NULL;
}

int SSLClientSocketMac::InitializeSSLContext() {
  VLOG(1) << "----- InitializeSSLContext";
  OSStatus status = noErr;

  status = SSLNewContext(false, &ssl_context_);
  if (status)
    return NetErrorFromOSStatus(status);

  status = SSLSetProtocolVersionEnabled(ssl_context_,
                                        kSSLProtocol2,
                                        false);
  if (status)
    return NetErrorFromOSStatus(status);

  // If ssl_config_.version_max > SSL_PROTOCOL_VERSION_TLS1, it means the
  // SSLConfigService::SetDefaultVersionMax(SSL_PROTOCOL_VERSION_TLS1) call
  // in ClientSocketFactory::UseSystemSSL() is not effective.
  DCHECK_LE(ssl_config_.version_max, SSL_PROTOCOL_VERSION_TLS1);

  bool ssl3_enabled = (ssl_config_.version_min == SSL_PROTOCOL_VERSION_SSL3);
  status = SSLSetProtocolVersionEnabled(ssl_context_,
                                        kSSLProtocol3,
                                        ssl3_enabled);
  if (status)
    return NetErrorFromOSStatus(status);

  bool tls1_enabled = (ssl_config_.version_min <= SSL_PROTOCOL_VERSION_TLS1 &&
                       ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1);
  status = SSLSetProtocolVersionEnabled(ssl_context_,
                                        kTLSProtocol1,
                                        tls1_enabled);
  if (status)
    return NetErrorFromOSStatus(status);

  std::vector<SSLCipherSuite> enabled_ciphers =
      g_enabled_cipher_suites.Get().ciphers();

  CipherSuiteIsDisabledFunctor is_disabled_cipher(
      ssl_config_.disabled_cipher_suites);
  std::vector<SSLCipherSuite>::iterator new_end =
      std::remove_if(enabled_ciphers.begin(), enabled_ciphers.end(),
                     is_disabled_cipher);
  if (new_end != enabled_ciphers.end())
    enabled_ciphers.erase(new_end, enabled_ciphers.end());

  status = SSLSetEnabledCiphers(
      ssl_context_,
      enabled_ciphers.empty() ? NULL : &enabled_ciphers[0],
      enabled_ciphers.size());

  if (status)
    return NetErrorFromOSStatus(status);

  status = SSLSetIOFuncs(ssl_context_, SSLReadCallback, SSLWriteCallback);
  if (status)
    return NetErrorFromOSStatus(status);

  status = SSLSetConnection(ssl_context_, this);
  if (status)
    return NetErrorFromOSStatus(status);

  // Passing the domain name enables the server_name TLS extension (SNI).
  status = SSLSetPeerDomainName(ssl_context_,
                                host_and_port_.host().data(),
                                host_and_port_.host().length());
  if (status)
    return NetErrorFromOSStatus(status);

  // Disable certificate verification within Secure Transport; we'll
  // be handling that ourselves.
  status = SSLSetEnableCertVerify(ssl_context_, false);
  if (status)
    return NetErrorFromOSStatus(status);

  if (ssl_config_.send_client_cert) {
    status = SetClientCert();
    if (status)
      return NetErrorFromOSStatus(status);
    return OK;
  }

  // Concatenate the hostname and peer address to use as the peer ID. To
  // resume a session, we must connect to the same server on the same port
  // using the same hostname (i.e., localhost and 127.0.0.1 are considered
  // different peers, which puts us through certificate validation again
  // and catches hostname/certificate name mismatches.
  IPEndPoint endpoint;
  int rv = transport_->socket()->GetPeerAddress(&endpoint);
  if (rv != OK)
    return rv;
  std::string peer_id(host_and_port_.ToString());
  peer_id += std::string(reinterpret_cast<const char*>(&endpoint.address()[0]),
                         endpoint.address().size());
  // SSLSetPeerID() treats peer_id as a binary blob, and makes its
  // own copy.
  status = SSLSetPeerID(ssl_context_, peer_id.data(), peer_id.length());
  if (status)
    return NetErrorFromOSStatus(status);

  return OK;
}

void SSLClientSocketMac::DoConnectCallback(int rv) {
  DCHECK(rv != ERR_IO_PENDING);
  DCHECK(!user_connect_callback_.is_null());

  CompletionCallback c = user_connect_callback_;
  user_connect_callback_.Reset();
  c.Run(rv > OK ? OK : rv);
}

void SSLClientSocketMac::DoReadCallback(int rv) {
  DCHECK(rv != ERR_IO_PENDING);
  DCHECK(!user_read_callback_.is_null());

  // Since Run may result in Read being called, clear user_read_callback_ up
  // front.
  CompletionCallback c = user_read_callback_;
  user_read_callback_.Reset();
  user_read_buf_ = NULL;
  user_read_buf_len_ = 0;
  c.Run(rv);
}

void SSLClientSocketMac::DoWriteCallback(int rv) {
  DCHECK(rv != ERR_IO_PENDING);
  DCHECK(!user_write_callback_.is_null());

  // Since Run may result in Write being called, clear user_write_callback_ up
  // front.
  CompletionCallback c = user_write_callback_;
  user_write_callback_.Reset();
  user_write_buf_ = NULL;
  user_write_buf_len_ = 0;
  c.Run(rv);
}

void SSLClientSocketMac::OnHandshakeIOComplete(int result) {
  int rv = DoHandshakeLoop(result);
  if (rv != ERR_IO_PENDING) {
    // If there is no connect callback available to call, we are
    // renegotiating (which occurs because we are in the middle of a Read
    // when the renegotiation process starts).  So we complete the Read
    // here.
    if (user_connect_callback_.is_null()) {
      DoReadCallback(rv);
      return;
    }
    net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
    DoConnectCallback(rv);
  }
}

void SSLClientSocketMac::OnTransportReadComplete(int result) {
  if (result > 0) {
    recv_buffer_.insert(recv_buffer_.end(),
                        read_io_buf_->data(),
                        read_io_buf_->data() + result);
  }
  read_io_buf_ = NULL;

  if (!completed_handshake()) {
    OnHandshakeIOComplete(result);
    return;
  }

  if (user_read_buf_) {
    if (result < 0) {
      DoReadCallback(result);
      return;
    }
    int rv = DoPayloadRead();
    if (rv != ERR_IO_PENDING)
      DoReadCallback(rv);
  }
}

void SSLClientSocketMac::OnTransportWriteComplete(int result) {
  write_io_buf_ = NULL;

  if (result < 0) {
    pending_send_error_ = result;
    return;
  }

  send_buffer_.erase(send_buffer_.begin(),
                     send_buffer_.begin() + result);
  if (!send_buffer_.empty())
    SSLWriteCallback(this, NULL, NULL);

  if (!completed_handshake()) {
    OnHandshakeIOComplete(result);
    return;
  }

  // If paused because too much data is in flight, try writing again and make
  // the promised callback.
  if (user_write_buf_ && send_buffer_.size() < kWriteSizeResumeLimit) {
    int rv = DoPayloadWrite();
    if (rv != ERR_IO_PENDING)
      DoWriteCallback(rv);
  }
}

int SSLClientSocketMac::DoHandshakeLoop(int last_io_result) {
  DCHECK(next_handshake_state_ != STATE_NONE);
  int rv = last_io_result;
  do {
    State state = next_handshake_state_;
    next_handshake_state_ = STATE_NONE;
    switch (state) {
      case STATE_HANDSHAKE:
        // Do the SSL/TLS handshake.
        rv = DoHandshake();
        break;
      case STATE_VERIFY_CERT:
        // Kick off server certificate validation.
        rv = DoVerifyCert();
        break;
      case STATE_VERIFY_CERT_COMPLETE:
        // Check the results of the server certificate validation.
        rv = DoVerifyCertComplete(rv);
        break;
      case STATE_COMPLETED_RENEGOTIATION:
        // The renegotiation handshake has completed, and the Read() call
        // that was interrupted by the renegotiation needs to be resumed in
        // order to to satisfy the original caller's request.
        rv = DoCompletedRenegotiation(rv);
        break;
      case STATE_COMPLETED_HANDSHAKE:
        next_handshake_state_ = STATE_COMPLETED_HANDSHAKE;
        // This is the end of our state machine, so return.
        return rv;
      default:
        rv = ERR_UNEXPECTED;
        NOTREACHED() << "unexpected state";
        break;
    }
  } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
  return rv;
}

int SSLClientSocketMac::DoHandshake() {
  client_cert_requested_ = false;

  OSStatus status;
  if (!renegotiating_) {
    status = SSLHandshake(ssl_context_);
  } else {
    // Renegotiation can only be detected by a call to DoPayloadRead(),
    // which means |user_read_buf_| should be valid.
    DCHECK(user_read_buf_);

    // On OS X 10.5.x, SSLSetSessionOption with
    // kSSLSessionOptionBreakOnServerAuth is broken for renegotiation, as
    // SSLRead() does not internally handle errSSLServerAuthCompleted being
    // returned during handshake. In order to support certificate validation
    // after a renegotiation, SSLRead() sets |renegotiating_| to be true and
    // returns errSSLWouldBlock when it detects an attempt to read the
    // ServerHello after responding to a HelloRequest. It would be
    // appropriate to call SSLHandshake() at this point to restart the
    // handshake state machine, however, on 10.5.x, SSLHandshake() is buggy
    // and will always return noErr (indicating handshake completion),
    // without doing any actual work. Because of this, the only way to
    // advance SecureTransport's internal handshake state machine is to
    // continuously call SSLRead() until the handshake is marked complete.
    // Once the handshake is completed, if it completed successfully, the
    // user read callback is invoked with |bytes_read_after_renegotiation_|
    // as the callback result. On 10.6.0+, both errSSLServerAuthCompleted
    // and SSLHandshake() work as expected, so this strange workaround is
    // only necessary while OS X 10.5.x is still supported.
    bytes_read_after_renegotiation_ = 0;
    status = SSLRead(ssl_context_, user_read_buf_->data(),
                     user_read_buf_len_, &bytes_read_after_renegotiation_);
    if (bytes_read_after_renegotiation_ > 0) {
      // With SecureTransport, as of 10.6.5, if application data is read,
      // then the handshake should be completed. This is because
      // SecureTransport does not (yet) support exchanging application data
      // in the midst of handshakes. This is permitted in the TLS
      // specification, as peers may exchange messages using the previous
      // cipher spec up until they exchange ChangeCipherSpec messages.
      // However, in addition to SecureTransport not supporting this, we do
      // not permit callers to enter Read() or Write() when a handshake is
      // occurring, in part due to the deception that happens in
      // SSLWriteCallback(). Thus we need to make sure the handshake is
      // truly completed before processing application data, and if any was
      // read before the handshake is completed, it will be dropped and the
      // connection aborted.
      SSLSessionState session_state = kSSLIdle;
      status = SSLGetSessionState(ssl_context_, &session_state);
      if (session_state != kSSLConnected)
        status = errSSLProtocol;
    }
  }

  SSLClientCertificateState client_cert_state;
  if (SSLGetClientCertificateState(ssl_context_, &client_cert_state) != noErr)
    client_cert_state = kSSLClientCertNone;
  if (client_cert_state > kSSLClientCertNone)
    client_cert_requested_ = true;

  int net_error = ERR_FAILED;
  switch (status) {
    case noErr:
      return DidCompleteHandshake();
    case errSSLWouldBlock:
      next_handshake_state_ = STATE_HANDSHAKE;
      return ERR_IO_PENDING;
    case errSSLClosedGraceful:
      // The server unexpectedly closed on us.
      net_error = ERR_SSL_PROTOCOL_ERROR;
      break;
    case errSSLClosedAbort:
    case errSSLPeerHandshakeFail:
      if (client_cert_requested_) {
        if (!ssl_config_.send_client_cert) {
          // The server aborted, likely due to requiring a client certificate
          // and one wasn't sent.
          VLOG(1) << "Server requested SSL cert during handshake";
          net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
        } else {
          // The server aborted, likely due to not liking the client
          // certificate that was sent.
          LOG(WARNING) << "Server aborted SSL handshake";
          net_error = ERR_BAD_SSL_CLIENT_AUTH_CERT;
        }
        // Don't fall through - the error was intentionally remapped.
        break;
      }
      // Fall through if a client cert wasn't requested.
    default:
      net_error = NetErrorFromOSStatus(status);
      DCHECK(!IsCertificateError(net_error));
      if (!ssl_config_.send_client_cert &&
         (client_cert_state == kSSLClientCertRejected ||
          net_error == ERR_BAD_SSL_CLIENT_AUTH_CERT)) {
        // The server unexpectedly sent a peer certificate error alert when no
        // certificate had been sent.
        net_error = ERR_SSL_PROTOCOL_ERROR;
      }
      break;
  }

  net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
                    CreateNetLogSSLErrorCallback(net_error, status));
  return net_error;
}

int SSLClientSocketMac::DoVerifyCert() {
  next_handshake_state_ = STATE_VERIFY_CERT_COMPLETE;

  DCHECK(server_cert_);

  VLOG(1) << "DoVerifyCert...";
  CertStatus cert_status;
  if (ssl_config_.IsAllowedBadCert(server_cert_, &cert_status)) {
    VLOG(1) << "Received an expected bad cert with status: " << cert_status;
    server_cert_verify_result_.Reset();
    server_cert_verify_result_.cert_status = cert_status;
    server_cert_verify_result_.verified_cert = server_cert_;
    return OK;
  }

  int flags = 0;
  if (ssl_config_.rev_checking_enabled)
    flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED;
  if (ssl_config_.verify_ev_cert)
    flags |= CertVerifier::VERIFY_EV_CERT;
  if (ssl_config_.cert_io_enabled)
    flags |= CertVerifier::VERIFY_CERT_IO_ENABLED;
  verifier_.reset(new SingleRequestCertVerifier(cert_verifier_));
  return verifier_->Verify(
      server_cert_, host_and_port_.host(), flags,
      NULL /* no CRL set */,
      &server_cert_verify_result_,
      base::Bind(&SSLClientSocketMac::OnHandshakeIOComplete,
                 base::Unretained(this)),
      net_log_);
}

int SSLClientSocketMac::DoVerifyCertComplete(int result) {
  DCHECK(verifier_.get());
  verifier_.reset();

  VLOG(1) << "...DoVerifyCertComplete (result=" << result << ")";
  if (result == OK && client_cert_requested_ &&
      !ssl_config_.send_client_cert) {
    // Caller hasn't specified a client cert, so let it know the server is
    // asking for one, and abort the connection.
    return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
  }
  VLOG(1) << "Handshake finished! (DoVerifyCertComplete)";

  if (renegotiating_) {
    DidCompleteRenegotiation();
    return result;
  }

  // The initial handshake has completed.
  next_handshake_state_ = STATE_COMPLETED_HANDSHAKE;

  return result;
}

int SSLClientSocketMac::SetClientCert() {
  if (!ssl_config_.send_client_cert || !ssl_config_.client_cert)
    return noErr;

  base::mac::ScopedCFTypeRef<CFArrayRef> cert_refs(
      ssl_config_.client_cert->CreateClientCertificateChain());
  VLOG(1) << "SSLSetCertificate(" << CFArrayGetCount(cert_refs) << " certs)";
  OSStatus result = SSLSetCertificate(ssl_context_, cert_refs);
  if (result)
    OSSTATUS_LOG(ERROR, result) << "SSLSetCertificate failed";
  return result;
}

int SSLClientSocketMac::DoPayloadRead() {
  size_t processed = 0;
  OSStatus status = SSLRead(ssl_context_, user_read_buf_->data(),
                            user_read_buf_len_, &processed);
  if (status == errSSLWouldBlock && renegotiating_) {
    CHECK_EQ(static_cast<size_t>(0), processed);
    next_handshake_state_ = STATE_HANDSHAKE;
    return DoHandshakeLoop(OK);
  }
  // There's a subtle difference here in semantics of the "would block" errors.
  // In our code, ERR_IO_PENDING means the whole operation is async, while
  // errSSLWouldBlock means that the stream isn't ending (and is often returned
  // along with partial data). So even though "would block" is returned, if we
  // have data, let's just return it. This is further complicated by the fact
  // that errSSLWouldBlock is also used to short-circuit SSLRead()'s
  // transparent renegotiation, so that we can update our state machine above,
  // which otherwise would get out of sync with the SSLContextRef's internal
  // state machine.
  if (processed > 0) {
    net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED,
                                  processed, user_read_buf_->data());
    return processed;
  }

  switch (status) {
    case errSSLClosedNoNotify:
      // TODO(wtc): Unless we have received the close_notify alert, we need to
      // return an error code indicating that the SSL connection ended
      // uncleanly, a potential truncation attack.  See http://crbug.com/18586.
      return OK;

    default:
      return NetErrorFromOSStatus(status);
  }
}

int SSLClientSocketMac::DoPayloadWrite() {
  // Too much data in flight?
  if (send_buffer_.size() > kWriteSizePauseLimit)
    return ERR_IO_PENDING;

  size_t processed = 0;
  OSStatus status = SSLWrite(ssl_context_,
                             user_write_buf_->data(),
                             user_write_buf_len_,
                             &processed);

  if (processed > 0) {
    net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_SENT, processed,
                                  user_write_buf_->data());
    return processed;
  }

  return NetErrorFromOSStatus(status);
}

int SSLClientSocketMac::DoCompletedRenegotiation(int result) {
  // The user had a read in progress, which was interrupted by the
  // renegotiation. Return the application data that was processed after the
  // handshake completed.
  next_handshake_state_ = STATE_COMPLETED_HANDSHAKE;
  if (result != OK)
    return result;
  return bytes_read_after_renegotiation_;
}

void SSLClientSocketMac::DidCompleteRenegotiation() {
  DCHECK(user_connect_callback_.is_null());
  renegotiating_ = false;
  next_handshake_state_ = STATE_COMPLETED_RENEGOTIATION;
}

int SSLClientSocketMac::DidCompleteHandshake() {
  DCHECK(!server_cert_ || renegotiating_);
  VLOG(1) << "Handshake completed, next verify cert";

  scoped_refptr<X509Certificate> new_server_cert(
      GetServerCert(ssl_context_));
  if (!new_server_cert)
    return ERR_UNEXPECTED;
  net_log_.AddEvent(
      NetLog::TYPE_SSL_CERTIFICATES_RECEIVED,
      base::Bind(&NetLogX509CertificateCallback,
                 base::Unretained(new_server_cert.get())));

  if (renegotiating_ &&
      X509Certificate::IsSameOSCert(server_cert_->os_cert_handle(),
                                    new_server_cert->os_cert_handle())) {
    // We already verified the server certificate.  Either it is good or the
    // user has accepted the certificate error.
    DidCompleteRenegotiation();
  } else {
    server_cert_ = new_server_cert;
    next_handshake_state_ = STATE_VERIFY_CERT;
  }
  return OK;
}

// static
OSStatus SSLClientSocketMac::SSLReadCallback(SSLConnectionRef connection,
                                             void* data,
                                             size_t* data_length) {
  DCHECK(data);
  DCHECK(data_length);
  SSLClientSocketMac* us =
      const_cast<SSLClientSocketMac*>(
          static_cast<const SSLClientSocketMac*>(connection));

  if (us->read_io_buf_) {
    // We have I/O in flight; promise we'll get back to them and use the
    // existing callback to do so.
    *data_length = 0;
    return errSSLWouldBlock;
  }
  if (us->completed_handshake()) {
    // The state machine for SSLRead, located in libsecurity_ssl's
    // sslTransport.c, will attempt to fully complete the renegotiation
    // transparently in SSLRead once it reads the server's HelloRequest
    // message. In order to make sure that the server certificate is
    // (re-)verified and that any other parameters are logged (eg:
    // certificate request state), we try to detect that the
    // SSLClientSocketMac's state machine is out of sync with the
    // SSLContext's. When that happens, we break out by faking
    // errSSLWouldBlock, and set a flag so that DoPayloadRead() knows that
    // it's not actually blocked. DoPayloadRead() will then restart the
    // handshake state machine, and finally resume the original Read()
    // once it successfully completes, similar to the behaviour of
    // SSLClientSocketWin's DoDecryptPayload() and DoLoop() behave.
    SSLSessionState state;
    OSStatus status = SSLGetSessionState(us->ssl_context_, &state);
    if (status) {
      *data_length = 0;
      return status;
    }
    if (state == kSSLHandshake) {
      *data_length = 0;
      us->renegotiating_ = true;
      return errSSLWouldBlock;
    }
  }

  size_t total_read = us->recv_buffer_.size();

  int rv = 1;  // any old value to spin the loop below
  while (rv > 0 && total_read < *data_length) {
    us->read_io_buf_ = new IOBuffer(*data_length - total_read);
    rv = us->transport_->socket()->Read(
        us->read_io_buf_,
        *data_length - total_read,
        base::Bind(&SSLClientSocketMac::OnTransportReadComplete,
                   base::Unretained(us)));

    if (rv >= 0) {
      us->recv_buffer_.insert(us->recv_buffer_.end(),
                              us->read_io_buf_->data(),
                              us->read_io_buf_->data() + rv);
      us->read_io_buf_ = NULL;
      total_read += rv;
    }
  }

  *data_length = total_read;
  if (total_read) {
    memcpy(data, &us->recv_buffer_[0], total_read);
    us->recv_buffer_.clear();
  }

  if (rv != ERR_IO_PENDING)
    us->read_io_buf_ = NULL;

  if (rv < 0)
    return OSStatusFromNetError(rv);
  else if (rv == 0)  // stream closed
    return errSSLClosedGraceful;
  else
    return noErr;
}

// static
OSStatus SSLClientSocketMac::SSLWriteCallback(SSLConnectionRef connection,
                                              const void* data,
                                              size_t* data_length) {
  SSLClientSocketMac* us =
      const_cast<SSLClientSocketMac*>(
          static_cast<const SSLClientSocketMac*>(connection));

  if (us->pending_send_error_ != OK) {
    OSStatus status = OSStatusFromNetError(us->pending_send_error_);
    us->pending_send_error_ = OK;
    return status;
  }

  if (data)
    us->send_buffer_.insert(us->send_buffer_.end(),
                            static_cast<const char*>(data),
                            static_cast<const char*>(data) + *data_length);

  if (us->write_io_buf_) {
    // If we have I/O in flight, just add the data to the end of the buffer and
    // return to our caller. The existing callback will trigger the write of the
    // new data when it sees that data remains in the buffer after removing the
    // sent data. As always, lie to our caller.
    return noErr;
  }

  int rv;
  do {
    us->write_io_buf_ = new IOBuffer(us->send_buffer_.size());
    memcpy(us->write_io_buf_->data(), &us->send_buffer_[0],
           us->send_buffer_.size());
    rv = us->transport_->socket()->Write(
        us->write_io_buf_,
        us->send_buffer_.size(),
        base::Bind(&SSLClientSocketMac::OnTransportWriteComplete,
                   base::Unretained(us)));
    if (rv > 0) {
      us->send_buffer_.erase(us->send_buffer_.begin(),
                             us->send_buffer_.begin() + rv);
      us->write_io_buf_ = NULL;
    }
  } while (rv > 0 && !us->send_buffer_.empty());

  if (rv < 0 && rv != ERR_IO_PENDING) {
    us->write_io_buf_ = NULL;
    return OSStatusFromNetError(rv);
  }

  // always lie to our caller
  return noErr;
}

}  // namespace net
